123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847 |
- //===------- SemaTemplate.cpp - Semantic Analysis for C++ Templates -------===/
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //===----------------------------------------------------------------------===/
- //
- // This file implements semantic analysis for C++ templates.
- //===----------------------------------------------------------------------===/
- #include "Sema.h"
- #include "clang/AST/ASTContext.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/ExprCXX.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/Parse/DeclSpec.h"
- #include "clang/Basic/LangOptions.h"
- using namespace clang;
- /// isTemplateName - Determines whether the identifier II is a
- /// template name in the current scope, and returns the template
- /// declaration if II names a template. An optional CXXScope can be
- /// passed to indicate the C++ scope in which the identifier will be
- /// found.
- TemplateNameKind Sema::isTemplateName(const IdentifierInfo &II, Scope *S,
- TemplateTy &TemplateResult,
- const CXXScopeSpec *SS) {
- NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
- TemplateNameKind TNK = TNK_Non_template;
- TemplateDecl *Template = 0;
- if (IIDecl) {
- if ((Template = dyn_cast<TemplateDecl>(IIDecl))) {
- if (isa<FunctionTemplateDecl>(IIDecl))
- TNK = TNK_Function_template;
- else if (isa<ClassTemplateDecl>(IIDecl) ||
- isa<TemplateTemplateParmDecl>(IIDecl))
- TNK = TNK_Type_template;
- else
- assert(false && "Unknown template declaration kind");
- } else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(IIDecl)) {
- // C++ [temp.local]p1:
- // Like normal (non-template) classes, class templates have an
- // injected-class-name (Clause 9). The injected-class-name
- // can be used with or without a template-argument-list. When
- // it is used without a template-argument-list, it is
- // equivalent to the injected-class-name followed by the
- // template-parameters of the class template enclosed in
- // <>. When it is used with a template-argument-list, it
- // refers to the specified class template specialization,
- // which could be the current specialization or another
- // specialization.
- if (Record->isInjectedClassName()) {
- Record = cast<CXXRecordDecl>(Context.getCanonicalDecl(Record));
- if ((Template = Record->getDescribedClassTemplate()))
- TNK = TNK_Type_template;
- else if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
- Template = Spec->getSpecializedTemplate();
- TNK = TNK_Type_template;
- }
- }
- }
- // FIXME: What follows is a gross hack.
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(IIDecl)) {
- if (FD->getType()->isDependentType()) {
- TemplateResult = TemplateTy::make(FD);
- return TNK_Function_template;
- }
- } else if (OverloadedFunctionDecl *Ovl
- = dyn_cast<OverloadedFunctionDecl>(IIDecl)) {
- for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
- FEnd = Ovl->function_end();
- F != FEnd; ++F) {
- if ((*F)->getType()->isDependentType()) {
- TemplateResult = TemplateTy::make(Ovl);
- return TNK_Function_template;
- }
- }
- }
- if (TNK != TNK_Non_template) {
- if (SS && SS->isSet() && !SS->isInvalid()) {
- NestedNameSpecifier *Qualifier
- = static_cast<NestedNameSpecifier *>(SS->getScopeRep());
- TemplateResult
- = TemplateTy::make(Context.getQualifiedTemplateName(Qualifier,
- false,
- Template));
- } else
- TemplateResult = TemplateTy::make(TemplateName(Template));
- }
- }
- return TNK;
- }
- /// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
- /// that the template parameter 'PrevDecl' is being shadowed by a new
- /// declaration at location Loc. Returns true to indicate that this is
- /// an error, and false otherwise.
- bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
- assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
- // Microsoft Visual C++ permits template parameters to be shadowed.
- if (getLangOptions().Microsoft)
- return false;
- // C++ [temp.local]p4:
- // A template-parameter shall not be redeclared within its
- // scope (including nested scopes).
- Diag(Loc, diag::err_template_param_shadow)
- << cast<NamedDecl>(PrevDecl)->getDeclName();
- Diag(PrevDecl->getLocation(), diag::note_template_param_here);
- return true;
- }
- /// AdjustDeclIfTemplate - If the given decl happens to be a template, reset
- /// the parameter D to reference the templated declaration and return a pointer
- /// to the template declaration. Otherwise, do nothing to D and return null.
- TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) {
- if (TemplateDecl *Temp = dyn_cast<TemplateDecl>(D.getAs<Decl>())) {
- D = DeclPtrTy::make(Temp->getTemplatedDecl());
- return Temp;
- }
- return 0;
- }
- /// ActOnTypeParameter - Called when a C++ template type parameter
- /// (e.g., "typename T") has been parsed. Typename specifies whether
- /// the keyword "typename" was used to declare the type parameter
- /// (otherwise, "class" was used), and KeyLoc is the location of the
- /// "class" or "typename" keyword. ParamName is the name of the
- /// parameter (NULL indicates an unnamed template parameter) and
- /// ParamName is the location of the parameter name (if any).
- /// If the type parameter has a default argument, it will be added
- /// later via ActOnTypeParameterDefault.
- Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
- SourceLocation EllipsisLoc,
- SourceLocation KeyLoc,
- IdentifierInfo *ParamName,
- SourceLocation ParamNameLoc,
- unsigned Depth, unsigned Position) {
- assert(S->isTemplateParamScope() &&
- "Template type parameter not in template parameter scope!");
- bool Invalid = false;
- if (ParamName) {
- NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
- if (PrevDecl && PrevDecl->isTemplateParameter())
- Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
- PrevDecl);
- }
- SourceLocation Loc = ParamNameLoc;
- if (!ParamName)
- Loc = KeyLoc;
- TemplateTypeParmDecl *Param
- = TemplateTypeParmDecl::Create(Context, CurContext, Loc,
- Depth, Position, ParamName, Typename,
- Ellipsis);
- if (Invalid)
- Param->setInvalidDecl();
- if (ParamName) {
- // Add the template parameter into the current scope.
- S->AddDecl(DeclPtrTy::make(Param));
- IdResolver.AddDecl(Param);
- }
- return DeclPtrTy::make(Param);
- }
- /// ActOnTypeParameterDefault - Adds a default argument (the type
- /// Default) to the given template type parameter (TypeParam).
- void Sema::ActOnTypeParameterDefault(DeclPtrTy TypeParam,
- SourceLocation EqualLoc,
- SourceLocation DefaultLoc,
- TypeTy *DefaultT) {
- TemplateTypeParmDecl *Parm
- = cast<TemplateTypeParmDecl>(TypeParam.getAs<Decl>());
- QualType Default = QualType::getFromOpaquePtr(DefaultT);
- // C++0x [temp.param]p9:
- // A default template-argument may be specified for any kind of
- // template-parameter that is not a template parameter pack.
- if (Parm->isParameterPack()) {
- Diag(DefaultLoc, diag::err_template_param_pack_default_arg);
- return;
- }
-
- // C++ [temp.param]p14:
- // A template-parameter shall not be used in its own default argument.
- // FIXME: Implement this check! Needs a recursive walk over the types.
-
- // Check the template argument itself.
- if (CheckTemplateArgument(Parm, Default, DefaultLoc)) {
- Parm->setInvalidDecl();
- return;
- }
- Parm->setDefaultArgument(Default, DefaultLoc, false);
- }
- /// \brief Check that the type of a non-type template parameter is
- /// well-formed.
- ///
- /// \returns the (possibly-promoted) parameter type if valid;
- /// otherwise, produces a diagnostic and returns a NULL type.
- QualType
- Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
- // C++ [temp.param]p4:
- //
- // A non-type template-parameter shall have one of the following
- // (optionally cv-qualified) types:
- //
- // -- integral or enumeration type,
- if (T->isIntegralType() || T->isEnumeralType() ||
- // -- pointer to object or pointer to function,
- (T->isPointerType() &&
- (T->getAsPointerType()->getPointeeType()->isObjectType() ||
- T->getAsPointerType()->getPointeeType()->isFunctionType())) ||
- // -- reference to object or reference to function,
- T->isReferenceType() ||
- // -- pointer to member.
- T->isMemberPointerType() ||
- // If T is a dependent type, we can't do the check now, so we
- // assume that it is well-formed.
- T->isDependentType())
- return T;
- // C++ [temp.param]p8:
- //
- // A non-type template-parameter of type "array of T" or
- // "function returning T" is adjusted to be of type "pointer to
- // T" or "pointer to function returning T", respectively.
- else if (T->isArrayType())
- // FIXME: Keep the type prior to promotion?
- return Context.getArrayDecayedType(T);
- else if (T->isFunctionType())
- // FIXME: Keep the type prior to promotion?
- return Context.getPointerType(T);
- Diag(Loc, diag::err_template_nontype_parm_bad_type)
- << T;
- return QualType();
- }
- /// ActOnNonTypeTemplateParameter - Called when a C++ non-type
- /// template parameter (e.g., "int Size" in "template<int Size>
- /// class Array") has been parsed. S is the current scope and D is
- /// the parsed declarator.
- Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
- unsigned Depth,
- unsigned Position) {
- QualType T = GetTypeForDeclarator(D, S);
- assert(S->isTemplateParamScope() &&
- "Non-type template parameter not in template parameter scope!");
- bool Invalid = false;
- IdentifierInfo *ParamName = D.getIdentifier();
- if (ParamName) {
- NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
- if (PrevDecl && PrevDecl->isTemplateParameter())
- Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
- PrevDecl);
- }
- T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc());
- if (T.isNull()) {
- T = Context.IntTy; // Recover with an 'int' type.
- Invalid = true;
- }
- NonTypeTemplateParmDecl *Param
- = NonTypeTemplateParmDecl::Create(Context, CurContext, D.getIdentifierLoc(),
- Depth, Position, ParamName, T);
- if (Invalid)
- Param->setInvalidDecl();
- if (D.getIdentifier()) {
- // Add the template parameter into the current scope.
- S->AddDecl(DeclPtrTy::make(Param));
- IdResolver.AddDecl(Param);
- }
- return DeclPtrTy::make(Param);
- }
- /// \brief Adds a default argument to the given non-type template
- /// parameter.
- void Sema::ActOnNonTypeTemplateParameterDefault(DeclPtrTy TemplateParamD,
- SourceLocation EqualLoc,
- ExprArg DefaultE) {
- NonTypeTemplateParmDecl *TemplateParm
- = cast<NonTypeTemplateParmDecl>(TemplateParamD.getAs<Decl>());
- Expr *Default = static_cast<Expr *>(DefaultE.get());
-
- // C++ [temp.param]p14:
- // A template-parameter shall not be used in its own default argument.
- // FIXME: Implement this check! Needs a recursive walk over the types.
-
- // Check the well-formedness of the default template argument.
- TemplateArgument Converted;
- if (CheckTemplateArgument(TemplateParm, TemplateParm->getType(), Default,
- Converted)) {
- TemplateParm->setInvalidDecl();
- return;
- }
- TemplateParm->setDefaultArgument(DefaultE.takeAs<Expr>());
- }
- /// ActOnTemplateTemplateParameter - Called when a C++ template template
- /// parameter (e.g. T in template <template <typename> class T> class array)
- /// has been parsed. S is the current scope.
- Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
- SourceLocation TmpLoc,
- TemplateParamsTy *Params,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- unsigned Depth,
- unsigned Position)
- {
- assert(S->isTemplateParamScope() &&
- "Template template parameter not in template parameter scope!");
- // Construct the parameter object.
- TemplateTemplateParmDecl *Param =
- TemplateTemplateParmDecl::Create(Context, CurContext, TmpLoc, Depth,
- Position, Name,
- (TemplateParameterList*)Params);
- // Make sure the parameter is valid.
- // FIXME: Decl object is not currently invalidated anywhere so this doesn't
- // do anything yet. However, if the template parameter list or (eventual)
- // default value is ever invalidated, that will propagate here.
- bool Invalid = false;
- if (Invalid) {
- Param->setInvalidDecl();
- }
- // If the tt-param has a name, then link the identifier into the scope
- // and lookup mechanisms.
- if (Name) {
- S->AddDecl(DeclPtrTy::make(Param));
- IdResolver.AddDecl(Param);
- }
- return DeclPtrTy::make(Param);
- }
- /// \brief Adds a default argument to the given template template
- /// parameter.
- void Sema::ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParamD,
- SourceLocation EqualLoc,
- ExprArg DefaultE) {
- TemplateTemplateParmDecl *TemplateParm
- = cast<TemplateTemplateParmDecl>(TemplateParamD.getAs<Decl>());
- // Since a template-template parameter's default argument is an
- // id-expression, it must be a DeclRefExpr.
- DeclRefExpr *Default
- = cast<DeclRefExpr>(static_cast<Expr *>(DefaultE.get()));
- // C++ [temp.param]p14:
- // A template-parameter shall not be used in its own default argument.
- // FIXME: Implement this check! Needs a recursive walk over the types.
- // Check the well-formedness of the template argument.
- if (!isa<TemplateDecl>(Default->getDecl())) {
- Diag(Default->getSourceRange().getBegin(),
- diag::err_template_arg_must_be_template)
- << Default->getSourceRange();
- TemplateParm->setInvalidDecl();
- return;
- }
- if (CheckTemplateArgument(TemplateParm, Default)) {
- TemplateParm->setInvalidDecl();
- return;
- }
- DefaultE.release();
- TemplateParm->setDefaultArgument(Default);
- }
- /// ActOnTemplateParameterList - Builds a TemplateParameterList that
- /// contains the template parameters in Params/NumParams.
- Sema::TemplateParamsTy *
- Sema::ActOnTemplateParameterList(unsigned Depth,
- SourceLocation ExportLoc,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- DeclPtrTy *Params, unsigned NumParams,
- SourceLocation RAngleLoc) {
- if (ExportLoc.isValid())
- Diag(ExportLoc, diag::note_template_export_unsupported);
- return TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,
- (Decl**)Params, NumParams, RAngleLoc);
- }
- Sema::DeclResult
- Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
- SourceLocation KWLoc, const CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
- MultiTemplateParamsArg TemplateParameterLists,
- AccessSpecifier AS) {
- assert(TemplateParameterLists.size() > 0 && "No template parameter lists?");
- assert(TK != TK_Reference && "Can only declare or define class templates");
- bool Invalid = false;
- // Check that we can declare a template here.
- if (CheckTemplateDeclScope(S, TemplateParameterLists))
- return true;
- TagDecl::TagKind Kind;
- switch (TagSpec) {
- default: assert(0 && "Unknown tag type!");
- case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
- case DeclSpec::TST_union: Kind = TagDecl::TK_union; break;
- case DeclSpec::TST_class: Kind = TagDecl::TK_class; break;
- }
- // There is no such thing as an unnamed class template.
- if (!Name) {
- Diag(KWLoc, diag::err_template_unnamed_class);
- return true;
- }
- // Find any previous declaration with this name.
- LookupResult Previous = LookupParsedName(S, &SS, Name, LookupOrdinaryName,
- true);
- assert(!Previous.isAmbiguous() && "Ambiguity in class template redecl?");
- NamedDecl *PrevDecl = 0;
- if (Previous.begin() != Previous.end())
- PrevDecl = *Previous.begin();
- DeclContext *SemanticContext = CurContext;
- if (SS.isNotEmpty() && !SS.isInvalid()) {
- SemanticContext = computeDeclContext(SS);
- // FIXME: need to match up several levels of template parameter lists here.
- }
- // FIXME: member templates!
- TemplateParameterList *TemplateParams
- = static_cast<TemplateParameterList *>(*TemplateParameterLists.release());
- // If there is a previous declaration with the same name, check
- // whether this is a valid redeclaration.
- ClassTemplateDecl *PrevClassTemplate
- = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);
- if (PrevClassTemplate) {
- // Ensure that the template parameter lists are compatible.
- if (!TemplateParameterListsAreEqual(TemplateParams,
- PrevClassTemplate->getTemplateParameters(),
- /*Complain=*/true))
- return true;
- // C++ [temp.class]p4:
- // In a redeclaration, partial specialization, explicit
- // specialization or explicit instantiation of a class template,
- // the class-key shall agree in kind with the original class
- // template declaration (7.1.5.3).
- RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl();
- if (!isAcceptableTagRedeclaration(PrevRecordDecl, Kind, KWLoc, *Name)) {
- Diag(KWLoc, diag::err_use_with_wrong_tag)
- << Name
- << CodeModificationHint::CreateReplacement(KWLoc,
- PrevRecordDecl->getKindName());
- Diag(PrevRecordDecl->getLocation(), diag::note_previous_use);
- Kind = PrevRecordDecl->getTagKind();
- }
- // Check for redefinition of this class template.
- if (TK == TK_Definition) {
- if (TagDecl *Def = PrevRecordDecl->getDefinition(Context)) {
- Diag(NameLoc, diag::err_redefinition) << Name;
- Diag(Def->getLocation(), diag::note_previous_definition);
- // FIXME: Would it make sense to try to "forget" the previous
- // definition, as part of error recovery?
- return true;
- }
- }
- } else if (PrevDecl && PrevDecl->isTemplateParameter()) {
- // Maybe we will complain about the shadowed template parameter.
- DiagnoseTemplateParameterShadow(NameLoc, PrevDecl);
- // Just pretend that we didn't see the previous declaration.
- PrevDecl = 0;
- } else if (PrevDecl) {
- // C++ [temp]p5:
- // A class template shall not have the same name as any other
- // template, class, function, object, enumeration, enumerator,
- // namespace, or type in the same scope (3.3), except as specified
- // in (14.5.4).
- Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
- Diag(PrevDecl->getLocation(), diag::note_previous_definition);
- return true;
- }
- // Check the template parameter list of this declaration, possibly
- // merging in the template parameter list from the previous class
- // template declaration.
- if (CheckTemplateParameterList(TemplateParams,
- PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0))
- Invalid = true;
-
- // FIXME: If we had a scope specifier, we better have a previous template
- // declaration!
- CXXRecordDecl *NewClass =
- CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name,
- PrevClassTemplate?
- PrevClassTemplate->getTemplatedDecl() : 0,
- /*DelayTypeCreation=*/true);
- ClassTemplateDecl *NewTemplate
- = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
- DeclarationName(Name), TemplateParams,
- NewClass, PrevClassTemplate);
- NewClass->setDescribedClassTemplate(NewTemplate);
- // Build the type for the class template declaration now.
- QualType T =
- Context.getTypeDeclType(NewClass,
- PrevClassTemplate?
- PrevClassTemplate->getTemplatedDecl() : 0);
- assert(T->isDependentType() && "Class template type is not dependent?");
- (void)T;
- // Set the access specifier.
- SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS);
-
- // Set the lexical context of these templates
- NewClass->setLexicalDeclContext(CurContext);
- NewTemplate->setLexicalDeclContext(CurContext);
- if (TK == TK_Definition)
- NewClass->startDefinition();
- if (Attr)
- ProcessDeclAttributeList(NewClass, Attr);
- PushOnScopeChains(NewTemplate, S);
- if (Invalid) {
- NewTemplate->setInvalidDecl();
- NewClass->setInvalidDecl();
- }
- return DeclPtrTy::make(NewTemplate);
- }
- /// \brief Checks the validity of a template parameter list, possibly
- /// considering the template parameter list from a previous
- /// declaration.
- ///
- /// If an "old" template parameter list is provided, it must be
- /// equivalent (per TemplateParameterListsAreEqual) to the "new"
- /// template parameter list.
- ///
- /// \param NewParams Template parameter list for a new template
- /// declaration. This template parameter list will be updated with any
- /// default arguments that are carried through from the previous
- /// template parameter list.
- ///
- /// \param OldParams If provided, template parameter list from a
- /// previous declaration of the same template. Default template
- /// arguments will be merged from the old template parameter list to
- /// the new template parameter list.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
- TemplateParameterList *OldParams) {
- bool Invalid = false;
-
- // C++ [temp.param]p10:
- // The set of default template-arguments available for use with a
- // template declaration or definition is obtained by merging the
- // default arguments from the definition (if in scope) and all
- // declarations in scope in the same way default function
- // arguments are (8.3.6).
- bool SawDefaultArgument = false;
- SourceLocation PreviousDefaultArgLoc;
- bool SawParameterPack = false;
- SourceLocation ParameterPackLoc;
- // Dummy initialization to avoid warnings.
- TemplateParameterList::iterator OldParam = NewParams->end();
- if (OldParams)
- OldParam = OldParams->begin();
- for (TemplateParameterList::iterator NewParam = NewParams->begin(),
- NewParamEnd = NewParams->end();
- NewParam != NewParamEnd; ++NewParam) {
- // Variables used to diagnose redundant default arguments
- bool RedundantDefaultArg = false;
- SourceLocation OldDefaultLoc;
- SourceLocation NewDefaultLoc;
- // Variables used to diagnose missing default arguments
- bool MissingDefaultArg = false;
- // C++0x [temp.param]p11:
- // If a template parameter of a class template is a template parameter pack,
- // it must be the last template parameter.
- if (SawParameterPack) {
- Diag(ParameterPackLoc,
- diag::err_template_param_pack_must_be_last_template_parameter);
- Invalid = true;
- }
- // Merge default arguments for template type parameters.
- if (TemplateTypeParmDecl *NewTypeParm
- = dyn_cast<TemplateTypeParmDecl>(*NewParam)) {
- TemplateTypeParmDecl *OldTypeParm
- = OldParams? cast<TemplateTypeParmDecl>(*OldParam) : 0;
-
- if (NewTypeParm->isParameterPack()) {
- assert(!NewTypeParm->hasDefaultArgument() &&
- "Parameter packs can't have a default argument!");
- SawParameterPack = true;
- ParameterPackLoc = NewTypeParm->getLocation();
- } else if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
- NewTypeParm->hasDefaultArgument()) {
- OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc();
- NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc();
- SawDefaultArgument = true;
- RedundantDefaultArg = true;
- PreviousDefaultArgLoc = NewDefaultLoc;
- } else if (OldTypeParm && OldTypeParm->hasDefaultArgument()) {
- // Merge the default argument from the old declaration to the
- // new declaration.
- SawDefaultArgument = true;
- NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgument(),
- OldTypeParm->getDefaultArgumentLoc(),
- true);
- PreviousDefaultArgLoc = OldTypeParm->getDefaultArgumentLoc();
- } else if (NewTypeParm->hasDefaultArgument()) {
- SawDefaultArgument = true;
- PreviousDefaultArgLoc = NewTypeParm->getDefaultArgumentLoc();
- } else if (SawDefaultArgument)
- MissingDefaultArg = true;
- }
- // Merge default arguments for non-type template parameters
- else if (NonTypeTemplateParmDecl *NewNonTypeParm
- = dyn_cast<NonTypeTemplateParmDecl>(*NewParam)) {
- NonTypeTemplateParmDecl *OldNonTypeParm
- = OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : 0;
- if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() &&
- NewNonTypeParm->hasDefaultArgument()) {
- OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc();
- NewDefaultLoc = NewNonTypeParm->getDefaultArgumentLoc();
- SawDefaultArgument = true;
- RedundantDefaultArg = true;
- PreviousDefaultArgLoc = NewDefaultLoc;
- } else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument()) {
- // Merge the default argument from the old declaration to the
- // new declaration.
- SawDefaultArgument = true;
- // FIXME: We need to create a new kind of "default argument"
- // expression that points to a previous template template
- // parameter.
- NewNonTypeParm->setDefaultArgument(
- OldNonTypeParm->getDefaultArgument());
- PreviousDefaultArgLoc = OldNonTypeParm->getDefaultArgumentLoc();
- } else if (NewNonTypeParm->hasDefaultArgument()) {
- SawDefaultArgument = true;
- PreviousDefaultArgLoc = NewNonTypeParm->getDefaultArgumentLoc();
- } else if (SawDefaultArgument)
- MissingDefaultArg = true;
- }
- // Merge default arguments for template template parameters
- else {
- TemplateTemplateParmDecl *NewTemplateParm
- = cast<TemplateTemplateParmDecl>(*NewParam);
- TemplateTemplateParmDecl *OldTemplateParm
- = OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : 0;
- if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() &&
- NewTemplateParm->hasDefaultArgument()) {
- OldDefaultLoc = OldTemplateParm->getDefaultArgumentLoc();
- NewDefaultLoc = NewTemplateParm->getDefaultArgumentLoc();
- SawDefaultArgument = true;
- RedundantDefaultArg = true;
- PreviousDefaultArgLoc = NewDefaultLoc;
- } else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument()) {
- // Merge the default argument from the old declaration to the
- // new declaration.
- SawDefaultArgument = true;
- // FIXME: We need to create a new kind of "default argument" expression
- // that points to a previous template template parameter.
- NewTemplateParm->setDefaultArgument(
- OldTemplateParm->getDefaultArgument());
- PreviousDefaultArgLoc = OldTemplateParm->getDefaultArgumentLoc();
- } else if (NewTemplateParm->hasDefaultArgument()) {
- SawDefaultArgument = true;
- PreviousDefaultArgLoc = NewTemplateParm->getDefaultArgumentLoc();
- } else if (SawDefaultArgument)
- MissingDefaultArg = true;
- }
- if (RedundantDefaultArg) {
- // C++ [temp.param]p12:
- // A template-parameter shall not be given default arguments
- // by two different declarations in the same scope.
- Diag(NewDefaultLoc, diag::err_template_param_default_arg_redefinition);
- Diag(OldDefaultLoc, diag::note_template_param_prev_default_arg);
- Invalid = true;
- } else if (MissingDefaultArg) {
- // C++ [temp.param]p11:
- // If a template-parameter has a default template-argument,
- // all subsequent template-parameters shall have a default
- // template-argument supplied.
- Diag((*NewParam)->getLocation(),
- diag::err_template_param_default_arg_missing);
- Diag(PreviousDefaultArgLoc, diag::note_template_param_prev_default_arg);
- Invalid = true;
- }
- // If we have an old template parameter list that we're merging
- // in, move on to the next parameter.
- if (OldParams)
- ++OldParam;
- }
- return Invalid;
- }
- /// \brief Translates template arguments as provided by the parser
- /// into template arguments used by semantic analysis.
- static void
- translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
- llvm::SmallVector<TemplateArgument, 16> &TemplateArgs) {
- TemplateArgs.reserve(TemplateArgsIn.size());
- void **Args = TemplateArgsIn.getArgs();
- bool *ArgIsType = TemplateArgsIn.getArgIsType();
- for (unsigned Arg = 0, Last = TemplateArgsIn.size(); Arg != Last; ++Arg) {
- TemplateArgs.push_back(
- ArgIsType[Arg]? TemplateArgument(TemplateArgLocs[Arg],
- QualType::getFromOpaquePtr(Args[Arg]))
- : TemplateArgument(reinterpret_cast<Expr *>(Args[Arg])));
- }
- }
- /// \brief Build a canonical version of a template argument list.
- ///
- /// This function builds a canonical version of the given template
- /// argument list, where each of the template arguments has been
- /// converted into its canonical form. This routine is typically used
- /// to canonicalize a template argument list when the template name
- /// itself is dependent. When the template name refers to an actual
- /// template declaration, Sema::CheckTemplateArgumentList should be
- /// used to check and canonicalize the template arguments.
- ///
- /// \param TemplateArgs The incoming template arguments.
- ///
- /// \param NumTemplateArgs The number of template arguments in \p
- /// TemplateArgs.
- ///
- /// \param Canonical A vector to be filled with the canonical versions
- /// of the template arguments.
- ///
- /// \param Context The ASTContext in which the template arguments live.
- static void CanonicalizeTemplateArguments(const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- llvm::SmallVectorImpl<TemplateArgument> &Canonical,
- ASTContext &Context) {
- Canonical.reserve(NumTemplateArgs);
- for (unsigned Idx = 0; Idx < NumTemplateArgs; ++Idx) {
- switch (TemplateArgs[Idx].getKind()) {
- case TemplateArgument::Null:
- assert(false && "Should never see a NULL template argument here");
- break;
-
- case TemplateArgument::Expression:
- // FIXME: Build canonical expression (!)
- Canonical.push_back(TemplateArgs[Idx]);
- break;
- case TemplateArgument::Declaration:
- Canonical.push_back(
- TemplateArgument(SourceLocation(),
- Context.getCanonicalDecl(TemplateArgs[Idx].getAsDecl())));
- break;
- case TemplateArgument::Integral:
- Canonical.push_back(TemplateArgument(SourceLocation(),
- *TemplateArgs[Idx].getAsIntegral(),
- TemplateArgs[Idx].getIntegralType()));
- break;
- case TemplateArgument::Type: {
- QualType CanonType
- = Context.getCanonicalType(TemplateArgs[Idx].getAsType());
- Canonical.push_back(TemplateArgument(SourceLocation(), CanonType));
- break;
- }
- }
- }
- }
- QualType Sema::CheckTemplateIdType(TemplateName Name,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc) {
- TemplateDecl *Template = Name.getAsTemplateDecl();
- if (!Template) {
- // The template name does not resolve to a template, so we just
- // build a dependent template-id type.
- // Canonicalize the template arguments to build the canonical
- // template-id type.
- llvm::SmallVector<TemplateArgument, 16> CanonicalTemplateArgs;
- CanonicalizeTemplateArguments(TemplateArgs, NumTemplateArgs,
- CanonicalTemplateArgs, Context);
- TemplateName CanonName = Context.getCanonicalTemplateName(Name);
- QualType CanonType
- = Context.getTemplateSpecializationType(CanonName,
- &CanonicalTemplateArgs[0],
- CanonicalTemplateArgs.size());
- // Build the dependent template-id type.
- return Context.getTemplateSpecializationType(Name, TemplateArgs,
- NumTemplateArgs, CanonType);
- }
- // Check that the template argument list is well-formed for this
- // template.
- TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
- if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
- TemplateArgs, NumTemplateArgs, RAngleLoc,
- ConvertedTemplateArgs))
- return QualType();
- assert((ConvertedTemplateArgs.size() ==
- Template->getTemplateParameters()->size()) &&
- "Converted template argument list is too short!");
- QualType CanonType;
- if (TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs,
- NumTemplateArgs)) {
- // This class template specialization is a dependent
- // type. Therefore, its canonical type is another class template
- // specialization type that contains all of the converted
- // arguments in canonical form. This ensures that, e.g., A<T> and
- // A<T, T> have identical types when A is declared as:
- //
- // template<typename T, typename U = T> struct A;
- TemplateName CanonName = Context.getCanonicalTemplateName(Name);
- CanonType = Context.getTemplateSpecializationType(CanonName,
- ConvertedTemplateArgs.getFlatArgumentList(),
- ConvertedTemplateArgs.flatSize());
- } else if (ClassTemplateDecl *ClassTemplate
- = dyn_cast<ClassTemplateDecl>(Template)) {
- // Find the class template specialization declaration that
- // corresponds to these arguments.
- llvm::FoldingSetNodeID ID;
- ClassTemplateSpecializationDecl::Profile(ID,
- ConvertedTemplateArgs.getFlatArgumentList(),
- ConvertedTemplateArgs.flatSize());
- void *InsertPos = 0;
- ClassTemplateSpecializationDecl *Decl
- = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
- if (!Decl) {
- // This is the first time we have referenced this class template
- // specialization. Create the canonical declaration and add it to
- // the set of specializations.
- Decl = ClassTemplateSpecializationDecl::Create(Context,
- ClassTemplate->getDeclContext(),
- TemplateLoc,
- ClassTemplate,
- ConvertedTemplateArgs, 0);
- ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos);
- Decl->setLexicalDeclContext(CurContext);
- }
- CanonType = Context.getTypeDeclType(Decl);
- }
-
- // Build the fully-sugared type for this class template
- // specialization, which refers back to the class template
- // specialization we created or found.
- return Context.getTemplateSpecializationType(Name, TemplateArgs,
- NumTemplateArgs, CanonType);
- }
- Action::TypeResult
- Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc) {
- TemplateName Template = TemplateD.getAsVal<TemplateName>();
- // Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
- translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
- QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
- TemplateArgs.data(),
- TemplateArgs.size(),
- RAngleLoc);
- TemplateArgsIn.release();
- if (Result.isNull())
- return true;
- return Result.getAsOpaquePtr();
- }
- /// \brief Form a dependent template name.
- ///
- /// This action forms a dependent template name given the template
- /// name and its (presumably dependent) scope specifier. For
- /// example, given "MetaFun::template apply", the scope specifier \p
- /// SS will be "MetaFun::", \p TemplateKWLoc contains the location
- /// of the "template" keyword, and "apply" is the \p Name.
- Sema::TemplateTy
- Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
- const IdentifierInfo &Name,
- SourceLocation NameLoc,
- const CXXScopeSpec &SS) {
- if (!SS.isSet() || SS.isInvalid())
- return TemplateTy();
- NestedNameSpecifier *Qualifier
- = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
- // FIXME: member of the current instantiation
- if (!Qualifier->isDependent()) {
- // C++0x [temp.names]p5:
- // If a name prefixed by the keyword template is not the name of
- // a template, the program is ill-formed. [Note: the keyword
- // template may not be applied to non-template members of class
- // templates. -end note ] [ Note: as is the case with the
- // typename prefix, the template prefix is allowed in cases
- // where it is not strictly necessary; i.e., when the
- // nested-name-specifier or the expression on the left of the ->
- // or . is not dependent on a template-parameter, or the use
- // does not appear in the scope of a template. -end note]
- //
- // Note: C++03 was more strict here, because it banned the use of
- // the "template" keyword prior to a template-name that was not a
- // dependent name. C++ DR468 relaxed this requirement (the
- // "template" keyword is now permitted). We follow the C++0x
- // rules, even in C++03 mode, retroactively applying the DR.
- TemplateTy Template;
- TemplateNameKind TNK = isTemplateName(Name, 0, Template, &SS);
- if (TNK == TNK_Non_template) {
- Diag(NameLoc, diag::err_template_kw_refers_to_non_template)
- << &Name;
- return TemplateTy();
- }
- return Template;
- }
- return TemplateTy::make(Context.getDependentTemplateName(Qualifier, &Name));
- }
- bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
- const TemplateArgument &Arg,
- TemplateArgumentListBuilder &Converted) {
- // Check template type parameter.
- if (Arg.getKind() != TemplateArgument::Type) {
- // C++ [temp.arg.type]p1:
- // A template-argument for a template-parameter which is a
- // type shall be a type-id.
- // We have a template type parameter but the template argument
- // is not a type.
- Diag(Arg.getLocation(), diag::err_template_arg_must_be_type);
- Diag(Param->getLocation(), diag::note_template_param_here);
-
- return true;
- }
- if (CheckTemplateArgument(Param, Arg.getAsType(), Arg.getLocation()))
- return true;
-
- // Add the converted template type argument.
- Converted.push_back(
- TemplateArgument(Arg.getLocation(),
- Context.getCanonicalType(Arg.getAsType())));
- return false;
- }
- /// \brief Check that the given template argument list is well-formed
- /// for specializing the given template.
- bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc,
- TemplateArgumentListBuilder &Converted) {
- TemplateParameterList *Params = Template->getTemplateParameters();
- unsigned NumParams = Params->size();
- unsigned NumArgs = NumTemplateArgs;
- bool Invalid = false;
- bool HasParameterPack =
- NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack();
-
- if ((NumArgs > NumParams && !HasParameterPack) ||
- NumArgs < Params->getMinRequiredArguments()) {
- // FIXME: point at either the first arg beyond what we can handle,
- // or the '>', depending on whether we have too many or too few
- // arguments.
- SourceRange Range;
- if (NumArgs > NumParams)
- Range = SourceRange(TemplateArgs[NumParams].getLocation(), RAngleLoc);
- Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
- << (NumArgs > NumParams)
- << (isa<ClassTemplateDecl>(Template)? 0 :
- isa<FunctionTemplateDecl>(Template)? 1 :
- isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
- << Template << Range;
- Diag(Template->getLocation(), diag::note_template_decl_here)
- << Params->getSourceRange();
- Invalid = true;
- }
-
- // C++ [temp.arg]p1:
- // [...] The type and form of each template-argument specified in
- // a template-id shall match the type and form specified for the
- // corresponding parameter declared by the template in its
- // template-parameter-list.
- unsigned ArgIdx = 0;
- for (TemplateParameterList::iterator Param = Params->begin(),
- ParamEnd = Params->end();
- Param != ParamEnd; ++Param, ++ArgIdx) {
- // Decode the template argument
- TemplateArgument Arg;
- if (ArgIdx >= NumArgs) {
- // Retrieve the default template argument from the template
- // parameter.
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
- if (TTP->isParameterPack()) {
- // We have an empty parameter pack.
- Converted.BeginParameterPack();
- Converted.EndParameterPack();
- break;
- }
-
- if (!TTP->hasDefaultArgument())
- break;
- QualType ArgType = TTP->getDefaultArgument();
- // If the argument type is dependent, instantiate it now based
- // on the previously-computed template arguments.
- if (ArgType->isDependentType()) {
- InstantiatingTemplate Inst(*this, TemplateLoc,
- Template, Converted.getFlatArgumentList(),
- Converted.flatSize(),
- SourceRange(TemplateLoc, RAngleLoc));
- TemplateArgumentList TemplateArgs(Context, Converted,
- /*CopyArgs=*/false,
- /*FlattenArgs=*/false);
- ArgType = InstantiateType(ArgType, TemplateArgs,
- TTP->getDefaultArgumentLoc(),
- TTP->getDeclName());
- }
- if (ArgType.isNull())
- return true;
- Arg = TemplateArgument(TTP->getLocation(), ArgType);
- } else if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
- if (!NTTP->hasDefaultArgument())
- break;
- InstantiatingTemplate Inst(*this, TemplateLoc,
- Template, Converted.getFlatArgumentList(),
- Converted.flatSize(),
- SourceRange(TemplateLoc, RAngleLoc));
-
- TemplateArgumentList TemplateArgs(Context, Converted,
- /*CopyArgs=*/false,
- /*FlattenArgs=*/false);
- Sema::OwningExprResult E = InstantiateExpr(NTTP->getDefaultArgument(),
- TemplateArgs);
- if (E.isInvalid())
- return true;
-
- Arg = TemplateArgument(E.takeAs<Expr>());
- } else {
- TemplateTemplateParmDecl *TempParm
- = cast<TemplateTemplateParmDecl>(*Param);
- if (!TempParm->hasDefaultArgument())
- break;
- // FIXME: Instantiate default argument
- Arg = TemplateArgument(TempParm->getDefaultArgument());
- }
- } else {
- // Retrieve the template argument produced by the user.
- Arg = TemplateArgs[ArgIdx];
- }
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
- if (TTP->isParameterPack()) {
- Converted.BeginParameterPack();
- // Check all the remaining arguments (if any).
- for (; ArgIdx < NumArgs; ++ArgIdx) {
- if (CheckTemplateTypeArgument(TTP, TemplateArgs[ArgIdx], Converted))
- Invalid = true;
- }
-
- Converted.EndParameterPack();
- } else {
- if (CheckTemplateTypeArgument(TTP, Arg, Converted))
- Invalid = true;
- }
- } else if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
- // Check non-type template parameters.
- // Instantiate the type of the non-type template parameter with
- // the template arguments we've seen thus far.
- QualType NTTPType = NTTP->getType();
- if (NTTPType->isDependentType()) {
- // Instantiate the type of the non-type template parameter.
- InstantiatingTemplate Inst(*this, TemplateLoc,
- Template, Converted.getFlatArgumentList(),
- Converted.flatSize(),
- SourceRange(TemplateLoc, RAngleLoc));
- TemplateArgumentList TemplateArgs(Context, Converted,
- /*CopyArgs=*/false,
- /*FlattenArgs=*/false);
- NTTPType = InstantiateType(NTTPType, TemplateArgs,
- NTTP->getLocation(),
- NTTP->getDeclName());
- // If that worked, check the non-type template parameter type
- // for validity.
- if (!NTTPType.isNull())
- NTTPType = CheckNonTypeTemplateParameterType(NTTPType,
- NTTP->getLocation());
- if (NTTPType.isNull()) {
- Invalid = true;
- break;
- }
- }
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- assert(false && "Should never see a NULL template argument here");
- break;
-
- case TemplateArgument::Expression: {
- Expr *E = Arg.getAsExpr();
- TemplateArgument Result;
- if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
- Invalid = true;
- else
- Converted.push_back(Result);
- break;
- }
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- // We've already checked this template argument, so just copy
- // it to the list of converted arguments.
- Converted.push_back(Arg);
- break;
- case TemplateArgument::Type:
- // We have a non-type template parameter but the template
- // argument is a type.
-
- // C++ [temp.arg]p2:
- // In a template-argument, an ambiguity between a type-id and
- // an expression is resolved to a type-id, regardless of the
- // form of the corresponding template-parameter.
- //
- // We warn specifically about this case, since it can be rather
- // confusing for users.
- if (Arg.getAsType()->isFunctionType())
- Diag(Arg.getLocation(), diag::err_template_arg_nontype_ambig)
- << Arg.getAsType();
- else
- Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr);
- Diag((*Param)->getLocation(), diag::note_template_param_here);
- Invalid = true;
- }
- } else {
- // Check template template parameters.
- TemplateTemplateParmDecl *TempParm
- = cast<TemplateTemplateParmDecl>(*Param);
-
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- assert(false && "Should never see a NULL template argument here");
- break;
-
- case TemplateArgument::Expression: {
- Expr *ArgExpr = Arg.getAsExpr();
- if (ArgExpr && isa<DeclRefExpr>(ArgExpr) &&
- isa<TemplateDecl>(cast<DeclRefExpr>(ArgExpr)->getDecl())) {
- if (CheckTemplateArgument(TempParm, cast<DeclRefExpr>(ArgExpr)))
- Invalid = true;
-
- // Add the converted template argument.
- Decl *D
- = Context.getCanonicalDecl(cast<DeclRefExpr>(ArgExpr)->getDecl());
- Converted.push_back(TemplateArgument(Arg.getLocation(), D));
- continue;
- }
- }
- // fall through
-
- case TemplateArgument::Type: {
- // We have a template template parameter but the template
- // argument does not refer to a template.
- Diag(Arg.getLocation(), diag::err_template_arg_must_be_template);
- Invalid = true;
- break;
- }
- case TemplateArgument::Declaration:
- // We've already checked this template argument, so just copy
- // it to the list of converted arguments.
- Converted.push_back(Arg);
- break;
-
- case TemplateArgument::Integral:
- assert(false && "Integral argument with template template parameter");
- break;
- }
- }
- }
- return Invalid;
- }
- /// \brief Check a template argument against its corresponding
- /// template type parameter.
- ///
- /// This routine implements the semantics of C++ [temp.arg.type]. It
- /// returns true if an error occurred, and false otherwise.
- bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
- QualType Arg, SourceLocation ArgLoc) {
- // C++ [temp.arg.type]p2:
- // A local type, a type with no linkage, an unnamed type or a type
- // compounded from any of these types shall not be used as a
- // template-argument for a template type-parameter.
- //
- // FIXME: Perform the recursive and no-linkage type checks.
- const TagType *Tag = 0;
- if (const EnumType *EnumT = Arg->getAsEnumType())
- Tag = EnumT;
- else if (const RecordType *RecordT = Arg->getAsRecordType())
- Tag = RecordT;
- if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod())
- return Diag(ArgLoc, diag::err_template_arg_local_type)
- << QualType(Tag, 0);
- else if (Tag && !Tag->getDecl()->getDeclName() &&
- !Tag->getDecl()->getTypedefForAnonDecl()) {
- Diag(ArgLoc, diag::err_template_arg_unnamed_type);
- Diag(Tag->getDecl()->getLocation(), diag::note_template_unnamed_type_here);
- return true;
- }
- return false;
- }
- /// \brief Checks whether the given template argument is the address
- /// of an object or function according to C++ [temp.arg.nontype]p1.
- bool Sema::CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
- NamedDecl *&Entity) {
- bool Invalid = false;
- // See through any implicit casts we added to fix the type.
- if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
- Arg = Cast->getSubExpr();
- // C++0x allows nullptr, and there's no further checking to be done for that.
- if (Arg->getType()->isNullPtrType())
- return false;
- // C++ [temp.arg.nontype]p1:
- //
- // A template-argument for a non-type, non-template
- // template-parameter shall be one of: [...]
- //
- // -- the address of an object or function with external
- // linkage, including function templates and function
- // template-ids but excluding non-static class members,
- // expressed as & id-expression where the & is optional if
- // the name refers to a function or array, or if the
- // corresponding template-parameter is a reference; or
- DeclRefExpr *DRE = 0;
-
- // Ignore (and complain about) any excess parentheses.
- while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
- if (!Invalid) {
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_extra_parens)
- << Arg->getSourceRange();
- Invalid = true;
- }
- Arg = Parens->getSubExpr();
- }
- if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
- if (UnOp->getOpcode() == UnaryOperator::AddrOf)
- DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
- } else
- DRE = dyn_cast<DeclRefExpr>(Arg);
- if (!DRE || !isa<ValueDecl>(DRE->getDecl()))
- return Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_object_or_func_form)
- << Arg->getSourceRange();
- // Cannot refer to non-static data members
- if (FieldDecl *Field = dyn_cast<FieldDecl>(DRE->getDecl()))
- return Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_field)
- << Field << Arg->getSourceRange();
- // Cannot refer to non-static member functions
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(DRE->getDecl()))
- if (!Method->isStatic())
- return Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_method)
- << Method << Arg->getSourceRange();
-
- // Functions must have external linkage.
- if (FunctionDecl *Func = dyn_cast<FunctionDecl>(DRE->getDecl())) {
- if (Func->getStorageClass() == FunctionDecl::Static) {
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_function_not_extern)
- << Func << Arg->getSourceRange();
- Diag(Func->getLocation(), diag::note_template_arg_internal_object)
- << true;
- return true;
- }
- // Okay: we've named a function with external linkage.
- Entity = Func;
- return Invalid;
- }
- if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
- if (!Var->hasGlobalStorage()) {
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_object_not_extern)
- << Var << Arg->getSourceRange();
- Diag(Var->getLocation(), diag::note_template_arg_internal_object)
- << true;
- return true;
- }
- // Okay: we've named an object with external linkage
- Entity = Var;
- return Invalid;
- }
-
- // We found something else, but we don't know specifically what it is.
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_object_or_func)
- << Arg->getSourceRange();
- Diag(DRE->getDecl()->getLocation(),
- diag::note_template_arg_refers_here);
- return true;
- }
- /// \brief Checks whether the given template argument is a pointer to
- /// member constant according to C++ [temp.arg.nontype]p1.
- bool
- Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member) {
- bool Invalid = false;
- // See through any implicit casts we added to fix the type.
- if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
- Arg = Cast->getSubExpr();
- // C++0x allows nullptr, and there's no further checking to be done for that.
- if (Arg->getType()->isNullPtrType())
- return false;
- // C++ [temp.arg.nontype]p1:
- //
- // A template-argument for a non-type, non-template
- // template-parameter shall be one of: [...]
- //
- // -- a pointer to member expressed as described in 5.3.1.
- QualifiedDeclRefExpr *DRE = 0;
- // Ignore (and complain about) any excess parentheses.
- while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
- if (!Invalid) {
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_extra_parens)
- << Arg->getSourceRange();
- Invalid = true;
- }
- Arg = Parens->getSubExpr();
- }
- if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg))
- if (UnOp->getOpcode() == UnaryOperator::AddrOf)
- DRE = dyn_cast<QualifiedDeclRefExpr>(UnOp->getSubExpr());
- if (!DRE)
- return Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_pointer_to_member_form)
- << Arg->getSourceRange();
- if (isa<FieldDecl>(DRE->getDecl()) || isa<CXXMethodDecl>(DRE->getDecl())) {
- assert((isa<FieldDecl>(DRE->getDecl()) ||
- !cast<CXXMethodDecl>(DRE->getDecl())->isStatic()) &&
- "Only non-static member pointers can make it here");
- // Okay: this is the address of a non-static member, and therefore
- // a member pointer constant.
- Member = DRE->getDecl();
- return Invalid;
- }
- // We found something else, but we don't know specifically what it is.
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_pointer_to_member_form)
- << Arg->getSourceRange();
- Diag(DRE->getDecl()->getLocation(),
- diag::note_template_arg_refers_here);
- return true;
- }
- /// \brief Check a template argument against its corresponding
- /// non-type template parameter.
- ///
- /// This routine implements the semantics of C++ [temp.arg.nontype].
- /// It returns true if an error occurred, and false otherwise. \p
- /// InstantiatedParamType is the type of the non-type template
- /// parameter after it has been instantiated.
- ///
- /// If no error was detected, Converted receives the converted template argument.
- bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
- QualType InstantiatedParamType, Expr *&Arg,
- TemplateArgument &Converted) {
- SourceLocation StartLoc = Arg->getSourceRange().getBegin();
- // If either the parameter has a dependent type or the argument is
- // type-dependent, there's nothing we can check now.
- // FIXME: Add template argument to Converted!
- if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) {
- // FIXME: Produce a cloned, canonical expression?
- Converted = TemplateArgument(Arg);
- return false;
- }
- // C++ [temp.arg.nontype]p5:
- // The following conversions are performed on each expression used
- // as a non-type template-argument. If a non-type
- // template-argument cannot be converted to the type of the
- // corresponding template-parameter then the program is
- // ill-formed.
- //
- // -- for a non-type template-parameter of integral or
- // enumeration type, integral promotions (4.5) and integral
- // conversions (4.7) are applied.
- QualType ParamType = InstantiatedParamType;
- QualType ArgType = Arg->getType();
- if (ParamType->isIntegralType() || ParamType->isEnumeralType()) {
- // C++ [temp.arg.nontype]p1:
- // A template-argument for a non-type, non-template
- // template-parameter shall be one of:
- //
- // -- an integral constant-expression of integral or enumeration
- // type; or
- // -- the name of a non-type template-parameter; or
- SourceLocation NonConstantLoc;
- llvm::APSInt Value;
- if (!ArgType->isIntegralType() && !ArgType->isEnumeralType()) {
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_integral_or_enumeral)
- << ArgType << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- } else if (!Arg->isValueDependent() &&
- !Arg->isIntegerConstantExpr(Value, Context, &NonConstantLoc)) {
- Diag(NonConstantLoc, diag::err_template_arg_not_ice)
- << ArgType << Arg->getSourceRange();
- return true;
- }
- // FIXME: We need some way to more easily get the unqualified form
- // of the types without going all the way to the
- // canonical type.
- if (Context.getCanonicalType(ParamType).getCVRQualifiers())
- ParamType = Context.getCanonicalType(ParamType).getUnqualifiedType();
- if (Context.getCanonicalType(ArgType).getCVRQualifiers())
- ArgType = Context.getCanonicalType(ArgType).getUnqualifiedType();
- // Try to convert the argument to the parameter's type.
- if (ParamType == ArgType) {
- // Okay: no conversion necessary
- } else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
- !ParamType->isEnumeralType()) {
- // This is an integral promotion or conversion.
- ImpCastExprToType(Arg, ParamType);
- } else {
- // We can't perform this conversion.
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_convertible)
- << Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
- QualType IntegerType = Context.getCanonicalType(ParamType);
- if (const EnumType *Enum = IntegerType->getAsEnumType())
- IntegerType = Context.getCanonicalType(Enum->getDecl()->getIntegerType());
- if (!Arg->isValueDependent()) {
- // Check that an unsigned parameter does not receive a negative
- // value.
- if (IntegerType->isUnsignedIntegerType()
- && (Value.isSigned() && Value.isNegative())) {
- Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_negative)
- << Value.toString(10) << Param->getType()
- << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
- // Check that we don't overflow the template parameter type.
- unsigned AllowedBits = Context.getTypeSize(IntegerType);
- if (Value.getActiveBits() > AllowedBits) {
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_too_large)
- << Value.toString(10) << Param->getType()
- << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
- if (Value.getBitWidth() != AllowedBits)
- Value.extOrTrunc(AllowedBits);
- Value.setIsSigned(IntegerType->isSignedIntegerType());
- }
- // Add the value of this argument to the list of converted
- // arguments. We use the bitwidth and signedness of the template
- // parameter.
- if (Arg->isValueDependent()) {
- // The argument is value-dependent. Create a new
- // TemplateArgument with the converted expression.
- Converted = TemplateArgument(Arg);
- return false;
- }
- Converted = TemplateArgument(StartLoc, Value,
- ParamType->isEnumeralType() ? ParamType
- : IntegerType);
- return false;
- }
- // Handle pointer-to-function, reference-to-function, and
- // pointer-to-member-function all in (roughly) the same way.
- if (// -- For a non-type template-parameter of type pointer to
- // function, only the function-to-pointer conversion (4.3) is
- // applied. If the template-argument represents a set of
- // overloaded functions (or a pointer to such), the matching
- // function is selected from the set (13.4).
- // In C++0x, any std::nullptr_t value can be converted.
- (ParamType->isPointerType() &&
- ParamType->getAsPointerType()->getPointeeType()->isFunctionType()) ||
- // -- For a non-type template-parameter of type reference to
- // function, no conversions apply. If the template-argument
- // represents a set of overloaded functions, the matching
- // function is selected from the set (13.4).
- (ParamType->isReferenceType() &&
- ParamType->getAsReferenceType()->getPointeeType()->isFunctionType()) ||
- // -- For a non-type template-parameter of type pointer to
- // member function, no conversions apply. If the
- // template-argument represents a set of overloaded member
- // functions, the matching member function is selected from
- // the set (13.4).
- // Again, C++0x allows a std::nullptr_t value.
- (ParamType->isMemberPointerType() &&
- ParamType->getAsMemberPointerType()->getPointeeType()
- ->isFunctionType())) {
- if (Context.hasSameUnqualifiedType(ArgType,
- ParamType.getNonReferenceType())) {
- // We don't have to do anything: the types already match.
- } else if (ArgType->isNullPtrType() && (ParamType->isPointerType() ||
- ParamType->isMemberPointerType())) {
- ArgType = ParamType;
- ImpCastExprToType(Arg, ParamType);
- } else if (ArgType->isFunctionType() && ParamType->isPointerType()) {
- ArgType = Context.getPointerType(ArgType);
- ImpCastExprToType(Arg, ArgType);
- } else if (FunctionDecl *Fn
- = ResolveAddressOfOverloadedFunction(Arg, ParamType, true)) {
- if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
- return true;
- FixOverloadedFunctionReference(Arg, Fn);
- ArgType = Arg->getType();
- if (ArgType->isFunctionType() && ParamType->isPointerType()) {
- ArgType = Context.getPointerType(Arg->getType());
- ImpCastExprToType(Arg, ArgType);
- }
- }
- if (!Context.hasSameUnqualifiedType(ArgType,
- ParamType.getNonReferenceType())) {
- // We can't perform this conversion.
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_convertible)
- << Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
-
- if (ParamType->isMemberPointerType()) {
- NamedDecl *Member = 0;
- if (CheckTemplateArgumentPointerToMember(Arg, Member))
- return true;
- Member = cast_or_null<NamedDecl>(Context.getCanonicalDecl(Member));
- Converted = TemplateArgument(StartLoc, Member);
- return false;
- }
-
- NamedDecl *Entity = 0;
- if (CheckTemplateArgumentAddressOfObjectOrFunction(Arg, Entity))
- return true;
- Entity = cast_or_null<NamedDecl>(Context.getCanonicalDecl(Entity));
- Converted = TemplateArgument(StartLoc, Entity);
- return false;
- }
- if (ParamType->isPointerType()) {
- // -- for a non-type template-parameter of type pointer to
- // object, qualification conversions (4.4) and the
- // array-to-pointer conversion (4.2) are applied.
- // C++0x also allows a value of std::nullptr_t.
- assert(ParamType->getAsPointerType()->getPointeeType()->isObjectType() &&
- "Only object pointers allowed here");
- if (ArgType->isNullPtrType()) {
- ArgType = ParamType;
- ImpCastExprToType(Arg, ParamType);
- } else if (ArgType->isArrayType()) {
- ArgType = Context.getArrayDecayedType(ArgType);
- ImpCastExprToType(Arg, ArgType);
- }
- if (IsQualificationConversion(ArgType, ParamType)) {
- ArgType = ParamType;
- ImpCastExprToType(Arg, ParamType);
- }
-
- if (!Context.hasSameUnqualifiedType(ArgType, ParamType)) {
- // We can't perform this conversion.
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_convertible)
- << Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
-
- NamedDecl *Entity = 0;
- if (CheckTemplateArgumentAddressOfObjectOrFunction(Arg, Entity))
- return true;
- Entity = cast_or_null<NamedDecl>(Context.getCanonicalDecl(Entity));
- Converted = TemplateArgument(StartLoc, Entity);
- return false;
- }
-
- if (const ReferenceType *ParamRefType = ParamType->getAsReferenceType()) {
- // -- For a non-type template-parameter of type reference to
- // object, no conversions apply. The type referred to by the
- // reference may be more cv-qualified than the (otherwise
- // identical) type of the template-argument. The
- // template-parameter is bound directly to the
- // template-argument, which must be an lvalue.
- assert(ParamRefType->getPointeeType()->isObjectType() &&
- "Only object references allowed here");
- if (!Context.hasSameUnqualifiedType(ParamRefType->getPointeeType(), ArgType)) {
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_no_ref_bind)
- << InstantiatedParamType << Arg->getType()
- << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
- unsigned ParamQuals
- = Context.getCanonicalType(ParamType).getCVRQualifiers();
- unsigned ArgQuals = Context.getCanonicalType(ArgType).getCVRQualifiers();
-
- if ((ParamQuals | ArgQuals) != ParamQuals) {
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_ref_bind_ignores_quals)
- << InstantiatedParamType << Arg->getType()
- << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
-
- NamedDecl *Entity = 0;
- if (CheckTemplateArgumentAddressOfObjectOrFunction(Arg, Entity))
- return true;
- Entity = cast<NamedDecl>(Context.getCanonicalDecl(Entity));
- Converted = TemplateArgument(StartLoc, Entity);
- return false;
- }
- // -- For a non-type template-parameter of type pointer to data
- // member, qualification conversions (4.4) are applied.
- // C++0x allows std::nullptr_t values.
- assert(ParamType->isMemberPointerType() && "Only pointers to members remain");
- if (Context.hasSameUnqualifiedType(ParamType, ArgType)) {
- // Types match exactly: nothing more to do here.
- } else if (ArgType->isNullPtrType()) {
- ImpCastExprToType(Arg, ParamType);
- } else if (IsQualificationConversion(ArgType, ParamType)) {
- ImpCastExprToType(Arg, ParamType);
- } else {
- // We can't perform this conversion.
- Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_not_convertible)
- << Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
- NamedDecl *Member = 0;
- if (CheckTemplateArgumentPointerToMember(Arg, Member))
- return true;
-
- Member = cast_or_null<NamedDecl>(Context.getCanonicalDecl(Member));
- Converted = TemplateArgument(StartLoc, Member);
- return false;
- }
- /// \brief Check a template argument against its corresponding
- /// template template parameter.
- ///
- /// This routine implements the semantics of C++ [temp.arg.template].
- /// It returns true if an error occurred, and false otherwise.
- bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
- DeclRefExpr *Arg) {
- assert(isa<TemplateDecl>(Arg->getDecl()) && "Only template decls allowed");
- TemplateDecl *Template = cast<TemplateDecl>(Arg->getDecl());
- // C++ [temp.arg.template]p1:
- // A template-argument for a template template-parameter shall be
- // the name of a class template, expressed as id-expression. Only
- // primary class templates are considered when matching the
- // template template argument with the corresponding parameter;
- // partial specializations are not considered even if their
- // parameter lists match that of the template template parameter.
- //
- // Note that we also allow template template parameters here, which
- // will happen when we are dealing with, e.g., class template
- // partial specializations.
- if (!isa<ClassTemplateDecl>(Template) &&
- !isa<TemplateTemplateParmDecl>(Template)) {
- assert(isa<FunctionTemplateDecl>(Template) &&
- "Only function templates are possible here");
- Diag(Arg->getSourceRange().getBegin(),
- diag::note_template_arg_refers_here_func)
- << Template;
- }
- return !TemplateParameterListsAreEqual(Template->getTemplateParameters(),
- Param->getTemplateParameters(),
- true, true,
- Arg->getSourceRange().getBegin());
- }
- /// \brief Determine whether the given template parameter lists are
- /// equivalent.
- ///
- /// \param New The new template parameter list, typically written in the
- /// source code as part of a new template declaration.
- ///
- /// \param Old The old template parameter list, typically found via
- /// name lookup of the template declared with this template parameter
- /// list.
- ///
- /// \param Complain If true, this routine will produce a diagnostic if
- /// the template parameter lists are not equivalent.
- ///
- /// \param IsTemplateTemplateParm If true, this routine is being
- /// called to compare the template parameter lists of a template
- /// template parameter.
- ///
- /// \param TemplateArgLoc If this source location is valid, then we
- /// are actually checking the template parameter list of a template
- /// argument (New) against the template parameter list of its
- /// corresponding template template parameter (Old). We produce
- /// slightly different diagnostics in this scenario.
- ///
- /// \returns True if the template parameter lists are equal, false
- /// otherwise.
- bool
- Sema::TemplateParameterListsAreEqual(TemplateParameterList *New,
- TemplateParameterList *Old,
- bool Complain,
- bool IsTemplateTemplateParm,
- SourceLocation TemplateArgLoc) {
- if (Old->size() != New->size()) {
- if (Complain) {
- unsigned NextDiag = diag::err_template_param_list_different_arity;
- if (TemplateArgLoc.isValid()) {
- Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
- NextDiag = diag::note_template_param_list_different_arity;
- }
- Diag(New->getTemplateLoc(), NextDiag)
- << (New->size() > Old->size())
- << IsTemplateTemplateParm
- << SourceRange(New->getTemplateLoc(), New->getRAngleLoc());
- Diag(Old->getTemplateLoc(), diag::note_template_prev_declaration)
- << IsTemplateTemplateParm
- << SourceRange(Old->getTemplateLoc(), Old->getRAngleLoc());
- }
- return false;
- }
- for (TemplateParameterList::iterator OldParm = Old->begin(),
- OldParmEnd = Old->end(), NewParm = New->begin();
- OldParm != OldParmEnd; ++OldParm, ++NewParm) {
- if ((*OldParm)->getKind() != (*NewParm)->getKind()) {
- unsigned NextDiag = diag::err_template_param_different_kind;
- if (TemplateArgLoc.isValid()) {
- Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
- NextDiag = diag::note_template_param_different_kind;
- }
- Diag((*NewParm)->getLocation(), NextDiag)
- << IsTemplateTemplateParm;
- Diag((*OldParm)->getLocation(), diag::note_template_prev_declaration)
- << IsTemplateTemplateParm;
- return false;
- }
- if (isa<TemplateTypeParmDecl>(*OldParm)) {
- // Okay; all template type parameters are equivalent (since we
- // know we're at the same index).
- #if 0
- // FIXME: Enable this code in debug mode *after* we properly go through
- // and "instantiate" the template parameter lists of template template
- // parameters. It's only after this instantiation that (1) any dependent
- // types within the template parameter list of the template template
- // parameter can be checked, and (2) the template type parameter depths
- // will match up.
- QualType OldParmType
- = Context.getTypeDeclType(cast<TemplateTypeParmDecl>(*OldParm));
- QualType NewParmType
- = Context.getTypeDeclType(cast<TemplateTypeParmDecl>(*NewParm));
- assert(Context.getCanonicalType(OldParmType) ==
- Context.getCanonicalType(NewParmType) &&
- "type parameter mismatch?");
- #endif
- } else if (NonTypeTemplateParmDecl *OldNTTP
- = dyn_cast<NonTypeTemplateParmDecl>(*OldParm)) {
- // The types of non-type template parameters must agree.
- NonTypeTemplateParmDecl *NewNTTP
- = cast<NonTypeTemplateParmDecl>(*NewParm);
- if (Context.getCanonicalType(OldNTTP->getType()) !=
- Context.getCanonicalType(NewNTTP->getType())) {
- if (Complain) {
- unsigned NextDiag = diag::err_template_nontype_parm_different_type;
- if (TemplateArgLoc.isValid()) {
- Diag(TemplateArgLoc,
- diag::err_template_arg_template_params_mismatch);
- NextDiag = diag::note_template_nontype_parm_different_type;
- }
- Diag(NewNTTP->getLocation(), NextDiag)
- << NewNTTP->getType()
- << IsTemplateTemplateParm;
- Diag(OldNTTP->getLocation(),
- diag::note_template_nontype_parm_prev_declaration)
- << OldNTTP->getType();
- }
- return false;
- }
- } else {
- // The template parameter lists of template template
- // parameters must agree.
- // FIXME: Could we perform a faster "type" comparison here?
- assert(isa<TemplateTemplateParmDecl>(*OldParm) &&
- "Only template template parameters handled here");
- TemplateTemplateParmDecl *OldTTP
- = cast<TemplateTemplateParmDecl>(*OldParm);
- TemplateTemplateParmDecl *NewTTP
- = cast<TemplateTemplateParmDecl>(*NewParm);
- if (!TemplateParameterListsAreEqual(NewTTP->getTemplateParameters(),
- OldTTP->getTemplateParameters(),
- Complain,
- /*IsTemplateTemplateParm=*/true,
- TemplateArgLoc))
- return false;
- }
- }
- return true;
- }
- /// \brief Check whether a template can be declared within this scope.
- ///
- /// If the template declaration is valid in this scope, returns
- /// false. Otherwise, issues a diagnostic and returns true.
- bool
- Sema::CheckTemplateDeclScope(Scope *S,
- MultiTemplateParamsArg &TemplateParameterLists) {
- assert(TemplateParameterLists.size() > 0 && "Not a template");
- // Find the nearest enclosing declaration scope.
- while ((S->getFlags() & Scope::DeclScope) == 0 ||
- (S->getFlags() & Scope::TemplateParamScope) != 0)
- S = S->getParent();
-
- TemplateParameterList *TemplateParams =
- static_cast<TemplateParameterList*>(*TemplateParameterLists.get());
- SourceLocation TemplateLoc = TemplateParams->getTemplateLoc();
- SourceRange TemplateRange
- = SourceRange(TemplateLoc, TemplateParams->getRAngleLoc());
- // C++ [temp]p2:
- // A template-declaration can appear only as a namespace scope or
- // class scope declaration.
- DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity());
- while (Ctx && isa<LinkageSpecDecl>(Ctx)) {
- if (cast<LinkageSpecDecl>(Ctx)->getLanguage() != LinkageSpecDecl::lang_cxx)
- return Diag(TemplateLoc, diag::err_template_linkage)
- << TemplateRange;
- Ctx = Ctx->getParent();
- }
- if (Ctx && (Ctx->isFileContext() || Ctx->isRecord()))
- return false;
- return Diag(TemplateLoc, diag::err_template_outside_namespace_or_class_scope)
- << TemplateRange;
- }
- /// \brief Check whether a class template specialization or explicit
- /// instantiation in the current context is well-formed.
- ///
- /// This routine determines whether a class template specialization or
- /// explicit instantiation can be declared in the current context
- /// (C++ [temp.expl.spec]p2, C++0x [temp.explicit]p2) and emits
- /// appropriate diagnostics if there was an error. It returns true if
- // there was an error that we cannot recover from, and false otherwise.
- bool
- Sema::CheckClassTemplateSpecializationScope(ClassTemplateDecl *ClassTemplate,
- ClassTemplateSpecializationDecl *PrevDecl,
- SourceLocation TemplateNameLoc,
- SourceRange ScopeSpecifierRange,
- bool PartialSpecialization,
- bool ExplicitInstantiation) {
- // C++ [temp.expl.spec]p2:
- // An explicit specialization shall be declared in the namespace
- // of which the template is a member, or, for member templates, in
- // the namespace of which the enclosing class or enclosing class
- // template is a member. An explicit specialization of a member
- // function, member class or static data member of a class
- // template shall be declared in the namespace of which the class
- // template is a member. Such a declaration may also be a
- // definition. If the declaration is not a definition, the
- // specialization may be defined later in the name- space in which
- // the explicit specialization was declared, or in a namespace
- // that encloses the one in which the explicit specialization was
- // declared.
- if (CurContext->getLookupContext()->isFunctionOrMethod()) {
- int Kind = ExplicitInstantiation? 2 : PartialSpecialization? 1 : 0;
- Diag(TemplateNameLoc, diag::err_template_spec_decl_function_scope)
- << Kind << ClassTemplate;
- return true;
- }
- DeclContext *DC = CurContext->getEnclosingNamespaceContext();
- DeclContext *TemplateContext
- = ClassTemplate->getDeclContext()->getEnclosingNamespaceContext();
- if ((!PrevDecl || PrevDecl->getSpecializationKind() == TSK_Undeclared) &&
- !ExplicitInstantiation) {
- // There is no prior declaration of this entity, so this
- // specialization must be in the same context as the template
- // itself.
- if (DC != TemplateContext) {
- if (isa<TranslationUnitDecl>(TemplateContext))
- Diag(TemplateNameLoc, diag::err_template_spec_decl_out_of_scope_global)
- << PartialSpecialization
- << ClassTemplate << ScopeSpecifierRange;
- else if (isa<NamespaceDecl>(TemplateContext))
- Diag(TemplateNameLoc, diag::err_template_spec_decl_out_of_scope)
- << PartialSpecialization << ClassTemplate
- << cast<NamedDecl>(TemplateContext) << ScopeSpecifierRange;
- Diag(ClassTemplate->getLocation(), diag::note_template_decl_here);
- }
- return false;
- }
- // We have a previous declaration of this entity. Make sure that
- // this redeclaration (or definition) occurs in an enclosing namespace.
- if (!CurContext->Encloses(TemplateContext)) {
- // FIXME: In C++98, we would like to turn these errors into warnings,
- // dependent on a -Wc++0x flag.
- bool SuppressedDiag = false;
- int Kind = ExplicitInstantiation? 2 : PartialSpecialization? 1 : 0;
- if (isa<TranslationUnitDecl>(TemplateContext)) {
- if (!ExplicitInstantiation || getLangOptions().CPlusPlus0x)
- Diag(TemplateNameLoc, diag::err_template_spec_redecl_global_scope)
- << Kind << ClassTemplate << ScopeSpecifierRange;
- else
- SuppressedDiag = true;
- } else if (isa<NamespaceDecl>(TemplateContext)) {
- if (!ExplicitInstantiation || getLangOptions().CPlusPlus0x)
- Diag(TemplateNameLoc, diag::err_template_spec_redecl_out_of_scope)
- << Kind << ClassTemplate
- << cast<NamedDecl>(TemplateContext) << ScopeSpecifierRange;
- else
- SuppressedDiag = true;
- }
-
- if (!SuppressedDiag)
- Diag(ClassTemplate->getLocation(), diag::note_template_decl_here);
- }
- return false;
- }
- /// \brief Check the non-type template arguments of a class template
- /// partial specialization according to C++ [temp.class.spec]p9.
- ///
- /// \param TemplateParams the template parameters of the primary class
- /// template.
- ///
- /// \param TemplateArg the template arguments of the class template
- /// partial specialization.
- ///
- /// \param MirrorsPrimaryTemplate will be set true if the class
- /// template partial specialization arguments are identical to the
- /// implicit template arguments of the primary template. This is not
- /// necessarily an error (C++0x), and it is left to the caller to diagnose
- /// this condition when it is an error.
- ///
- /// \returns true if there was an error, false otherwise.
- bool Sema::CheckClassTemplatePartialSpecializationArgs(
- TemplateParameterList *TemplateParams,
- const TemplateArgument *TemplateArgs,
- bool &MirrorsPrimaryTemplate) {
- // FIXME: the interface to this function will have to change to
- // accommodate variadic templates.
- MirrorsPrimaryTemplate = true;
- for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
- // Determine whether the template argument list of the partial
- // specialization is identical to the implicit argument list of
- // the primary template. The caller may need to diagnostic this as
- // an error per C++ [temp.class.spec]p9b3.
- if (MirrorsPrimaryTemplate) {
- if (TemplateTypeParmDecl *TTP
- = dyn_cast<TemplateTypeParmDecl>(TemplateParams->getParam(I))) {
- if (Context.getCanonicalType(Context.getTypeDeclType(TTP)) !=
- Context.getCanonicalType(TemplateArgs[I].getAsType()))
- MirrorsPrimaryTemplate = false;
- } else if (TemplateTemplateParmDecl *TTP
- = dyn_cast<TemplateTemplateParmDecl>(
- TemplateParams->getParam(I))) {
- // FIXME: We should settle on either Declaration storage or
- // Expression storage for template template parameters.
- TemplateTemplateParmDecl *ArgDecl
- = dyn_cast_or_null<TemplateTemplateParmDecl>(
- TemplateArgs[I].getAsDecl());
- if (!ArgDecl)
- if (DeclRefExpr *DRE
- = dyn_cast_or_null<DeclRefExpr>(TemplateArgs[I].getAsExpr()))
- ArgDecl = dyn_cast<TemplateTemplateParmDecl>(DRE->getDecl());
- if (!ArgDecl ||
- ArgDecl->getIndex() != TTP->getIndex() ||
- ArgDecl->getDepth() != TTP->getDepth())
- MirrorsPrimaryTemplate = false;
- }
- }
- NonTypeTemplateParmDecl *Param
- = dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I));
- if (!Param) {
- continue;
- }
- Expr *ArgExpr = TemplateArgs[I].getAsExpr();
- if (!ArgExpr) {
- MirrorsPrimaryTemplate = false;
- continue;
- }
- // C++ [temp.class.spec]p8:
- // A non-type argument is non-specialized if it is the name of a
- // non-type parameter. All other non-type arguments are
- // specialized.
- //
- // Below, we check the two conditions that only apply to
- // specialized non-type arguments, so skip any non-specialized
- // arguments.
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr))
- if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl())) {
- if (MirrorsPrimaryTemplate &&
- (Param->getIndex() != NTTP->getIndex() ||
- Param->getDepth() != NTTP->getDepth()))
- MirrorsPrimaryTemplate = false;
- continue;
- }
- // C++ [temp.class.spec]p9:
- // Within the argument list of a class template partial
- // specialization, the following restrictions apply:
- // -- A partially specialized non-type argument expression
- // shall not involve a template parameter of the partial
- // specialization except when the argument expression is a
- // simple identifier.
- if (ArgExpr->isTypeDependent() || ArgExpr->isValueDependent()) {
- Diag(ArgExpr->getLocStart(),
- diag::err_dependent_non_type_arg_in_partial_spec)
- << ArgExpr->getSourceRange();
- return true;
- }
- // -- The type of a template parameter corresponding to a
- // specialized non-type argument shall not be dependent on a
- // parameter of the specialization.
- if (Param->getType()->isDependentType()) {
- Diag(ArgExpr->getLocStart(),
- diag::err_dependent_typed_non_type_arg_in_partial_spec)
- << Param->getType()
- << ArgExpr->getSourceRange();
- Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
- }
- MirrorsPrimaryTemplate = false;
- }
- return false;
- }
- Sema::DeclResult
- Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
- SourceLocation KWLoc,
- const CXXScopeSpec &SS,
- TemplateTy TemplateD,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc,
- AttributeList *Attr,
- MultiTemplateParamsArg TemplateParameterLists) {
- // Find the class template we're specializing
- TemplateName Name = TemplateD.getAsVal<TemplateName>();
- ClassTemplateDecl *ClassTemplate
- = cast<ClassTemplateDecl>(Name.getAsTemplateDecl());
- bool isPartialSpecialization = false;
- // Check the validity of the template headers that introduce this
- // template.
- // FIXME: Once we have member templates, we'll need to check
- // C++ [temp.expl.spec]p17-18, where we could have multiple levels of
- // template<> headers.
- if (TemplateParameterLists.size() == 0)
- Diag(KWLoc, diag::err_template_spec_needs_header)
- << CodeModificationHint::CreateInsertion(KWLoc, "template<> ");
- else {
- TemplateParameterList *TemplateParams
- = static_cast<TemplateParameterList*>(*TemplateParameterLists.get());
- if (TemplateParameterLists.size() > 1) {
- Diag(TemplateParams->getTemplateLoc(),
- diag::err_template_spec_extra_headers);
- return true;
- }
- if (TemplateParams->size() > 0) {
- isPartialSpecialization = true;
- // C++ [temp.class.spec]p10:
- // The template parameter list of a specialization shall not
- // contain default template argument values.
- for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
- Decl *Param = TemplateParams->getParam(I);
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
- if (TTP->hasDefaultArgument()) {
- Diag(TTP->getDefaultArgumentLoc(),
- diag::err_default_arg_in_partial_spec);
- TTP->setDefaultArgument(QualType(), SourceLocation(), false);
- }
- } else if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
- if (Expr *DefArg = NTTP->getDefaultArgument()) {
- Diag(NTTP->getDefaultArgumentLoc(),
- diag::err_default_arg_in_partial_spec)
- << DefArg->getSourceRange();
- NTTP->setDefaultArgument(0);
- DefArg->Destroy(Context);
- }
- } else {
- TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(Param);
- if (Expr *DefArg = TTP->getDefaultArgument()) {
- Diag(TTP->getDefaultArgumentLoc(),
- diag::err_default_arg_in_partial_spec)
- << DefArg->getSourceRange();
- TTP->setDefaultArgument(0);
- DefArg->Destroy(Context);
- }
- }
- }
- }
- }
- // Check that the specialization uses the same tag kind as the
- // original template.
- TagDecl::TagKind Kind;
- switch (TagSpec) {
- default: assert(0 && "Unknown tag type!");
- case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
- case DeclSpec::TST_union: Kind = TagDecl::TK_union; break;
- case DeclSpec::TST_class: Kind = TagDecl::TK_class; break;
- }
- if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
- Kind, KWLoc,
- *ClassTemplate->getIdentifier())) {
- Diag(KWLoc, diag::err_use_with_wrong_tag)
- << ClassTemplate
- << CodeModificationHint::CreateReplacement(KWLoc,
- ClassTemplate->getTemplatedDecl()->getKindName());
- Diag(ClassTemplate->getTemplatedDecl()->getLocation(),
- diag::note_previous_use);
- Kind = ClassTemplate->getTemplatedDecl()->getTagKind();
- }
- // Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
- translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
- // Check that the template argument list is well-formed for this
- // template.
- TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
- if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
- &TemplateArgs[0], TemplateArgs.size(),
- RAngleLoc, ConvertedTemplateArgs))
- return true;
- assert((ConvertedTemplateArgs.size() ==
- ClassTemplate->getTemplateParameters()->size()) &&
- "Converted template argument list is too short!");
-
- // Find the class template (partial) specialization declaration that
- // corresponds to these arguments.
- llvm::FoldingSetNodeID ID;
- if (isPartialSpecialization) {
- bool MirrorsPrimaryTemplate;
- if (CheckClassTemplatePartialSpecializationArgs(
- ClassTemplate->getTemplateParameters(),
- ConvertedTemplateArgs.getFlatArgumentList(),
- MirrorsPrimaryTemplate))
- return true;
- if (MirrorsPrimaryTemplate) {
- // C++ [temp.class.spec]p9b3:
- //
- // -- The argument list of the specialization shall not be identical
- // to the implicit argument list of the primary template.
- Diag(TemplateNameLoc, diag::err_partial_spec_args_match_primary_template)
- << (TK == TK_Definition)
- << CodeModificationHint::CreateRemoval(SourceRange(LAngleLoc,
- RAngleLoc));
- return ActOnClassTemplate(S, TagSpec, TK, KWLoc, SS,
- ClassTemplate->getIdentifier(),
- TemplateNameLoc,
- Attr,
- move(TemplateParameterLists),
- AS_none);
- }
- // FIXME: Template parameter list matters, too
- ClassTemplatePartialSpecializationDecl::Profile(ID,
- ConvertedTemplateArgs.getFlatArgumentList(),
- ConvertedTemplateArgs.flatSize());
- }
- else
- ClassTemplateSpecializationDecl::Profile(ID,
- ConvertedTemplateArgs.getFlatArgumentList(),
- ConvertedTemplateArgs.flatSize());
- void *InsertPos = 0;
- ClassTemplateSpecializationDecl *PrevDecl = 0;
- if (isPartialSpecialization)
- PrevDecl
- = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
- InsertPos);
- else
- PrevDecl
- = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
- ClassTemplateSpecializationDecl *Specialization = 0;
- // Check whether we can declare a class template specialization in
- // the current scope.
- if (CheckClassTemplateSpecializationScope(ClassTemplate, PrevDecl,
- TemplateNameLoc,
- SS.getRange(),
- isPartialSpecialization,
- /*ExplicitInstantiation=*/false))
- return true;
- if (PrevDecl && PrevDecl->getSpecializationKind() == TSK_Undeclared) {
- // Since the only prior class template specialization with these
- // arguments was referenced but not declared, reuse that
- // declaration node as our own, updating its source location to
- // reflect our new declaration.
- Specialization = PrevDecl;
- Specialization->setLocation(TemplateNameLoc);
- PrevDecl = 0;
- } else if (isPartialSpecialization) {
- // Create a new class template partial specialization declaration node.
- TemplateParameterList *TemplateParams
- = static_cast<TemplateParameterList*>(*TemplateParameterLists.get());
- ClassTemplatePartialSpecializationDecl *PrevPartial
- = cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
- ClassTemplatePartialSpecializationDecl *Partial
- = ClassTemplatePartialSpecializationDecl::Create(Context,
- ClassTemplate->getDeclContext(),
- TemplateNameLoc,
- TemplateParams,
- ClassTemplate,
- ConvertedTemplateArgs,
- PrevPartial);
- if (PrevPartial) {
- ClassTemplate->getPartialSpecializations().RemoveNode(PrevPartial);
- ClassTemplate->getPartialSpecializations().GetOrInsertNode(Partial);
- } else {
- ClassTemplate->getPartialSpecializations().InsertNode(Partial, InsertPos);
- }
- Specialization = Partial;
- // Check that all of the template parameters of the class template
- // partial specialization are deducible from the template
- // arguments. If not, this class template partial specialization
- // will never be used.
- llvm::SmallVector<bool, 8> DeducibleParams;
- DeducibleParams.resize(TemplateParams->size());
- MarkDeducedTemplateParameters(Partial->getTemplateArgs(), DeducibleParams);
- unsigned NumNonDeducible = 0;
- for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I)
- if (!DeducibleParams[I])
- ++NumNonDeducible;
- if (NumNonDeducible) {
- Diag(TemplateNameLoc, diag::warn_partial_specs_not_deducible)
- << (NumNonDeducible > 1)
- << SourceRange(TemplateNameLoc, RAngleLoc);
- for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) {
- if (!DeducibleParams[I]) {
- NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I));
- if (Param->getDeclName())
- Diag(Param->getLocation(),
- diag::note_partial_spec_unused_parameter)
- << Param->getDeclName();
- else
- Diag(Param->getLocation(),
- diag::note_partial_spec_unused_parameter)
- << std::string("<anonymous>");
- }
- }
- }
- } else {
- // Create a new class template specialization declaration node for
- // this explicit specialization.
- Specialization
- = ClassTemplateSpecializationDecl::Create(Context,
- ClassTemplate->getDeclContext(),
- TemplateNameLoc,
- ClassTemplate,
- ConvertedTemplateArgs,
- PrevDecl);
- if (PrevDecl) {
- ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
- ClassTemplate->getSpecializations().GetOrInsertNode(Specialization);
- } else {
- ClassTemplate->getSpecializations().InsertNode(Specialization,
- InsertPos);
- }
- }
- // Note that this is an explicit specialization.
- Specialization->setSpecializationKind(TSK_ExplicitSpecialization);
- // Check that this isn't a redefinition of this specialization.
- if (TK == TK_Definition) {
- if (RecordDecl *Def = Specialization->getDefinition(Context)) {
- // FIXME: Should also handle explicit specialization after implicit
- // instantiation with a special diagnostic.
- SourceRange Range(TemplateNameLoc, RAngleLoc);
- Diag(TemplateNameLoc, diag::err_redefinition)
- << Context.getTypeDeclType(Specialization) << Range;
- Diag(Def->getLocation(), diag::note_previous_definition);
- Specialization->setInvalidDecl();
- return true;
- }
- }
- // Build the fully-sugared type for this class template
- // specialization as the user wrote in the specialization
- // itself. This means that we'll pretty-print the type retrieved
- // from the specialization's declaration the way that the user
- // actually wrote the specialization, rather than formatting the
- // name based on the "canonical" representation used to store the
- // template arguments in the specialization.
- QualType WrittenTy
- = Context.getTemplateSpecializationType(Name,
- &TemplateArgs[0],
- TemplateArgs.size(),
- Context.getTypeDeclType(Specialization));
- Specialization->setTypeAsWritten(WrittenTy);
- TemplateArgsIn.release();
- // C++ [temp.expl.spec]p9:
- // A template explicit specialization is in the scope of the
- // namespace in which the template was defined.
- //
- // We actually implement this paragraph where we set the semantic
- // context (in the creation of the ClassTemplateSpecializationDecl),
- // but we also maintain the lexical context where the actual
- // definition occurs.
- Specialization->setLexicalDeclContext(CurContext);
-
- // We may be starting the definition of this specialization.
- if (TK == TK_Definition)
- Specialization->startDefinition();
- // Add the specialization into its lexical context, so that it can
- // be seen when iterating through the list of declarations in that
- // context. However, specializations are not found by name lookup.
- CurContext->addDecl(Context, Specialization);
- return DeclPtrTy::make(Specialization);
- }
- // Explicit instantiation of a class template specialization
- Sema::DeclResult
- Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- const CXXScopeSpec &SS,
- TemplateTy TemplateD,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc,
- AttributeList *Attr) {
- // Find the class template we're specializing
- TemplateName Name = TemplateD.getAsVal<TemplateName>();
- ClassTemplateDecl *ClassTemplate
- = cast<ClassTemplateDecl>(Name.getAsTemplateDecl());
- // Check that the specialization uses the same tag kind as the
- // original template.
- TagDecl::TagKind Kind;
- switch (TagSpec) {
- default: assert(0 && "Unknown tag type!");
- case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
- case DeclSpec::TST_union: Kind = TagDecl::TK_union; break;
- case DeclSpec::TST_class: Kind = TagDecl::TK_class; break;
- }
- if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
- Kind, KWLoc,
- *ClassTemplate->getIdentifier())) {
- Diag(KWLoc, diag::err_use_with_wrong_tag)
- << ClassTemplate
- << CodeModificationHint::CreateReplacement(KWLoc,
- ClassTemplate->getTemplatedDecl()->getKindName());
- Diag(ClassTemplate->getTemplatedDecl()->getLocation(),
- diag::note_previous_use);
- Kind = ClassTemplate->getTemplatedDecl()->getTagKind();
- }
- // C++0x [temp.explicit]p2:
- // [...] An explicit instantiation shall appear in an enclosing
- // namespace of its template. [...]
- //
- // This is C++ DR 275.
- if (CheckClassTemplateSpecializationScope(ClassTemplate, 0,
- TemplateNameLoc,
- SS.getRange(),
- /*PartialSpecialization=*/false,
- /*ExplicitInstantiation=*/true))
- return true;
- // Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
- translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
- // Check that the template argument list is well-formed for this
- // template.
- TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
- if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
- TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc, ConvertedTemplateArgs))
- return true;
- assert((ConvertedTemplateArgs.size() ==
- ClassTemplate->getTemplateParameters()->size()) &&
- "Converted template argument list is too short!");
-
- // Find the class template specialization declaration that
- // corresponds to these arguments.
- llvm::FoldingSetNodeID ID;
- ClassTemplateSpecializationDecl::Profile(ID,
- ConvertedTemplateArgs.getFlatArgumentList(),
- ConvertedTemplateArgs.flatSize());
- void *InsertPos = 0;
- ClassTemplateSpecializationDecl *PrevDecl
- = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
- ClassTemplateSpecializationDecl *Specialization = 0;
- bool SpecializationRequiresInstantiation = true;
- if (PrevDecl) {
- if (PrevDecl->getSpecializationKind() == TSK_ExplicitInstantiation) {
- // This particular specialization has already been declared or
- // instantiated. We cannot explicitly instantiate it.
- Diag(TemplateNameLoc, diag::err_explicit_instantiation_duplicate)
- << Context.getTypeDeclType(PrevDecl);
- Diag(PrevDecl->getLocation(),
- diag::note_previous_explicit_instantiation);
- return DeclPtrTy::make(PrevDecl);
- }
- if (PrevDecl->getSpecializationKind() == TSK_ExplicitSpecialization) {
- // C++ DR 259, C++0x [temp.explicit]p4:
- // For a given set of template parameters, if an explicit
- // instantiation of a template appears after a declaration of
- // an explicit specialization for that template, the explicit
- // instantiation has no effect.
- if (!getLangOptions().CPlusPlus0x) {
- Diag(TemplateNameLoc,
- diag::ext_explicit_instantiation_after_specialization)
- << Context.getTypeDeclType(PrevDecl);
- Diag(PrevDecl->getLocation(),
- diag::note_previous_template_specialization);
- }
- // Create a new class template specialization declaration node
- // for this explicit specialization. This node is only used to
- // record the existence of this explicit instantiation for
- // accurate reproduction of the source code; we don't actually
- // use it for anything, since it is semantically irrelevant.
- Specialization
- = ClassTemplateSpecializationDecl::Create(Context,
- ClassTemplate->getDeclContext(),
- TemplateNameLoc,
- ClassTemplate,
- ConvertedTemplateArgs, 0);
- Specialization->setLexicalDeclContext(CurContext);
- CurContext->addDecl(Context, Specialization);
- return DeclPtrTy::make(Specialization);
- }
- // If we have already (implicitly) instantiated this
- // specialization, there is less work to do.
- if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation)
- SpecializationRequiresInstantiation = false;
- // Since the only prior class template specialization with these
- // arguments was referenced but not declared, reuse that
- // declaration node as our own, updating its source location to
- // reflect our new declaration.
- Specialization = PrevDecl;
- Specialization->setLocation(TemplateNameLoc);
- PrevDecl = 0;
- } else {
- // Create a new class template specialization declaration node for
- // this explicit specialization.
- Specialization
- = ClassTemplateSpecializationDecl::Create(Context,
- ClassTemplate->getDeclContext(),
- TemplateNameLoc,
- ClassTemplate,
- ConvertedTemplateArgs, 0);
- ClassTemplate->getSpecializations().InsertNode(Specialization,
- InsertPos);
- }
- // Build the fully-sugared type for this explicit instantiation as
- // the user wrote in the explicit instantiation itself. This means
- // that we'll pretty-print the type retrieved from the
- // specialization's declaration the way that the user actually wrote
- // the explicit instantiation, rather than formatting the name based
- // on the "canonical" representation used to store the template
- // arguments in the specialization.
- QualType WrittenTy
- = Context.getTemplateSpecializationType(Name,
- TemplateArgs.data(),
- TemplateArgs.size(),
- Context.getTypeDeclType(Specialization));
- Specialization->setTypeAsWritten(WrittenTy);
- TemplateArgsIn.release();
- // Add the explicit instantiation into its lexical context. However,
- // since explicit instantiations are never found by name lookup, we
- // just put it into the declaration context directly.
- Specialization->setLexicalDeclContext(CurContext);
- CurContext->addDecl(Context, Specialization);
- // C++ [temp.explicit]p3:
- // A definition of a class template or class member template
- // shall be in scope at the point of the explicit instantiation of
- // the class template or class member template.
- //
- // This check comes when we actually try to perform the
- // instantiation.
- if (SpecializationRequiresInstantiation)
- InstantiateClassTemplateSpecialization(Specialization, true);
- else // Instantiate the members of this class template specialization.
- InstantiateClassTemplateSpecializationMembers(TemplateLoc, Specialization);
- return DeclPtrTy::make(Specialization);
- }
- // Explicit instantiation of a member class of a class template.
- Sema::DeclResult
- Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- const CXXScopeSpec &SS,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- AttributeList *Attr) {
- bool Owned = false;
- DeclPtrTy TagD = ActOnTag(S, TagSpec, Action::TK_Reference,
- KWLoc, SS, Name, NameLoc, Attr, AS_none, Owned);
- if (!TagD)
- return true;
- TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
- if (Tag->isEnum()) {
- Diag(TemplateLoc, diag::err_explicit_instantiation_enum)
- << Context.getTypeDeclType(Tag);
- return true;
- }
- if (Tag->isInvalidDecl())
- return true;
- CXXRecordDecl *Record = cast<CXXRecordDecl>(Tag);
- CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
- if (!Pattern) {
- Diag(TemplateLoc, diag::err_explicit_instantiation_nontemplate_type)
- << Context.getTypeDeclType(Record);
- Diag(Record->getLocation(), diag::note_nontemplate_decl_here);
- return true;
- }
- // C++0x [temp.explicit]p2:
- // [...] An explicit instantiation shall appear in an enclosing
- // namespace of its template. [...]
- //
- // This is C++ DR 275.
- if (getLangOptions().CPlusPlus0x) {
- // FIXME: In C++98, we would like to turn these errors into warnings,
- // dependent on a -Wc++0x flag.
- DeclContext *PatternContext
- = Pattern->getDeclContext()->getEnclosingNamespaceContext();
- if (!CurContext->Encloses(PatternContext)) {
- Diag(TemplateLoc, diag::err_explicit_instantiation_out_of_scope)
- << Record << cast<NamedDecl>(PatternContext) << SS.getRange();
- Diag(Pattern->getLocation(), diag::note_previous_declaration);
- }
- }
- if (!Record->getDefinition(Context)) {
- // If the class has a definition, instantiate it (and all of its
- // members, recursively).
- Pattern = cast_or_null<CXXRecordDecl>(Pattern->getDefinition(Context));
- if (Pattern && InstantiateClass(TemplateLoc, Record, Pattern,
- getTemplateInstantiationArgs(Record),
- /*ExplicitInstantiation=*/true))
- return true;
- } else // Instantiate all of the members of class.
- InstantiateClassMembers(TemplateLoc, Record,
- getTemplateInstantiationArgs(Record));
- // FIXME: We don't have any representation for explicit instantiations of
- // member classes. Such a representation is not needed for compilation, but it
- // should be available for clients that want to see all of the declarations in
- // the source code.
- return TagD;
- }
- Sema::TypeResult
- Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
- const IdentifierInfo &II, SourceLocation IdLoc) {
- NestedNameSpecifier *NNS
- = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
- if (!NNS)
- return true;
- QualType T = CheckTypenameType(NNS, II, SourceRange(TypenameLoc, IdLoc));
- if (T.isNull())
- return true;
- return T.getAsOpaquePtr();
- }
- Sema::TypeResult
- Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
- SourceLocation TemplateLoc, TypeTy *Ty) {
- QualType T = QualType::getFromOpaquePtr(Ty);
- NestedNameSpecifier *NNS
- = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
- const TemplateSpecializationType *TemplateId
- = T->getAsTemplateSpecializationType();
- assert(TemplateId && "Expected a template specialization type");
- if (NNS->isDependent())
- return Context.getTypenameType(NNS, TemplateId).getAsOpaquePtr();
- return Context.getQualifiedNameType(NNS, T).getAsOpaquePtr();
- }
- /// \brief Build the type that describes a C++ typename specifier,
- /// e.g., "typename T::type".
- QualType
- Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II,
- SourceRange Range) {
- CXXRecordDecl *CurrentInstantiation = 0;
- if (NNS->isDependent()) {
- CurrentInstantiation = getCurrentInstantiationOf(NNS);
- // If the nested-name-specifier does not refer to the current
- // instantiation, then build a typename type.
- if (!CurrentInstantiation)
- return Context.getTypenameType(NNS, &II);
- }
- DeclContext *Ctx = 0;
- if (CurrentInstantiation)
- Ctx = CurrentInstantiation;
- else {
- CXXScopeSpec SS;
- SS.setScopeRep(NNS);
- SS.setRange(Range);
- if (RequireCompleteDeclContext(SS))
- return QualType();
- Ctx = computeDeclContext(SS);
- }
- assert(Ctx && "No declaration context?");
- DeclarationName Name(&II);
- LookupResult Result = LookupQualifiedName(Ctx, Name, LookupOrdinaryName,
- false);
- unsigned DiagID = 0;
- Decl *Referenced = 0;
- switch (Result.getKind()) {
- case LookupResult::NotFound:
- if (Ctx->isTranslationUnit())
- DiagID = diag::err_typename_nested_not_found_global;
- else
- DiagID = diag::err_typename_nested_not_found;
- break;
- case LookupResult::Found:
- if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getAsDecl())) {
- // We found a type. Build a QualifiedNameType, since the
- // typename-specifier was just sugar. FIXME: Tell
- // QualifiedNameType that it has a "typename" prefix.
- return Context.getQualifiedNameType(NNS, Context.getTypeDeclType(Type));
- }
- DiagID = diag::err_typename_nested_not_type;
- Referenced = Result.getAsDecl();
- break;
- case LookupResult::FoundOverloaded:
- DiagID = diag::err_typename_nested_not_type;
- Referenced = *Result.begin();
- break;
- case LookupResult::AmbiguousBaseSubobjectTypes:
- case LookupResult::AmbiguousBaseSubobjects:
- case LookupResult::AmbiguousReference:
- DiagnoseAmbiguousLookup(Result, Name, Range.getEnd(), Range);
- return QualType();
- }
- // If we get here, it's because name lookup did not find a
- // type. Emit an appropriate diagnostic and return an error.
- if (NamedDecl *NamedCtx = dyn_cast<NamedDecl>(Ctx))
- Diag(Range.getEnd(), DiagID) << Range << Name << NamedCtx;
- else
- Diag(Range.getEnd(), DiagID) << Range << Name;
- if (Referenced)
- Diag(Referenced->getLocation(), diag::note_typename_refers_here)
- << Name;
- return QualType();
- }
|