12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702 |
- //===- 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/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/Optional.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 <tuple>
- #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
- DeduceTemplateArguments(Sema &S,
- TemplateParameterList *TemplateParams,
- const TemplateArgument &Param,
- TemplateArgument Arg,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced);
- 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> Params,
- ArrayRef<TemplateArgument> Args,
- 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 NonTypeTemplateParmDecl *
- getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) {
- // If we are within an alias template, the expression may have undergone
- // any number of parameter substitutions already.
- while (true) {
- if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E))
- E = IC->getSubExpr();
- else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E))
- E = CE->getSubExpr();
- else if (SubstNonTypeTemplateParmExpr *Subst =
- dyn_cast<SubstNonTypeTemplateParmExpr>(E))
- E = Subst->getReplacement();
- else
- break;
- }
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
- if (NTTP->getDepth() == Info.getDeducedDepth())
- return NTTP;
- return nullptr;
- }
- /// 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.
- if (Y.getKind() == TemplateArgument::Type &&
- Context.hasSameType(X.getAsType(), Y.getAsType()))
- return X;
- // 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 X;
- // 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 X;
- // 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())
- 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,
- 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 = 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.
- return DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, ParamType.getNonReferenceType(),
- ValueType.getNonReferenceType(), 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,
- 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,
- NonTypeTemplateParmDecl *NTTP, QualType NullPtrType,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- Expr *Value =
- S.ImpCastExprToType(new (S.Context) CXXNullPtrLiteralExpr(
- S.Context.NullPtrTy, NTTP->getLocation()),
- NullPtrType, 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,
- 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,
- 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 Param the parameter type
- ///
- /// \param Arg 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
- DeduceTemplateArguments(Sema &S,
- TemplateParameterList *TemplateParams,
- const TemplateSpecializationType *Param,
- QualType Arg,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
- assert(Arg.isCanonical() && "Argument type must be canonical");
- // Treat an injected-class-name as its underlying template-id.
- if (auto *Injected = dyn_cast<InjectedClassNameType>(Arg))
- Arg = Injected->getInjectedSpecializationType();
- // Check whether the template argument is a dependent template-id.
- if (const TemplateSpecializationType *SpecArg
- = dyn_cast<TemplateSpecializationType>(Arg)) {
- // Perform template argument deduction for the template name.
- if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArguments(S, TemplateParams,
- Param->getTemplateName(),
- SpecArg->getTemplateName(),
- 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,
- Param->template_arguments(),
- SpecArg->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 RecordType *RecordArg = dyn_cast<RecordType>(Arg);
- if (!RecordArg) {
- Info.FirstArg = TemplateArgument(QualType(Param, 0));
- Info.SecondArg = TemplateArgument(Arg);
- return Sema::TDK_NonDeducedMismatch;
- }
- ClassTemplateSpecializationDecl *SpecArg
- = dyn_cast<ClassTemplateSpecializationDecl>(RecordArg->getDecl());
- if (!SpecArg) {
- Info.FirstArg = TemplateArgument(QualType(Param, 0));
- Info.SecondArg = TemplateArgument(Arg);
- return Sema::TDK_NonDeducedMismatch;
- }
- // Perform template argument deduction for the template name.
- if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArguments(S,
- TemplateParams,
- Param->getTemplateName(),
- TemplateName(SpecArg->getSpecializedTemplate()),
- Info, Deduced))
- return Result;
- // Perform template argument deduction for the template arguments.
- return DeduceTemplateArguments(S, TemplateParams, Param->template_arguments(),
- SpecArg->getTemplateArgs().asArray(), Info,
- Deduced, /*NumberOfArgumentsMustMatch=*/true);
- }
- /// Determines whether the given type is an opaque type that
- /// might be more qualified when instantiated.
- static bool IsPossiblyOpaquelyQualifiedType(QualType T) {
- 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 IsPossiblyOpaquelyQualifiedType(
- cast<ArrayType>(T)->getElementType());
- default:
- return false;
- }
- }
- /// 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));
- }
- /// If \p Param is an expanded parameter pack, get the number of expansions.
- static Optional<unsigned> getExpandedPackSize(NamedDecl *Param) {
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param))
- if (NTTP->isExpandedParameterPack())
- return NTTP->getNumExpansionTypes();
- if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param))
- if (TTP->isExpandedParameterPack())
- return TTP->getNumExpansionTemplateParameters();
- return None;
- }
- /// 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 (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());
- auto AddPack = [&](unsigned Index) {
- if (SawIndices[Index])
- return;
- SawIndices[Index] = true;
- addPack(Index);
- };
- // First look for unexpanded packs in the 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);
- }
- assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
- unsigned NumNamedPacks = Packs.size();
- // We can also have deduced template parameters that do not actually
- // appear in the pattern, but can be deduced by it (the type of a non-type
- // template parameter pack, in particular). These won't have prevented us
- // from partially expanding the pack.
- llvm::SmallBitVector Used(TemplateParams->size());
- MarkUsedTemplateParameters(S.Context, Pattern, /*OnlyDeduced*/true,
- Info.getDeducedDepth(), Used);
- for (int Index = Used.find_first(); Index != -1;
- Index = Used.find_next(Index))
- if (TemplateParams->getParam(Index)->isParameterPack())
- AddPack(Index);
- 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.hasValue(); }
- /// 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(bool TreatNoDeductionsAsNonDeduced = true) {
- // 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;
- // If we are deducing the size of this pack even if we didn't deduce any
- // values for it, then make sure we build a pack of the right size.
- // FIXME: Should we always deduce the size, even if the pack appears in
- // a non-deduced context?
- if (!TreatNoDeductionsAsNonDeduced)
- Pack.New.resize(PackElements);
- // Build or find a new value for this pack.
- DeducedTemplateArgument NewPack;
- if (PackElements && Pack.New.empty()) {
- if (Pack.DeferredDeduction.isNull()) {
- // We were not able to deduce anything for this parameter pack
- // (because it only appeared in non-deduced contexts), so just
- // restore the saved argument pack.
- continue;
- }
- NewPack = Pack.DeferredDeduction;
- Pack.DeferredDeduction = TemplateArgument();
- } else 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::makeArrayRef(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 (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.
- 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], Args[ArgIdx],
- Info, Deduced, TDF,
- PartialOrdering))
- 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,
- Args[ArgIdx], Info, Deduced,
- TDF, PartialOrdering))
- 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.
- 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;
- }
- // 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 Param the template parameter type.
- ///
- /// \param Arg the argument type.
- bool Sema::isSameOrCompatibleFunctionType(CanQualType Param,
- CanQualType Arg) {
- const FunctionType *ParamFunction = Param->getAs<FunctionType>(),
- *ArgFunction = Arg->getAs<FunctionType>();
- // Just compare if not functions.
- if (!ParamFunction || !ArgFunction)
- return Param == Arg;
- // Noreturn and noexcept adjustment.
- QualType AdjustedParam;
- if (IsFunctionConversion(Param, Arg, AdjustedParam))
- return Arg == Context.getCanonicalType(AdjustedParam);
- // FIXME: Compatible calling conventions.
- return Param == Arg;
- }
- /// 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;
- }
- /// 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 ParamIn the parameter type
- ///
- /// \param ArgIn 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 ParamIn, QualType ArgIn,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- unsigned TDF,
- bool PartialOrdering,
- bool DeducedFromArrayBound) {
- // We only want to look at the canonical types, since typedefs and
- // sugar are not part of template argument deduction.
- QualType Param = S.Context.getCanonicalType(ParamIn);
- QualType Arg = S.Context.getCanonicalType(ArgIn);
- // If the argument type is a pack expansion, look at its pattern.
- // This isn't explicitly called out
- if (const PackExpansionType *ArgExpansion
- = dyn_cast<PackExpansionType>(Arg))
- Arg = ArgExpansion->getPattern();
- 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 *ParamRef = Param->getAs<ReferenceType>();
- if (ParamRef)
- Param = ParamRef->getPointeeType();
- // - If A is a reference type, A is replaced by the type referred to.
- const ReferenceType *ArgRef = Arg->getAs<ReferenceType>();
- if (ArgRef)
- Arg = ArgRef->getPointeeType();
- if (ParamRef && ArgRef && S.Context.hasSameUnqualifiedType(Param, Arg)) {
- // 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 ParamQuals = Param.getQualifiers();
- Qualifiers ArgQuals = Arg.getQualifiers();
- if ((ParamRef->isLValueReferenceType() &&
- !ArgRef->isLValueReferenceType()) ||
- ParamQuals.isStrictSupersetOf(ArgQuals) ||
- (ParamQuals.hasNonTrivialObjCLifetime() &&
- ArgQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone &&
- ParamQuals.withoutObjCLifetime() ==
- ArgQuals.withoutObjCLifetime())) {
- Info.FirstArg = TemplateArgument(ParamIn);
- Info.SecondArg = TemplateArgument(ArgIn);
- return Sema::TDK_NonDeducedMismatch;
- }
- }
- // 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.
- Param = Param.getUnqualifiedType();
- // - If A is a cv-qualified type, A is replaced by the cv-unqualified
- // version of A.
- Arg = Arg.getUnqualifiedType();
- } 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 UnqualParam = S.Context.getUnqualifiedArrayType(Param, Quals);
- Quals.setCVRQualifiers(Quals.getCVRQualifiers() &
- Arg.getCVRQualifiers());
- Param = S.Context.getQualifiedType(UnqualParam, Quals);
- }
- if ((TDF & TDF_TopLevelParameterTypeList) && !Param->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(Param, 0) && Arg->isLValueReferenceType())
- Param = Param->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 TemplateTypeParmType *TemplateTypeParm
- = Param->getAs<TemplateTypeParmType>()) {
- // Just skip any attempts to deduce from a placeholder type or a parameter
- // at a different depth.
- if (Arg->isPlaceholderType() ||
- Info.getDeducedDepth() != TemplateTypeParm->getDepth())
- return Sema::TDK_Success;
- unsigned Index = TemplateTypeParm->getIndex();
- bool RecanonicalizeArg = false;
- // 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 (isa<ArrayType>(Arg)) {
- Qualifiers Quals;
- Arg = S.Context.getUnqualifiedArrayType(Arg, Quals);
- if (Quals) {
- Arg = S.Context.getQualifiedType(Arg, Quals);
- RecanonicalizeArg = true;
- }
- }
- // The argument type can not be less qualified than the parameter
- // type.
- if (!(TDF & TDF_IgnoreQualifiers) &&
- hasInconsistentOrSupersetQualifiersOf(Param, Arg)) {
- Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
- Info.FirstArg = TemplateArgument(Param);
- Info.SecondArg = TemplateArgument(Arg);
- 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 (Arg->isFunctionType() && Param.hasQualifiers()) {
- return Sema::TDK_NonDeducedMismatch;
- }
- assert(TemplateTypeParm->getDepth() == Info.getDeducedDepth() &&
- "saw template type parameter with wrong depth");
- assert(Arg != S.Context.OverloadTy && "Unresolved overloaded function");
- QualType DeducedType = Arg;
- // Remove any qualifiers on the parameter from the deduced type.
- // We checked the qualifiers for consistency above.
- Qualifiers DeducedQs = DeducedType.getQualifiers();
- Qualifiers ParamQs = Param.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(Param);
- Info.SecondArg = TemplateArgument(Arg);
- 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);
- if (RecanonicalizeArg)
- DeducedType = S.Context.getCanonicalType(DeducedType);
- 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(ParamIn);
- Info.SecondArg = TemplateArgument(ArgIn);
- // 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 (isa<SubstTemplateTypeParmPackType>(Param))
- return Sema::TDK_Success;
- // Check the cv-qualifiers on the parameter and argument types.
- CanQualType CanParam = S.Context.getCanonicalType(Param);
- CanQualType CanArg = S.Context.getCanonicalType(Arg);
- if (!(TDF & TDF_IgnoreQualifiers)) {
- if (TDF & TDF_ParamWithReferenceType) {
- if (hasInconsistentOrSupersetQualifiersOf(Param, Arg))
- 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 (!Arg.getQualifiers().compatiblyIncludes(Param.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;
- Arg = S.Context.getUnqualifiedArrayType(Arg, Quals);
- Arg = S.Context.getQualifiedType(Arg, Param.getQualifiers());
- } else if (!IsPossiblyOpaquelyQualifiedType(Param)) {
- if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
- return Sema::TDK_NonDeducedMismatch;
- }
- // If the parameter type is not dependent, there is nothing to deduce.
- if (!Param->isDependentType()) {
- if (!(TDF & TDF_SkipNonDependent)) {
- bool NonDeduced =
- (TDF & TDF_AllowCompatibleFunctionType)
- ? !S.isSameOrCompatibleFunctionType(CanParam, CanArg)
- : Param != Arg;
- if (NonDeduced) {
- return Sema::TDK_NonDeducedMismatch;
- }
- }
- return Sema::TDK_Success;
- }
- } else if (!Param->isDependentType()) {
- CanQualType ParamUnqualType = CanParam.getUnqualifiedType(),
- ArgUnqualType = CanArg.getUnqualifiedType();
- bool Success =
- (TDF & TDF_AllowCompatibleFunctionType)
- ? S.isSameOrCompatibleFunctionType(ParamUnqualType, ArgUnqualType)
- : ParamUnqualType == ArgUnqualType;
- if (Success)
- return Sema::TDK_Success;
- }
- switch (Param->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.def"
- case Type::TemplateTypeParm:
- case Type::SubstTemplateTypeParmPack:
- llvm_unreachable("Type nodes handled above");
- // These types cannot be dependent, so simply check whether the types are
- // the same.
- 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:
- if (TDF & TDF_SkipNonDependent)
- return Sema::TDK_Success;
- if (TDF & TDF_IgnoreQualifiers) {
- Param = Param.getUnqualifiedType();
- Arg = Arg.getUnqualifiedType();
- }
- return Param == Arg? Sema::TDK_Success : Sema::TDK_NonDeducedMismatch;
- // _Complex T [placeholder extension]
- case Type::Complex:
- if (const ComplexType *ComplexArg = Arg->getAs<ComplexType>())
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- cast<ComplexType>(Param)->getElementType(),
- ComplexArg->getElementType(),
- Info, Deduced, TDF);
- return Sema::TDK_NonDeducedMismatch;
- // _Atomic T [extension]
- case Type::Atomic:
- if (const AtomicType *AtomicArg = Arg->getAs<AtomicType>())
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- cast<AtomicType>(Param)->getValueType(),
- AtomicArg->getValueType(),
- Info, Deduced, TDF);
- return Sema::TDK_NonDeducedMismatch;
- // T *
- case Type::Pointer: {
- QualType PointeeType;
- if (const PointerType *PointerArg = Arg->getAs<PointerType>()) {
- PointeeType = PointerArg->getPointeeType();
- } else if (const ObjCObjectPointerType *PointerArg
- = Arg->getAs<ObjCObjectPointerType>()) {
- PointeeType = PointerArg->getPointeeType();
- } else {
- return Sema::TDK_NonDeducedMismatch;
- }
- unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass);
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- cast<PointerType>(Param)->getPointeeType(),
- PointeeType,
- Info, Deduced, SubTDF);
- }
- // T &
- case Type::LValueReference: {
- const LValueReferenceType *ReferenceArg =
- Arg->getAs<LValueReferenceType>();
- if (!ReferenceArg)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- cast<LValueReferenceType>(Param)->getPointeeType(),
- ReferenceArg->getPointeeType(), Info, Deduced, 0);
- }
- // T && [C++0x]
- case Type::RValueReference: {
- const RValueReferenceType *ReferenceArg =
- Arg->getAs<RValueReferenceType>();
- if (!ReferenceArg)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- cast<RValueReferenceType>(Param)->getPointeeType(),
- ReferenceArg->getPointeeType(),
- Info, Deduced, 0);
- }
- // T [] (implied, but not stated explicitly)
- case Type::IncompleteArray: {
- const IncompleteArrayType *IncompleteArrayArg =
- S.Context.getAsIncompleteArrayType(Arg);
- if (!IncompleteArrayArg)
- return Sema::TDK_NonDeducedMismatch;
- unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- S.Context.getAsIncompleteArrayType(Param)->getElementType(),
- IncompleteArrayArg->getElementType(),
- Info, Deduced, SubTDF);
- }
- // T [integer-constant]
- case Type::ConstantArray: {
- const ConstantArrayType *ConstantArrayArg =
- S.Context.getAsConstantArrayType(Arg);
- if (!ConstantArrayArg)
- return Sema::TDK_NonDeducedMismatch;
- const ConstantArrayType *ConstantArrayParm =
- S.Context.getAsConstantArrayType(Param);
- if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
- return Sema::TDK_NonDeducedMismatch;
- unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- ConstantArrayParm->getElementType(),
- ConstantArrayArg->getElementType(),
- Info, Deduced, SubTDF);
- }
- // type [i]
- case Type::DependentSizedArray: {
- const ArrayType *ArrayArg = S.Context.getAsArrayType(Arg);
- if (!ArrayArg)
- return Sema::TDK_NonDeducedMismatch;
- unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
- // Check the element type of the arrays
- const DependentSizedArrayType *DependentArrayParm
- = S.Context.getAsDependentSizedArrayType(Param);
- if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- DependentArrayParm->getElementType(),
- ArrayArg->getElementType(),
- Info, Deduced, SubTDF))
- return Result;
- // Determine the array bound is something we can deduce.
- NonTypeTemplateParmDecl *NTTP
- = getDeducedParameterFromExpr(Info, DependentArrayParm->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 ConstantArrayType *ConstantArrayArg
- = dyn_cast<ConstantArrayType>(ArrayArg)) {
- llvm::APSInt Size(ConstantArrayArg->getSize());
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, Size,
- S.Context.getSizeType(),
- /*ArrayBound=*/true,
- Info, Deduced);
- }
- if (const DependentSizedArrayType *DependentArrayArg
- = dyn_cast<DependentSizedArrayType>(ArrayArg))
- if (DependentArrayArg->getSizeExpr())
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- DependentArrayArg->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: {
- unsigned SubTDF = TDF & TDF_TopLevelParameterTypeList;
- const FunctionProtoType *FunctionProtoArg =
- dyn_cast<FunctionProtoType>(Arg);
- if (!FunctionProtoArg)
- return Sema::TDK_NonDeducedMismatch;
- const FunctionProtoType *FunctionProtoParam =
- cast<FunctionProtoType>(Param);
- if (FunctionProtoParam->getMethodQuals()
- != FunctionProtoArg->getMethodQuals() ||
- FunctionProtoParam->getRefQualifier()
- != FunctionProtoArg->getRefQualifier() ||
- FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic())
- return Sema::TDK_NonDeducedMismatch;
- // Check return types.
- if (auto Result = DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, FunctionProtoParam->getReturnType(),
- FunctionProtoArg->getReturnType(), Info, Deduced, 0))
- return Result;
- // Check parameter types.
- if (auto Result = DeduceTemplateArguments(
- S, TemplateParams, FunctionProtoParam->param_type_begin(),
- FunctionProtoParam->getNumParams(),
- FunctionProtoArg->param_type_begin(),
- FunctionProtoArg->getNumParams(), Info, Deduced, SubTDF))
- 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 = FunctionProtoParam->getNoexceptExpr();
- if (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 (FunctionProtoArg->canThrow()) {
- case CT_Cannot:
- Noexcept = 1;
- LLVM_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,
- /*ArrayBound*/true, Info, Deduced);
- case CT_Dependent:
- if (Expr *ArgNoexceptExpr = FunctionProtoArg->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.
- Param = cast<InjectedClassNameType>(Param)
- ->getInjectedSpecializationType();
- assert(isa<TemplateSpecializationType>(Param) &&
- "injected class name is not a template specialization type");
- LLVM_FALLTHROUGH;
- // template-name<T> (where template-name refers to a class template)
- // template-name<i>
- // TT<T>
- // TT<i>
- // TT<>
- case Type::TemplateSpecialization: {
- const TemplateSpecializationType *SpecParam =
- cast<TemplateSpecializationType>(Param);
- // When Arg cannot be a derived class, we can just try to deduce template
- // arguments from the template-id.
- const RecordType *RecordT = Arg->getAs<RecordType>();
- if (!(TDF & TDF_DerivedClass) || !RecordT)
- return DeduceTemplateArguments(S, TemplateParams, SpecParam, Arg, Info,
- Deduced);
- SmallVector<DeducedTemplateArgument, 8> DeducedOrig(Deduced.begin(),
- Deduced.end());
- Sema::TemplateDeductionResult Result = DeduceTemplateArguments(
- S, TemplateParams, SpecParam, Arg, 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(), Arg))
- return Result;
- // 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.
- //
- // These alternatives are considered only if type deduction would
- // otherwise fail. If they yield more than one possible deduced A, the
- // type deduction fails.
- // Reset the incorrectly deduced argument from above.
- Deduced = DeducedOrig;
- // Use data recursion to crawl through the list of base classes.
- // Visited contains the set of nodes we have already visited, while
- // ToVisit is our stack of records that we still need to visit.
- llvm::SmallPtrSet<const RecordType *, 8> Visited;
- SmallVector<const RecordType *, 8> ToVisit;
- ToVisit.push_back(RecordT);
- bool Successful = false;
- SmallVector<DeducedTemplateArgument, 8> SuccessfulDeduced;
- while (!ToVisit.empty()) {
- // Retrieve the next class in the inheritance hierarchy.
- const RecordType *NextT = ToVisit.pop_back_val();
- // If we have already seen this type, skip it.
- if (!Visited.insert(NextT).second)
- continue;
- // If this is a base class, try to perform template argument
- // deduction from it.
- if (NextT != RecordT) {
- TemplateDeductionInfo BaseInfo(Info.getLocation());
- Sema::TemplateDeductionResult BaseResult =
- DeduceTemplateArguments(S, TemplateParams, SpecParam,
- QualType(NextT, 0), BaseInfo, Deduced);
- // If template argument deduction for this base was successful,
- // note that we had some success. Otherwise, ignore any deductions
- // from this base class.
- if (BaseResult == Sema::TDK_Success) {
- // If we've already seen some success, then deduction fails due to
- // an ambiguity (temp.deduct.call p5).
- if (Successful)
- return Sema::TDK_MiscellaneousDeductionFailure;
- Successful = true;
- std::swap(SuccessfulDeduced, Deduced);
- Info.Param = BaseInfo.Param;
- Info.FirstArg = BaseInfo.FirstArg;
- Info.SecondArg = BaseInfo.SecondArg;
- }
- Deduced = DeducedOrig;
- }
- // Visit base classes
- CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl());
- for (const auto &Base : Next->bases()) {
- assert(Base.getType()->isRecordType() &&
- "Base class that isn't a record?");
- ToVisit.push_back(Base.getType()->getAs<RecordType>());
- }
- }
- if (Successful) {
- std::swap(SuccessfulDeduced, Deduced);
- return Sema::TDK_Success;
- }
- return 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 MemberPointerType *MemPtrParam = cast<MemberPointerType>(Param);
- const MemberPointerType *MemPtrArg = dyn_cast<MemberPointerType>(Arg);
- if (!MemPtrArg)
- return Sema::TDK_NonDeducedMismatch;
- QualType ParamPointeeType = MemPtrParam->getPointeeType();
- if (ParamPointeeType->isFunctionType())
- S.adjustMemberFunctionCC(ParamPointeeType, /*IsStatic=*/true,
- /*IsCtorOrDtor=*/false, Info.getLocation());
- QualType ArgPointeeType = MemPtrArg->getPointeeType();
- if (ArgPointeeType->isFunctionType())
- S.adjustMemberFunctionCC(ArgPointeeType, /*IsStatic=*/true,
- /*IsCtorOrDtor=*/false, Info.getLocation());
- if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- ParamPointeeType,
- ArgPointeeType,
- Info, Deduced,
- TDF & TDF_IgnoreQualifiers))
- return Result;
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- QualType(MemPtrParam->getClass(), 0),
- QualType(MemPtrArg->getClass(), 0),
- Info, Deduced,
- TDF & TDF_IgnoreQualifiers);
- }
- // (clang extension)
- //
- // type(^)(T)
- // T(^)()
- // T(^)(T)
- case Type::BlockPointer: {
- const BlockPointerType *BlockPtrParam = cast<BlockPointerType>(Param);
- const BlockPointerType *BlockPtrArg = dyn_cast<BlockPointerType>(Arg);
- if (!BlockPtrArg)
- return Sema::TDK_NonDeducedMismatch;
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- BlockPtrParam->getPointeeType(),
- BlockPtrArg->getPointeeType(),
- Info, Deduced, 0);
- }
- // (clang extension)
- //
- // T __attribute__(((ext_vector_type(<integral constant>))))
- case Type::ExtVector: {
- const ExtVectorType *VectorParam = cast<ExtVectorType>(Param);
- if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) {
- // Make sure that the vectors have the same number of elements.
- if (VectorParam->getNumElements() != VectorArg->getNumElements())
- return Sema::TDK_NonDeducedMismatch;
- // Perform deduction on the element types.
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- VectorParam->getElementType(),
- VectorArg->getElementType(),
- Info, Deduced, TDF);
- }
- if (const DependentSizedExtVectorType *VectorArg
- = dyn_cast<DependentSizedExtVectorType>(Arg)) {
- // We can't check the number of elements, since the argument has a
- // dependent number of elements. This can only occur during partial
- // ordering.
- // Perform deduction on the element types.
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- VectorParam->getElementType(),
- VectorArg->getElementType(),
- Info, Deduced, TDF);
- }
- return Sema::TDK_NonDeducedMismatch;
- }
- case Type::DependentVector: {
- const auto *VectorParam = cast<DependentVectorType>(Param);
- if (const auto *VectorArg = dyn_cast<VectorType>(Arg)) {
- // Perform deduction on the element types.
- if (Sema::TemplateDeductionResult Result =
- DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, VectorParam->getElementType(),
- VectorArg->getElementType(), Info, Deduced, TDF))
- return Result;
- // Perform deduction on the vector size, if we can.
- NonTypeTemplateParmDecl *NTTP =
- getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
- ArgSize = VectorArg->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 *VectorArg = dyn_cast<DependentVectorType>(Arg)) {
- // Perform deduction on the element types.
- if (Sema::TemplateDeductionResult Result =
- DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, VectorParam->getElementType(),
- VectorArg->getElementType(), Info, Deduced, TDF))
- return Result;
- // Perform deduction on the vector size, if we can.
- NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(
- Info, VectorParam->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, VectorArg->getSizeExpr(), Info, Deduced);
- }
- return Sema::TDK_NonDeducedMismatch;
- }
- // (clang extension)
- //
- // T __attribute__(((ext_vector_type(N))))
- case Type::DependentSizedExtVector: {
- const DependentSizedExtVectorType *VectorParam
- = cast<DependentSizedExtVectorType>(Param);
- if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) {
- // Perform deduction on the element types.
- if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- VectorParam->getElementType(),
- VectorArg->getElementType(),
- Info, Deduced, TDF))
- return Result;
- // Perform deduction on the vector size, if we can.
- NonTypeTemplateParmDecl *NTTP
- = getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
- ArgSize = VectorArg->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 DependentSizedExtVectorType *VectorArg
- = dyn_cast<DependentSizedExtVectorType>(Arg)) {
- // Perform deduction on the element types.
- if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- VectorParam->getElementType(),
- VectorArg->getElementType(),
- Info, Deduced, TDF))
- return Result;
- // Perform deduction on the vector size, if we can.
- NonTypeTemplateParmDecl *NTTP
- = getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- VectorArg->getSizeExpr(),
- Info, Deduced);
- }
- return Sema::TDK_NonDeducedMismatch;
- }
- // (clang extension)
- //
- // T __attribute__(((address_space(N))))
- case Type::DependentAddressSpace: {
- const DependentAddressSpaceType *AddressSpaceParam =
- cast<DependentAddressSpaceType>(Param);
- if (const DependentAddressSpaceType *AddressSpaceArg =
- dyn_cast<DependentAddressSpaceType>(Arg)) {
- // Perform deduction on the pointer type.
- if (Sema::TemplateDeductionResult Result =
- DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, AddressSpaceParam->getPointeeType(),
- AddressSpaceArg->getPointeeType(), Info, Deduced, TDF))
- return Result;
- // Perform deduction on the address space, if we can.
- NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(
- Info, AddressSpaceParam->getAddrSpaceExpr());
- if (!NTTP)
- return Sema::TDK_Success;
- return DeduceNonTypeTemplateArgument(
- S, TemplateParams, NTTP, AddressSpaceArg->getAddrSpaceExpr(), Info,
- Deduced);
- }
- if (isTargetAddressSpace(Arg.getAddressSpace())) {
- llvm::APSInt ArgAddressSpace(S.Context.getTypeSize(S.Context.IntTy),
- false);
- ArgAddressSpace = toTargetAddressSpace(Arg.getAddressSpace());
- // Perform deduction on the pointer types.
- if (Sema::TemplateDeductionResult Result =
- DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, AddressSpaceParam->getPointeeType(),
- S.Context.removeAddrSpaceQualType(Arg), Info, Deduced, TDF))
- return Result;
- // Perform deduction on the address space, if we can.
- NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(
- Info, AddressSpaceParam->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::TypeOfExpr:
- case Type::TypeOf:
- case Type::DependentName:
- case Type::UnresolvedUsing:
- case Type::Decltype:
- case Type::UnaryTransform:
- case Type::Auto:
- 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 &Param,
- TemplateArgument Arg,
- 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 (Arg.isPackExpansion())
- Arg = Arg.getPackExpansionPattern();
- switch (Param.getKind()) {
- case TemplateArgument::Null:
- llvm_unreachable("Null template argument in parameter list");
- case TemplateArgument::Type:
- if (Arg.getKind() == TemplateArgument::Type)
- return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
- Param.getAsType(),
- Arg.getAsType(),
- Info, Deduced, 0);
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::Template:
- if (Arg.getKind() == TemplateArgument::Template)
- return DeduceTemplateArguments(S, TemplateParams,
- Param.getAsTemplate(),
- Arg.getAsTemplate(), Info, Deduced);
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::TemplateExpansion:
- llvm_unreachable("caller should handle pack expansions");
- case TemplateArgument::Declaration:
- if (Arg.getKind() == TemplateArgument::Declaration &&
- isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()))
- return Sema::TDK_Success;
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::NullPtr:
- if (Arg.getKind() == TemplateArgument::NullPtr &&
- S.Context.hasSameType(Param.getNullPtrType(), Arg.getNullPtrType()))
- return Sema::TDK_Success;
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::Integral:
- if (Arg.getKind() == TemplateArgument::Integral) {
- if (hasSameExtendedValue(Param.getAsIntegral(), Arg.getAsIntegral()))
- return Sema::TDK_Success;
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
- }
- if (Arg.getKind() == TemplateArgument::Expression) {
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
- }
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- return Sema::TDK_NonDeducedMismatch;
- case TemplateArgument::Expression:
- if (NonTypeTemplateParmDecl *NTTP
- = getDeducedParameterFromExpr(Info, Param.getAsExpr())) {
- if (Arg.getKind() == TemplateArgument::Integral)
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- Arg.getAsIntegral(),
- Arg.getIntegralType(),
- /*ArrayBound=*/false,
- Info, Deduced);
- if (Arg.getKind() == TemplateArgument::NullPtr)
- return DeduceNullPtrTemplateArgument(S, TemplateParams, NTTP,
- Arg.getNullPtrType(),
- Info, Deduced);
- if (Arg.getKind() == TemplateArgument::Expression)
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- Arg.getAsExpr(), Info, Deduced);
- if (Arg.getKind() == TemplateArgument::Declaration)
- return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
- Arg.getAsDecl(),
- Arg.getParamTypeForDecl(),
- Info, Deduced);
- Info.FirstArg = Param;
- Info.SecondArg = Arg;
- 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> Params,
- ArrayRef<TemplateArgument> Args,
- 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(Params))
- 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(Params, ParamIdx); ++ParamIdx) {
- if (!Params[ParamIdx].isPackExpansion()) {
- // The simple case: deduce template arguments by matching Pi and Ai.
- // Check whether we have enough arguments.
- if (!hasTemplateArgumentForDeduction(Args, 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 (Args[ArgIdx].isPackExpansion())
- return Sema::TDK_MiscellaneousDeductionFailure;
- // Perform deduction for this Pi/Ai pair.
- if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArguments(S, TemplateParams,
- Params[ParamIdx], Args[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 = Params[ParamIdx].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(Args, ArgIdx) &&
- PackScope.hasNextElement();
- ++ArgIdx) {
- // Deduce template arguments from the pattern.
- if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[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 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:
- if (X.pack_size() != Y.pack_size())
- return false;
- for (TemplateArgument::pack_iterator XP = X.pack_begin(),
- XPEnd = X.pack_end(),
- YP = Y.pack_begin();
- XP != XPEnd; ++XP, ++YP)
- if (!isSameTemplateArg(Context, *XP, *YP, 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.getAsTemplate();
- 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(Arg, Builder.getWithLocInContext(Context),
- Loc);
- return TemplateArgumentLoc(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!");
- }
- /// 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> &Output) {
- 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, Output,
- 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> PackedArgsBuilder;
- 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, PackedArgsBuilder.size()))
- return true;
- // Move the converted template argument into our argument pack.
- PackedArgsBuilder.push_back(Output.pop_back_val());
- }
- // If the pack is empty, we still need to substitute into the parameter
- // itself, in case that substitution fails.
- if (PackedArgsBuilder.empty()) {
- LocalInstantiationScope Scope(S);
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
- MultiLevelTemplateArgumentList Args(TemplateArgs);
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
- Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
- NTTP, Output,
- 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, Output,
- 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.
- Output.push_back(
- TemplateArgument::CreatePackCopy(S.Context, PackedArgsBuilder));
- 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> &Builder,
- 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(/*TreatNoDeductionsAsNonDeduced*/false))
- 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.
- Builder.push_back(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, Builder)) {
- Info.Param = makeTemplateParameter(Param);
- // FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
- 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 = S.SubstDefaultTemplateArgumentIfAvailable(
- TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder,
- 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, Builder));
- 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, Builder,
- 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, Builder));
- 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;
- };
- /// Complete template argument deduction for a partial specialization.
- template <typename T>
- static typename std::enable_if<IsPartialSpecialization<T>::value,
- Sema::TemplateDeductionResult>::type
- 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> Builder;
- if (auto Result = ConvertDeducedTemplateArguments(
- S, Partial, IsPartialOrdering, Deduced, Info, Builder))
- return Result;
- // Form the template argument list from the deduced template arguments.
- TemplateArgumentList *DeducedArgumentList
- = TemplateArgumentList::CreateCopy(S.Context, Builder);
- Info.reset(DeducedArgumentList);
- // 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();
- const TemplateArgumentLoc *PartialTemplateArgs =
- PartialTemplArgInfo->getTemplateArgs();
- TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc,
- PartialTemplArgInfo->RAngleLoc);
- if (S.Subst(PartialTemplateArgs, PartialTemplArgInfo->NumTemplateArgs,
- InstArgs, MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
- 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 = PartialTemplateArgs[ArgIdx].getArgument();
- return Sema::TDK_SubstitutionFailure;
- }
- SmallVector<TemplateArgument, 4> ConvertedInstArgs;
- if (S.CheckTemplateArgumentList(Template, Partial->getLocation(), InstArgs,
- false, ConvertedInstArgs))
- return Sema::TDK_SubstitutionFailure;
- TemplateParameterList *TemplateParams = Template->getTemplateParameters();
- for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
- TemplateArgument InstArg = ConvertedInstArgs.data()[I];
- if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
- Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
- Info.FirstArg = TemplateArgs[I];
- Info.SecondArg = InstArg;
- return Sema::TDK_NonDeducedMismatch;
- }
- }
- if (Trap.hasErrorOccurred())
- return Sema::TDK_SubstitutionFailure;
- 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> Builder;
- if (auto Result = ConvertDeducedTemplateArguments(
- S, Template, /*IsDeduced*/PartialOrdering, Deduced, Info, Builder))
- 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 = Builder[I];
- if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg,
- /*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;
- 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);
- 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;
- return ::FinishTemplateArgumentDeduction(
- *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info);
- }
- /// 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);
- 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;
- return ::FinishTemplateArgumentDeduction(
- *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info);
- }
- /// 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> Builder;
- // 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, Builder, false) ||
- Trap.hasErrorOccurred()) {
- unsigned Index = Builder.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 *ExplicitArgumentList
- = TemplateArgumentList::CreateCopy(Context, Builder);
- Info.setExplicitArgs(ExplicitArgumentList);
- // 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 (!Builder.empty()) {
- const TemplateArgument &Arg = Builder.back();
- if (Arg.getKind() == TemplateArgument::Pack) {
- auto *Param = TemplateParams->getParam(Builder.size() - 1);
- // If this is a fully-saturated fixed-size pack, it should be
- // fully-substituted, not partially-substituted.
- Optional<unsigned> Expansions = getExpandedPackSize(Param);
- if (!Expansions || Arg.pack_size() < *Expansions) {
- PartiallySubstitutedPackIndex = Builder.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;
- // 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(),
- MultiLevelTemplateArgumentList(*ExplicitArgumentList),
- 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(),
- MultiLevelTemplateArgumentList(*ExplicitArgumentList),
- Function->getTypeSpecStartLoc(), Function->getDeclName());
- if (ResultType.isNull() || Trap.hasErrorOccurred())
- 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(),
- MultiLevelTemplateArgumentList(*ExplicitArgumentList),
- 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,
- MultiLevelTemplateArgumentList(*ExplicitArgumentList)))
- 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 = ExplicitArgumentList->size(); I != N; ++I) {
- const TemplateArgument &Arg = ExplicitArgumentList->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).getValueOr(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> Builder;
- if (auto Result = ConvertDeducedTemplateArguments(
- *this, FunctionTemplate, /*IsDeduced*/true, Deduced, Info, Builder,
- 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 *DeducedArgumentList
- = TemplateArgumentList::CreateCopy(Context, Builder);
- Info.reset(DeducedArgumentList);
- // 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(*DeducedArgumentList);
- 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() == DeducedArgumentList &&
- !Trap.hasErrorOccurred())
- Info.take();
- // 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;
- }
- 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.resolveAddressOfOnlyViableOverloadCandidate(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()) {
- S.completeExprArrayBound(Arg);
- ArgType = Arg->getType();
- }
- // 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())
- 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 (ArgType->isArrayType())
- ArgType = S.Context.getArrayDecayedType(ArgType);
- // - 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,
- else if (ArgType->isFunctionType())
- ArgType = S.Context.getPointerType(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->getAs<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;
- }
- // 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 (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 FunctionProtoType *Proto
- = Function->getType()->getAs<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 =
- 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.
- 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;
- return FinishTemplateArgumentDeduction(
- FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
- &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() {
- ContextRAII SavedContext(*this, CallingCtx);
- return CheckNonDependent(ParamTypesForArgChecking);
- });
- }
- QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType,
- QualType FunctionType,
- bool AdjustExceptionSpec) {
- if (ArgFunctionType.isNull())
- return ArgFunctionType;
- const FunctionProtoType *FunctionTypeP =
- FunctionType->castAs<FunctionProtoType>();
- const FunctionProtoType *ArgFunctionTypeP =
- ArgFunctionType->getAs<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) {
- if (TemplateDeductionResult Result
- = SubstituteExplicitTemplateArguments(FunctionTemplate,
- *ExplicitTemplateArgs,
- Deduced, ParamTypes,
- &FunctionType, Info))
- 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 = SubstAutoType(FunctionType, Context.DependentTy);
- HasDeducedReturnType = true;
- }
- if (!ArgFunctionType.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;
- }
- if (TemplateDeductionResult Result
- = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
- NumExplicitlySpecified,
- Specialization, Info))
- 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
- = 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), Replacement(),
- 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);
- auto NewTL = TLB.push<AutoTypeLoc>(Result);
- NewTL.setNameLoc(TL.getNameLoc());
- 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
- Sema::DeduceAutoResult
- Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result,
- Optional<unsigned> DependentDeductionDepth) {
- return DeduceAutoType(Type->getTypeLoc(), Init, Result,
- DependentDeductionDepth);
- }
- /// Attempt to produce an informative diagostic explaining why auto deduction
- /// failed.
- /// \return \c true if diagnosed, \c false if not.
- static bool diagnoseAutoDeductionFailure(Sema &S,
- Sema::TemplateDeductionResult TDK,
- TemplateDeductionInfo &Info,
- ArrayRef<SourceRange> Ranges) {
- switch (TDK) {
- case Sema::TDK_Inconsistent: {
- // Inconsistent deduction means we were deducing from an initializer list.
- auto D = S.Diag(Info.getLocation(), diag::err_auto_inconsistent_deduction);
- D << Info.FirstArg << Info.SecondArg;
- for (auto R : Ranges)
- D << R;
- return true;
- }
- // FIXME: Are there other cases for which a custom diagnostic is more useful
- // than the basic "types don't match" diagnostic?
- default:
- 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 DependentDeductionDepth Set if we should permit deduction in
- /// dependent cases. This is necessary for template partial ordering with
- /// 'auto' template parameters. The value specified is the template
- /// parameter depth at which we should perform 'auto' deduction.
- Sema::DeduceAutoResult
- Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
- Optional<unsigned> DependentDeductionDepth) {
- if (Init->getType()->isNonOverloadPlaceholderType()) {
- ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
- if (NonPlaceholder.isInvalid())
- return DAR_FailedAlreadyDiagnosed;
- Init = NonPlaceholder.get();
- }
- DependentAuto DependentResult = {
- /*.IsPack = */ (bool)Type.getAs<PackExpansionTypeLoc>()};
- if (!DependentDeductionDepth &&
- (Type.getType()->isDependentType() || Init->isTypeDependent())) {
- Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type);
- assert(!Result.isNull() && "substituting DependentTy can't fail");
- return DAR_Succeeded;
- }
- // Find the depth of template parameter to synthesize.
- unsigned Depth = DependentDeductionDepth.getValueOr(0);
- // If this is a 'decltype(auto)' specifier, do the decltype dance.
- // Since 'decltype(auto)' can only occur at the top of the type, we
- // don't need to go digging for it.
- if (const AutoType *AT = Type.getType()->getAs<AutoType>()) {
- if (AT->isDecltypeAuto()) {
- if (isa<InitListExpr>(Init)) {
- Diag(Init->getBeginLoc(), diag::err_decltype_auto_initializer_list);
- return DAR_FailedAlreadyDiagnosed;
- }
- ExprResult ER = CheckPlaceholderExpr(Init);
- if (ER.isInvalid())
- return DAR_FailedAlreadyDiagnosed;
- Init = ER.get();
- QualType Deduced = BuildDecltypeType(Init, Init->getBeginLoc(), false);
- if (Deduced.isNull())
- return DAR_FailedAlreadyDiagnosed;
- // FIXME: Support a non-canonical deduced type for 'auto'.
- Deduced = Context.getCanonicalType(Deduced);
- Result = SubstituteDeducedTypeTransform(*this, Deduced).Apply(Type);
- if (Result.isNull())
- return DAR_FailedAlreadyDiagnosed;
- return DAR_Succeeded;
- } else if (!getLangOpts().CPlusPlus) {
- if (isa<InitListExpr>(Init)) {
- Diag(Init->getBeginLoc(), diag::err_auto_init_list_from_c);
- return DAR_FailedAlreadyDiagnosed;
- }
- }
- }
- SourceLocation Loc = Init->getExprLoc();
- LocalInstantiationScope InstScope(*this);
- // Build template<class TemplParam> void Func(FuncParam);
- TemplateTypeParmDecl *TemplParam = TemplateTypeParmDecl::Create(
- Context, nullptr, SourceLocation(), Loc, Depth, 0, nullptr, false, false);
- QualType TemplArg = QualType(TemplParam->getTypeForDecl(), 0);
- NamedDecl *TemplParamPtr = TemplParam;
- FixedSizeTemplateParameterListStorage<1, false> TemplateParamsSt(
- Loc, Loc, TemplParamPtr, Loc, nullptr);
- QualType FuncParam =
- SubstituteDeducedTypeTransform(*this, TemplArg, /*UseTypeSugar*/false)
- .Apply(Type);
- assert(!FuncParam.isNull() &&
- "substituting template parameter for 'auto' failed");
- // Deduce type of TemplParam in Func(Init)
- SmallVector<DeducedTemplateArgument, 1> Deduced;
- Deduced.resize(1);
- TemplateDeductionInfo Info(Loc, Depth);
- // If deduction failed, don't diagnose if the initializer is dependent; it
- // might acquire a matching type in the instantiation.
- auto DeductionFailed = [&](TemplateDeductionResult TDK,
- ArrayRef<SourceRange> Ranges) -> DeduceAutoResult {
- if (Init->isTypeDependent()) {
- Result =
- SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type);
- assert(!Result.isNull() && "substituting DependentTy can't fail");
- return DAR_Succeeded;
- }
- if (diagnoseAutoDeductionFailure(*this, TDK, Info, Ranges))
- return DAR_FailedAlreadyDiagnosed;
- return DAR_Failed;
- };
- SmallVector<OriginalCallArg, 4> OriginalCallArgs;
- InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
- 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 DAR_Failed;
- SourceRange DeducedFromInitRange;
- for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) {
- Expr *Init = InitList->getInit(i);
- if (auto TDK = DeduceTemplateArgumentsFromCallArgument(
- *this, TemplateParamsSt.get(), 0, TemplArg, Init,
- Info, Deduced, OriginalCallArgs, /*Decomposed*/ true,
- /*ArgIdx*/ 0, /*TDF*/ 0))
- return DeductionFailed(TDK, {DeducedFromInitRange,
- Init->getSourceRange()});
- if (DeducedFromInitRange.isInvalid() &&
- Deduced[0].getKind() != TemplateArgument::Null)
- DeducedFromInitRange = Init->getSourceRange();
- }
- } else {
- if (!getLangOpts().CPlusPlus && Init->refersToBitField()) {
- Diag(Loc, diag::err_auto_bitfield);
- return DAR_FailedAlreadyDiagnosed;
- }
- 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, {});
- QualType DeducedType = Deduced[0].getAsType();
- if (InitList) {
- DeducedType = BuildStdInitializerList(DeducedType, Loc);
- if (DeducedType.isNull())
- return DAR_FailedAlreadyDiagnosed;
- }
- Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type);
- if (Result.isNull())
- return DAR_FailedAlreadyDiagnosed;
- // 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 DAR_Succeeded;
- }
- QualType Sema::SubstAutoType(QualType TypeWithAuto,
- QualType TypeToReplaceAuto) {
- if (TypeToReplaceAuto->isDependentType())
- return SubstituteDeducedTypeTransform(
- *this, DependentAuto{
- TypeToReplaceAuto->containsUnexpandedParameterPack()})
- .TransformType(TypeWithAuto);
- return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto)
- .TransformType(TypeWithAuto);
- }
- TypeSourceInfo *Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
- QualType TypeToReplaceAuto) {
- if (TypeToReplaceAuto->isDependentType())
- return SubstituteDeducedTypeTransform(
- *this,
- DependentAuto{
- TypeToReplaceAuto->containsUnexpandedParameterPack()})
- .TransformType(TypeWithAuto);
- return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto)
- .TransformType(TypeWithAuto);
- }
- QualType Sema::ReplaceAutoType(QualType 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.
- QualType RetType = getLambdaConversionFunctionResultType(
- CallOp->getType()->castAs<FunctionProtoType>());
- 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) {
- 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);
- }
- 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 (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;
- }
- /// Determine whether this a function template whose parameter-type-list
- /// ends with a function parameter pack.
- static bool isVariadicFunctionTemplate(FunctionTemplateDecl *FunTmpl) {
- FunctionDecl *Function = FunTmpl->getTemplatedDecl();
- unsigned NumParams = Function->getNumParams();
- if (NumParams == 0)
- return false;
- ParmVarDecl *Last = Function->getParamDecl(NumParams - 1);
- if (!Last->isParameterPack())
- return false;
- // Make sure that no previous parameter is a parameter pack.
- while (--NumParams > 0) {
- if (Function->getParamDecl(NumParams - 1)->isParameterPack())
- 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.
- ///
- /// \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 Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
- NumCallArguments1);
- bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
- NumCallArguments2);
- if (Better1 != Better2) // We have a clear winner
- return Better1 ? FT1 : FT2;
- if (!Better1 && !Better2) // Neither is better than the other
- return nullptr;
- // FIXME: This mimics what GCC implements, but doesn't match up with the
- // proposed resolution for core issue 692. This area needs to be sorted out,
- // but for now we attempt to maintain compatibility.
- bool Variadic1 = isVariadicFunctionTemplate(FT1);
- bool Variadic2 = isVariadicFunctionTemplate(FT2);
- if (Variadic1 != Variadic2)
- return Variadic1? FT2 : FT1;
- return nullptr;
- }
- /// 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);
- auto *TST1 = T1->castAs<TemplateSpecializationType>();
- if (FinishTemplateArgumentDeduction(
- S, P2, /*IsPartialOrdering=*/true,
- TemplateArgumentList(TemplateArgumentList::OnStack,
- TST1->template_arguments()),
- Deduced, Info))
- return false;
- return true;
- }
- /// 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);
- bool Better1 = isAtLeastAsSpecializedAs(*this, PT1, PT2, PS2, Info);
- bool Better2 = isAtLeastAsSpecializedAs(*this, PT2, PT1, PS1, Info);
- if (Better1 == Better2)
- return nullptr;
- return Better1 ? PS1 : PS2;
- }
- bool Sema::isMoreSpecializedThanPrimary(
- ClassTemplatePartialSpecializationDecl *Spec, TemplateDeductionInfo &Info) {
- ClassTemplateDecl *Primary = Spec->getSpecializedTemplate();
- QualType PrimaryT = Primary->getInjectedClassNameSpecialization();
- QualType PartialT = Spec->getInjectedSpecializationType();
- if (!isAtLeastAsSpecializedAs(*this, PartialT, PrimaryT, Primary, Info))
- return false;
- if (isAtLeastAsSpecializedAs(*this, PrimaryT, PartialT, Spec, Info)) {
- Info.clearSFINAEDiagnostic();
- return false;
- }
- return true;
- }
- 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);
- bool Better1 = isAtLeastAsSpecializedAs(*this, PT1, PT2, PS2, Info);
- bool Better2 = isAtLeastAsSpecializedAs(*this, PT2, PT1, PS1, Info);
- if (Better1 == Better2)
- return nullptr;
- return Better1 ? PS1 : PS2;
- }
- bool Sema::isMoreSpecializedThanPrimary(
- VarTemplatePartialSpecializationDecl *Spec, TemplateDeductionInfo &Info) {
- TemplateDecl *Primary = Spec->getSpecializedTemplate();
- // FIXME: Cache the injected template arguments rather than recomputing
- // them for each partial specialization.
- SmallVector<TemplateArgument, 8> PrimaryArgs;
- Context.getInjectedTemplateArgs(Primary->getTemplateParameters(),
- PrimaryArgs);
- TemplateName CanonTemplate =
- Context.getCanonicalTemplateName(TemplateName(Primary));
- QualType PrimaryT = Context.getTemplateSpecializationType(
- CanonTemplate, PrimaryArgs);
- QualType PartialT = Context.getTemplateSpecializationType(
- CanonTemplate, Spec->getTemplateArgs().asArray());
- if (!isAtLeastAsSpecializedAs(*this, PartialT, PrimaryT, Primary, Info))
- return false;
- if (isAtLeastAsSpecializedAs(*this, PrimaryT, PartialT, Spec, Info)) {
- Info.clearSFINAEDiagnostic();
- return false;
- }
- return true;
- }
- 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.
- if (CheckTemplateArgumentList(AArg, Loc, PArgList, false, PArgs) ||
- Trap.hasErrorOccurred())
- return false;
- }
- QualType AType = Context.getTemplateSpecializationType(X, AArgs);
- QualType PType = Context.getTemplateSpecializationType(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);
- }
- /// 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) {
- // We can deduce from a pack expansion.
- if (const PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(E))
- E = Expansion->getPattern();
- // Skip through any implicit casts we added while type-checking, and any
- // substitutions performed by template alias expansion.
- while (true) {
- if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
- E = ICE->getSubExpr();
- else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(E))
- E = CE->getSubExpr();
- else if (const SubstNonTypeTemplateParmExpr *Subst =
- dyn_cast<SubstNonTypeTemplateParmExpr>(E))
- E = Subst->getReplacement();
- else
- break;
- }
- // FIXME: if !OnlyDeduced, we have to walk the whole subexpression to
- // find other occurrences of template parameters.
- const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
- if (!DRE)
- return;
- const NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
- 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
- LLVM_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::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);
- MarkUsedTemplateParameters(Ctx,
- QualType(Subst->getReplacedParameter(), 0),
- OnlyDeduced, Depth, Used);
- MarkUsedTemplateParameters(Ctx, Subst->getArgumentPack(),
- OnlyDeduced, Depth, Used);
- break;
- }
- case Type::InjectedClassName:
- T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType();
- LLVM_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 (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
- MarkUsedTemplateParameters(Ctx, Spec->getArg(I), 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 (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
- MarkUsedTemplateParameters(Ctx, Spec->getArg(I), OnlyDeduced, Depth,
- Used);
- break;
- }
- case Type::TypeOf:
- if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx,
- cast<TypeOfType>(T)->getUnderlyingType(),
- 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;
- // 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:
- #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.def"
- 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 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();
- }
|