diff options
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 920 |
1 files changed, 530 insertions, 390 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 28603daa267c..63581a44dbe5 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -10,8 +10,8 @@ //===----------------------------------------------------------------------===/ #include "TreeTransform.h" -#include "clang/AST/ASTContext.h" #include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" @@ -20,6 +20,7 @@ #include "clang/AST/TypeVisitor.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedTemplate.h" @@ -51,8 +52,8 @@ static NamedDecl *isAcceptableTemplateName(ASTContext &Context, if (isa<TemplateDecl>(D)) { if (!AllowFunctionTemplates && isa<FunctionTemplateDecl>(D)) - return 0; - + return nullptr; + return Orig; } @@ -78,10 +79,10 @@ static NamedDecl *isAcceptableTemplateName(ASTContext &Context, return Spec->getSpecializedTemplate(); } - return 0; + return nullptr; } - return 0; + return nullptr; } void Sema::FilterAcceptableTemplateNames(LookupResult &R, @@ -193,8 +194,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S, TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl()); if (SS.isSet() && !SS.isInvalid()) { - NestedNameSpecifier *Qualifier - = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); + NestedNameSpecifier *Qualifier = SS.getScopeRep(); Template = Context.getQualifiedTemplateName(Qualifier, hasTemplateKeyword, TD); } else { @@ -250,7 +250,7 @@ void Sema::LookupTemplateName(LookupResult &Found, bool &MemberOfUnknownSpecialization) { // Determine where to perform name lookup MemberOfUnknownSpecialization = false; - DeclContext *LookupCtx = 0; + DeclContext *LookupCtx = nullptr; bool isDependent = false; if (!ObjectType.isNull()) { // This nested-name-specifier occurs in a member access expression, e.g., @@ -325,7 +325,8 @@ void Sema::LookupTemplateName(LookupResult &Found, FilterCCC.WantCXXNamedCasts = true; if (TypoCorrection Corrected = CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, - FilterCCC, LookupCtx)) { + FilterCCC, CTK_ErrorRecovery, + LookupCtx)) { Found.setLookupName(Corrected.getCorrection()); if (Corrected.getCorrectionDecl()) Found.addDecl(Corrected.getCorrectionDecl()); @@ -418,17 +419,12 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, // Since the 'this' expression is synthesized, we don't need to // perform the double-lookup check. - NamedDecl *FirstQualifierInScope = 0; + NamedDecl *FirstQualifierInScope = nullptr; - return Owned(CXXDependentScopeMemberExpr::Create(Context, - /*This*/ 0, ThisType, - /*IsArrow*/ true, - /*Op*/ SourceLocation(), - SS.getWithLocInContext(Context), - TemplateKWLoc, - FirstQualifierInScope, - NameInfo, - TemplateArgs)); + return CXXDependentScopeMemberExpr::Create( + Context, /*This*/ nullptr, ThisType, /*IsArrow*/ true, + /*Op*/ SourceLocation(), SS.getWithLocInContext(Context), TemplateKWLoc, + FirstQualifierInScope, NameInfo, TemplateArgs); } return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs); @@ -439,11 +435,9 @@ Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { - return Owned(DependentScopeDeclRefExpr::Create(Context, - SS.getWithLocInContext(Context), - TemplateKWLoc, - NameInfo, - TemplateArgs)); + return DependentScopeDeclRefExpr::Create( + Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo, + TemplateArgs); } /// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining @@ -474,7 +468,7 @@ TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) { D = Temp->getTemplatedDecl(); return Temp; } - return 0; + return nullptr; } ParsedTemplateArgument ParsedTemplateArgument::getTemplatePackExpansion( @@ -550,7 +544,7 @@ static void maybeDiagnoseTemplateParameterShadow(Sema &SemaRef, Scope *S, /// ParamNameLoc is the location of the parameter name (if any). /// If the type parameter has a default argument, it will be added /// later via ActOnTypeParameterDefault. -Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, +Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, SourceLocation EllipsisLoc, SourceLocation KeyLoc, IdentifierInfo *ParamName, @@ -566,10 +560,11 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, if (!ParamName) Loc = KeyLoc; + bool IsParameterPack = EllipsisLoc.isValid(); TemplateTypeParmDecl *Param = TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(), KeyLoc, Loc, Depth, Position, ParamName, - Typename, Ellipsis); + Typename, IsParameterPack); Param->setAccess(AS_public); if (Invalid) Param->setInvalidDecl(); @@ -585,7 +580,7 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, // 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 (DefaultArg && Ellipsis) { + if (DefaultArg && IsParameterPack) { Diag(EqualLoc, diag::err_template_param_pack_default_arg); DefaultArg = ParsedType(); } @@ -715,7 +710,7 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, // template-parameter that is not a template parameter pack. if (Default && IsParameterPack) { Diag(EqualLoc, diag::err_template_param_pack_default_arg); - Default = 0; + Default = nullptr; } // Check the well-formedness of the default template argument, if provided. @@ -730,7 +725,7 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, Param->setInvalidDecl(); return Param; } - Default = DefaultRes.take(); + Default = DefaultRes.get(); Param->setDefaultArgument(Default, false); } @@ -843,6 +838,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, AttributeList *Attr, TemplateParameterList *TemplateParams, AccessSpecifier AS, SourceLocation ModulePrivateLoc, + SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists, TemplateParameterList** OuterTemplateParamLists) { assert(TemplateParams && TemplateParams->size() > 0 && @@ -906,7 +902,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, if (Previous.isAmbiguous()) return true; - NamedDecl *PrevDecl = 0; + NamedDecl *PrevDecl = nullptr; if (Previous.begin() != Previous.end()) PrevDecl = (*Previous.begin())->getUnderlyingDecl(); @@ -949,7 +945,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // Declarations in outer scopes don't matter. However, the outermost // context we computed is the semantic context for our new // declaration. - PrevDecl = PrevClassTemplate = 0; + PrevDecl = PrevClassTemplate = nullptr; SemanticContext = OutermostContext; // Check that the chosen semantic context doesn't already contain a @@ -968,8 +964,9 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, PrevDecl = (*Previous.begin())->getUnderlyingDecl(); } } - } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S)) - PrevDecl = PrevClassTemplate = 0; + } else if (PrevDecl && + !isDeclInScope(PrevDecl, SemanticContext, S, SS.isValid())) + PrevDecl = PrevClassTemplate = nullptr; if (PrevClassTemplate) { // Ensure that the template parameter lists are compatible. Skip this check @@ -1011,7 +1008,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(NameLoc, PrevDecl); // Just pretend that we didn't see the previous declaration. - PrevDecl = 0; + PrevDecl = nullptr; } else if (PrevDecl) { // C++ [temp]p5: // A class template shall not have the same name as any other @@ -1030,7 +1027,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, if (!(TUK == TUK_Friend && CurContext->isDependentContext()) && CheckTemplateParameterList( TemplateParams, - PrevClassTemplate ? PrevClassTemplate->getTemplateParameters() : 0, + PrevClassTemplate ? PrevClassTemplate->getTemplateParameters() + : nullptr, (SS.isSet() && SemanticContext && SemanticContext->isRecord() && SemanticContext->isDependentContext()) ? TPC_ClassTemplateMember @@ -1052,7 +1050,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, CXXRecordDecl *NewClass = CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name, PrevClassTemplate? - PrevClassTemplate->getTemplatedDecl() : 0, + PrevClassTemplate->getTemplatedDecl() : nullptr, /*DelayTypeCreation=*/true); SetNestedNameSpecifier(NewClass, SS); if (NumOuterTemplateParamLists > 0) @@ -1126,10 +1124,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, /* AddToContext = */ false); } - FriendDecl *Friend = FriendDecl::Create(Context, CurContext, - NewClass->getLocation(), - NewTemplate, - /*FIXME:*/NewClass->getLocation()); + FriendDecl *Friend = FriendDecl::Create( + Context, CurContext, NewClass->getLocation(), NewTemplate, FriendLoc); Friend->setAccess(AS_public); CurContext->addDecl(Friend); } @@ -1299,7 +1295,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, // Merge default arguments for template type parameters. TemplateTypeParmDecl *OldTypeParm - = OldParams? cast<TemplateTypeParmDecl>(*OldParam) : 0; + = OldParams? cast<TemplateTypeParmDecl>(*OldParam) : nullptr; if (NewTypeParm->isParameterPack()) { assert(!NewTypeParm->hasDefaultArgument() && @@ -1344,7 +1340,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, // Merge default arguments for non-type template parameters NonTypeTemplateParmDecl *OldNonTypeParm - = OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : 0; + = OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : nullptr; if (NewNonTypeParm->isParameterPack()) { assert(!NewNonTypeParm->hasDefaultArgument() && "Parameter packs can't have a default argument!"); @@ -1391,7 +1387,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, // Merge default arguments for template template parameters TemplateTemplateParmDecl *OldTemplateParm - = OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : 0; + = OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : nullptr; if (NewTemplateParm->isParameterPack()) { assert(!NewTemplateParm->hasDefaultArgument() && "Parameter packs can't have a default argument!"); @@ -1487,6 +1483,9 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { unsigned Depth; bool Match; + SourceLocation MatchLoc; + + DependencyChecker(unsigned Depth) : Depth(Depth), Match(false) {} DependencyChecker(TemplateParameterList *Params) : Match(false) { NamedDecl *ND = Params->getParam(0); @@ -1500,14 +1499,19 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { } } - bool Matches(unsigned ParmDepth) { + bool Matches(unsigned ParmDepth, SourceLocation Loc = SourceLocation()) { if (ParmDepth >= Depth) { Match = true; + MatchLoc = Loc; return true; } return false; } + bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { + return !Matches(TL.getTypePtr()->getDepth(), TL.getNameLoc()); + } + bool VisitTemplateTypeParmType(const TemplateTypeParmType *T) { return !Matches(T->getDepth()); } @@ -1515,21 +1519,28 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { bool TraverseTemplateName(TemplateName N) { if (TemplateTemplateParmDecl *PD = dyn_cast_or_null<TemplateTemplateParmDecl>(N.getAsTemplateDecl())) - if (Matches(PD->getDepth())) return false; + if (Matches(PD->getDepth())) + return false; return super::TraverseTemplateName(N); } bool VisitDeclRefExpr(DeclRefExpr *E) { if (NonTypeTemplateParmDecl *PD = - dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) { - if (PD->getDepth() == Depth) { - Match = true; + dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) + if (Matches(PD->getDepth(), E->getExprLoc())) return false; - } - } return super::VisitDeclRefExpr(E); } - + + bool VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { + return TraverseType(T->getReplacementType()); + } + + bool + VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) { + return TraverseTemplateArgument(T->getArgumentPack()); + } + bool TraverseInjectedClassNameType(const InjectedClassNameType *T) { return TraverseType(T->getInjectedSpecializationType()); } @@ -1577,6 +1588,9 @@ static SourceRange getRangeOfTypeInNestedNameSpecifier(ASTContext &Context, /// parameter lists. This scope specifier precedes a qualified name that is /// being declared. /// +/// \param TemplateId The template-id following the scope specifier, if there +/// is one. Used to check for a missing 'template<>'. +/// /// \param ParamLists the template parameter lists, from the outermost to the /// innermost template parameter lists. /// @@ -1595,6 +1609,7 @@ static SourceRange getRangeOfTypeInNestedNameSpecifier(ASTContext &Context, /// itself a template). TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS, + TemplateIdAnnotation *TemplateId, ArrayRef<TemplateParameterList *> ParamLists, bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid) { IsExplicitSpecialization = false; @@ -1701,6 +1716,37 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( // template<> for each enclosing class template that is // explicitly specialized. bool SawNonEmptyTemplateParameterList = false; + + auto CheckExplicitSpecialization = [&](SourceRange Range, bool Recovery) { + if (SawNonEmptyTemplateParameterList) { + Diag(DeclLoc, diag::err_specialize_member_of_template) + << !Recovery << Range; + Invalid = true; + IsExplicitSpecialization = false; + return true; + } + + return false; + }; + + auto DiagnoseMissingExplicitSpecialization = [&] (SourceRange Range) { + // Check that we can have an explicit specialization here. + if (CheckExplicitSpecialization(Range, true)) + return true; + + // We don't have a template header, but we should. + SourceLocation ExpectedTemplateLoc; + if (!ParamLists.empty()) + ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc(); + else + ExpectedTemplateLoc = DeclStartLoc; + + Diag(DeclLoc, diag::err_template_spec_needs_header) + << Range + << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> "); + return false; + }; + unsigned ParamIdx = 0; for (unsigned TypeIdx = 0, NumTypes = NestedTypes.size(); TypeIdx != NumTypes; ++TypeIdx) { @@ -1714,7 +1760,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( // For a dependent type, the set of template parameters that we // expect to see. - TemplateParameterList *ExpectedTemplateParams = 0; + TemplateParameterList *ExpectedTemplateParams = nullptr; // C++0x [temp.expl.spec]p15: // A member or a member template may be nested within many enclosing @@ -1771,13 +1817,9 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( // are not explicitly specialized as well. if (ParamIdx < ParamLists.size()) { if (ParamLists[ParamIdx]->size() == 0) { - if (SawNonEmptyTemplateParameterList) { - Diag(DeclLoc, diag::err_specialize_member_of_template) - << ParamLists[ParamIdx]->getSourceRange(); - Invalid = true; - IsExplicitSpecialization = false; - return 0; - } + if (CheckExplicitSpecialization(ParamLists[ParamIdx]->getSourceRange(), + false)) + return nullptr; } else SawNonEmptyTemplateParameterList = true; } @@ -1798,30 +1840,22 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( ParamLists[ParamIdx]->getRAngleLoc()) << getRangeOfTypeInNestedNameSpecifier(Context, T, SS); Invalid = true; - return 0; + return nullptr; } - + // Consume this template header. ++ParamIdx; continue; - } - - if (!IsFriend) { - // We don't have a template header, but we should. - SourceLocation ExpectedTemplateLoc; - if (!ParamLists.empty()) - ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc(); - else - ExpectedTemplateLoc = DeclStartLoc; - - Diag(DeclLoc, diag::err_template_spec_needs_header) - << getRangeOfTypeInNestedNameSpecifier(Context, T, SS) - << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> "); } - + + if (!IsFriend) + if (DiagnoseMissingExplicitSpecialization( + getRangeOfTypeInNestedNameSpecifier(Context, T, SS))) + return nullptr; + continue; } - + if (NeedNonemptyTemplateHeader) { // In friend declarations we can have template-ids which don't // depend on the corresponding template parameter lists. But @@ -1830,7 +1864,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( if (IsFriend && T->isDependentType()) { if (ParamIdx < ParamLists.size() && DependsOnTemplateParameters(T, ParamLists[ParamIdx])) - ExpectedTemplateParams = 0; + ExpectedTemplateParams = nullptr; else continue; } @@ -1842,9 +1876,9 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( ExpectedTemplateParams, true, TPL_TemplateMatch)) Invalid = true; - + if (!Invalid && - CheckTemplateParameterList(ParamLists[ParamIdx], 0, + CheckTemplateParameterList(ParamLists[ParamIdx], nullptr, TPC_ClassTemplateMember)) Invalid = true; @@ -1859,12 +1893,26 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( continue; } } - + // If there were at least as many template-ids as there were template // parameter lists, then there are no template parameter lists remaining for // the declaration itself. - if (ParamIdx >= ParamLists.size()) - return 0; + if (ParamIdx >= ParamLists.size()) { + if (TemplateId && !IsFriend) { + // We don't have a template header for the declaration itself, but we + // should. + IsExplicitSpecialization = true; + DiagnoseMissingExplicitSpecialization(SourceRange(TemplateId->LAngleLoc, + TemplateId->RAngleLoc)); + + // Fabricate an empty template parameter list for the invented header. + return TemplateParameterList::Create(Context, SourceLocation(), + SourceLocation(), nullptr, 0, + SourceLocation()); + } + + return nullptr; + } // If there were too many template parameter lists, complain about that now. if (ParamIdx < ParamLists.size() - 1) { @@ -1905,14 +1953,11 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( // unspecialized, except that the declaration shall not explicitly // specialize a class member template if its en- closing class templates // are not explicitly specialized as well. - if (ParamLists.back()->size() == 0 && SawNonEmptyTemplateParameterList) { - Diag(DeclLoc, diag::err_specialize_member_of_template) - << ParamLists[ParamIdx]->getSourceRange(); - Invalid = true; - IsExplicitSpecialization = false; - return 0; - } - + if (ParamLists.back()->size() == 0 && + CheckExplicitSpecialization(ParamLists[ParamIdx]->getSourceRange(), + false)) + return nullptr; + // Return the last template parameter list, which corresponds to the // entity being declared. return ParamLists.back(); @@ -1959,7 +2004,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, TemplateArgs); TemplateDecl *Template = Name.getAsTemplateDecl(); - if (!Template || isa<FunctionTemplateDecl>(Template)) { + if (!Template || isa<FunctionTemplateDecl>(Template) || + isa<VarTemplateDecl>(Template)) { // We might have a substituted template template parameter pack. If so, // build a template specialization type for it. if (Name.getAsSubstTemplateTemplateParmPack()) @@ -1974,17 +2020,15 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // Check that the template argument list is well-formed for this // template. SmallVector<TemplateArgument, 4> Converted; - bool ExpansionIntoFixedList = false; if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs, - false, Converted, &ExpansionIntoFixedList)) + false, Converted)) return QualType(); QualType CanonType; bool InstantiationDependent = false; - TypeAliasTemplateDecl *AliasTemplate = 0; - if (!ExpansionIntoFixedList && - (AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Template))) { + if (TypeAliasTemplateDecl *AliasTemplate = + dyn_cast<TypeAliasTemplateDecl>(Template)) { // Find the canonical type for this type alias template specialization. TypeAliasDecl *Pattern = AliasTemplate->getTemplatedDecl(); if (Pattern->isInvalidDecl()) @@ -2072,10 +2116,9 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, = dyn_cast<ClassTemplateDecl>(Template)) { // Find the class template specialization declaration that // corresponds to these arguments. - void *InsertPos = 0; + void *InsertPos = nullptr; ClassTemplateSpecializationDecl *Decl - = ClassTemplate->findSpecialization(Converted.data(), Converted.size(), - InsertPos); + = ClassTemplate->findSpecialization(Converted, InsertPos); if (!Decl) { // This is the first time we have referenced this class template // specialization. Create the canonical declaration and add it to @@ -2087,7 +2130,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, ClassTemplate->getLocation(), ClassTemplate, Converted.data(), - Converted.size(), 0); + Converted.size(), nullptr); ClassTemplate->AddSpecialization(Decl, InsertPos); if (ClassTemplate->isOutOfLine()) Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext()); @@ -2267,8 +2310,8 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, } static bool CheckTemplatePartialSpecializationArgs( - Sema &S, TemplateParameterList *TemplateParams, - SmallVectorImpl<TemplateArgument> &TemplateArgs); + Sema &S, SourceLocation NameLoc, TemplateParameterList *TemplateParams, + unsigned ExplicitArgs, SmallVectorImpl<TemplateArgument> &TemplateArgs); static bool CheckTemplateSpecializationScope(Sema &S, NamedDecl *Specialized, NamedDecl *PrevDecl, @@ -2340,25 +2383,49 @@ static bool isSameAsPrimaryTemplate(TemplateParameterList *Params, return true; } -DeclResult Sema::ActOnVarTemplateSpecialization( - Scope *S, VarTemplateDecl *VarTemplate, Declarator &D, TypeSourceInfo *DI, - SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams, - VarDecl::StorageClass SC, bool IsPartialSpecialization) { - assert(VarTemplate && "A variable template id without template?"); +/// Convert the parser's template argument list representation into our form. +static TemplateArgumentListInfo +makeTemplateArgumentListInfo(Sema &S, TemplateIdAnnotation &TemplateId) { + TemplateArgumentListInfo TemplateArgs(TemplateId.LAngleLoc, + TemplateId.RAngleLoc); + ASTTemplateArgsPtr TemplateArgsPtr(TemplateId.getTemplateArgs(), + TemplateId.NumArgs); + S.translateTemplateArguments(TemplateArgsPtr, TemplateArgs); + return TemplateArgs; +} +DeclResult Sema::ActOnVarTemplateSpecialization( + Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation TemplateKWLoc, + TemplateParameterList *TemplateParams, VarDecl::StorageClass SC, + bool IsPartialSpecialization) { // D must be variable template id. assert(D.getName().getKind() == UnqualifiedId::IK_TemplateId && "Variable template specialization is declared with a template it."); TemplateIdAnnotation *TemplateId = D.getName().TemplateId; + TemplateArgumentListInfo TemplateArgs = + makeTemplateArgumentListInfo(*this, *TemplateId); SourceLocation TemplateNameLoc = D.getIdentifierLoc(); SourceLocation LAngleLoc = TemplateId->LAngleLoc; SourceLocation RAngleLoc = TemplateId->RAngleLoc; - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), - TemplateId->NumArgs); - TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); - translateTemplateArguments(TemplateArgsPtr, TemplateArgs); - TemplateName Name(VarTemplate); + + TemplateName Name = TemplateId->Template.get(); + + // The template-id must name a variable template. + VarTemplateDecl *VarTemplate = + dyn_cast_or_null<VarTemplateDecl>(Name.getAsTemplateDecl()); + if (!VarTemplate) { + NamedDecl *FnTemplate; + if (auto *OTS = Name.getAsOverloadedTemplate()) + FnTemplate = *OTS->begin(); + else + FnTemplate = dyn_cast_or_null<FunctionTemplateDecl>(Name.getAsTemplateDecl()); + if (FnTemplate) + return Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template_but_method) + << FnTemplate->getDeclName(); + return Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template) + << IsPartialSpecialization; + } // Check for unexpanded parameter packs in any of the template arguments. for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) @@ -2396,7 +2463,8 @@ DeclResult Sema::ActOnVarTemplateSpecialization( // corresponds to these arguments. if (IsPartialSpecialization) { if (CheckTemplatePartialSpecializationArgs( - *this, VarTemplate->getTemplateParameters(), Converted)) + *this, TemplateNameLoc, VarTemplate->getTemplateParameters(), + TemplateArgs.size(), Converted)) return true; bool InstantiationDependent; @@ -2425,18 +2493,16 @@ DeclResult Sema::ActOnVarTemplateSpecialization( } } - void *InsertPos = 0; - VarTemplateSpecializationDecl *PrevDecl = 0; + void *InsertPos = nullptr; + VarTemplateSpecializationDecl *PrevDecl = nullptr; if (IsPartialSpecialization) // FIXME: Template parameter list matters too - PrevDecl = VarTemplate->findPartialSpecialization( - Converted.data(), Converted.size(), InsertPos); + PrevDecl = VarTemplate->findPartialSpecialization(Converted, InsertPos); else - PrevDecl = VarTemplate->findSpecialization(Converted.data(), - Converted.size(), InsertPos); + PrevDecl = VarTemplate->findSpecialization(Converted, InsertPos); - VarTemplateSpecializationDecl *Specialization = 0; + VarTemplateSpecializationDecl *Specialization = nullptr; // Check whether we can declare a variable template specialization in // the current scope. @@ -2452,7 +2518,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization( // the list of outer template parameters to reflect our new declaration. Specialization = PrevDecl; Specialization->setLocation(TemplateNameLoc); - PrevDecl = 0; + PrevDecl = nullptr; } else if (IsPartialSpecialization) { // Create a new class template partial specialization declaration node. VarTemplatePartialSpecializationDecl *PrevPartial = @@ -2494,7 +2560,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization( << Param->getDeclName(); else Diag(Param->getLocation(), diag::note_partial_spec_unused_parameter) - << "<anonymous>"; + << "(anonymous)"; } } } @@ -2589,18 +2655,17 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, // Check that the template argument list is well-formed for this template. SmallVector<TemplateArgument, 4> Converted; - bool ExpansionIntoFixedList = false; if (CheckTemplateArgumentList( Template, TemplateNameLoc, const_cast<TemplateArgumentListInfo &>(TemplateArgs), false, - Converted, &ExpansionIntoFixedList)) + Converted)) return true; // Find the variable template specialization declaration that // corresponds to these arguments. - void *InsertPos = 0; + void *InsertPos = nullptr; if (VarTemplateSpecializationDecl *Spec = Template->findSpecialization( - Converted.data(), Converted.size(), InsertPos)) + Converted, InsertPos)) // If we already have a variable template specialization, return it. return Spec; @@ -2652,11 +2717,6 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, } } - // If we're dealing with a member template where the template parameters - // have been instantiated, this provides the original template parameters - // from which the member template's parameters were instantiated. - SmallVector<const NamedDecl *, 4> InstantiatedTemplateParameters; - if (Matched.size() >= 1) { SmallVector<MatchResult, 4>::iterator Best = Matched.begin(); if (Matched.size() == 1) { @@ -2756,7 +2816,7 @@ Sema::CheckVarTemplateId(const CXXScopeSpec &SS, // Build an ordinary singleton decl ref. return BuildDeclarationNameExpr(SS, NameInfo, Var, - /*FoundD=*/0, TemplateArgs); + /*FoundD=*/nullptr, TemplateArgs); } ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, @@ -2779,10 +2839,13 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, assert(!R.isAmbiguous() && "ambiguous lookup when building templateid"); // In C++1y, check variable template ids. - if (R.getAsSingle<VarTemplateDecl>()) { - return Owned(CheckVarTemplateId(SS, R.getLookupNameInfo(), - R.getAsSingle<VarTemplateDecl>(), - TemplateKWLoc, TemplateArgs)); + bool InstantiationDependent; + if (R.getAsSingle<VarTemplateDecl>() && + !TemplateSpecializationType::anyDependentTemplateArguments( + *TemplateArgs, InstantiationDependent)) { + return CheckVarTemplateId(SS, R.getLookupNameInfo(), + R.getAsSingle<VarTemplateDecl>(), + TemplateKWLoc, TemplateArgs); } // We don't want lookup warnings at this point. @@ -2796,7 +2859,7 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, RequiresADL, TemplateArgs, R.begin(), R.end()); - return Owned(ULE); + return ULE; } // We actually only call this from template instantiation. @@ -2815,7 +2878,7 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, bool MemberOfUnknownSpecialization; LookupResult R(*this, NameInfo, LookupOrdinaryName); - LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false, + LookupTemplateName(R, (Scope*)nullptr, SS, QualType(), /*Entering*/ false, MemberOfUnknownSpecialization); if (R.isAmbiguous()) @@ -2829,8 +2892,8 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) { Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template) - << (NestedNameSpecifier*) SS.getScopeRep() - << NameInfo.getName() << SS.getRange(); + << SS.getScopeRep() + << NameInfo.getName().getAsString() << SS.getRange(); Diag(Temp->getLocation(), diag::note_referenced_class_template); return ExprError(); } @@ -2859,7 +2922,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, diag::ext_template_outside_of_template) << FixItHint::CreateRemoval(TemplateKWLoc); - DeclContext *LookupCtx = 0; + DeclContext *LookupCtx = nullptr; if (SS.isSet()) LookupCtx = computeDeclContext(SS, EnteringContext); if (!LookupCtx && ObjectType) @@ -2903,8 +2966,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, } } - NestedNameSpecifier *Qualifier - = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); + NestedNameSpecifier *Qualifier = SS.getScopeRep(); switch (Name.getKind()) { case UnqualifiedId::IK_Identifier: @@ -2915,11 +2977,10 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, case UnqualifiedId::IK_OperatorFunctionId: Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier, Name.OperatorFunctionId.Operator)); - return TNK_Dependent_template_name; + return TNK_Function_template; case UnqualifiedId::IK_LiteralOperatorId: - llvm_unreachable( - "We don't support these; Parse shouldn't have allowed propagation"); + llvm_unreachable("literal operator id cannot have a dependent scope"); default: break; @@ -2934,9 +2995,11 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, } bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, - const TemplateArgumentLoc &AL, + TemplateArgumentLoc &AL, SmallVectorImpl<TemplateArgument> &Converted) { const TemplateArgument &Arg = AL.getArgument(); + QualType ArgType; + TypeSourceInfo *TSI = nullptr; // Check template type parameter. switch(Arg.getKind()) { @@ -2944,6 +3007,8 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, // C++ [temp.arg.type]p1: // A template-argument for a template-parameter which is a // type shall be a type-id. + ArgType = Arg.getAsType(); + TSI = AL.getTypeSourceInfo(); break; case TemplateArgument::Template: { // We have a template type parameter but the template argument @@ -2978,18 +3043,38 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, } } - if (NameInfo.getName().isIdentifier()) { + if (auto *II = NameInfo.getName().getAsIdentifierInfo()) { LookupResult Result(*this, NameInfo, LookupOrdinaryName); LookupParsedName(Result, CurScope, &SS); if (Result.getAsSingle<TypeDecl>() || Result.getResultKind() == - LookupResult::NotFoundInCurrentInstantiation) { - // FIXME: Add a FixIt and fix up the template argument for recovery. + LookupResult::NotFoundInCurrentInstantiation) { + // Suggest that the user add 'typename' before the NNS. SourceLocation Loc = AL.getSourceRange().getBegin(); - Diag(Loc, diag::err_template_arg_must_be_type_suggest); + Diag(Loc, getLangOpts().MSVCCompat + ? diag::ext_ms_template_type_arg_missing_typename + : diag::err_template_arg_must_be_type_suggest) + << FixItHint::CreateInsertion(Loc, "typename "); Diag(Param->getLocation(), diag::note_template_param_here); - return true; + + // Recover by synthesizing a type using the location information that we + // already have. + ArgType = + Context.getDependentNameType(ETK_Typename, SS.getScopeRep(), II); + TypeLocBuilder TLB; + DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(ArgType); + TL.setElaboratedKeywordLoc(SourceLocation(/*synthesized*/)); + TL.setQualifierLoc(SS.getWithLocInContext(Context)); + TL.setNameLoc(NameInfo.getLoc()); + TSI = TLB.getTypeSourceInfo(Context, ArgType); + + // Overwrite our input TemplateArgumentLoc so that we can recover + // properly. + AL = TemplateArgumentLoc(TemplateArgument(ArgType), + TemplateArgumentLocInfo(TSI)); + + break; } } // fallthrough @@ -3005,11 +3090,11 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, } } - if (CheckTemplateArgument(Param, AL.getTypeSourceInfo())) + if (CheckTemplateArgument(Param, TSI)) return true; // Add the converted template type argument. - QualType ArgType = Context.getCanonicalType(Arg.getAsType()); + ArgType = Context.getCanonicalType(ArgType); // Objective-C ARC: // If an explicitly-specified template argument type is a lifetime type @@ -3063,7 +3148,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef, Template, Converted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) - return 0; + return nullptr; TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted.data(), Converted.size()); @@ -3239,7 +3324,7 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, if (Arg.isInvalid()) return TemplateArgumentLoc(); - Expr *ArgE = Arg.takeAs<Expr>(); + Expr *ArgE = Arg.getAs<Expr>(); return TemplateArgumentLoc(TemplateArgument(ArgE), ArgE); } @@ -3291,7 +3376,7 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, /// /// \returns true on error, false otherwise. bool Sema::CheckTemplateArgument(NamedDecl *Param, - const TemplateArgumentLoc &Arg, + TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, @@ -3381,21 +3466,20 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, // so it was provided with a template keyword. However, its source // location is not stored in the template argument structure. SourceLocation TemplateKWLoc; - ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context, - SS.getWithLocInContext(Context), - TemplateKWLoc, - NameInfo, 0)); + ExprResult E = DependentScopeDeclRefExpr::Create( + Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo, + nullptr); // If we parsed the template argument as a pack expansion, create a // pack expansion expression. if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){ - E = ActOnPackExpansion(E.take(), Arg.getTemplateEllipsisLoc()); + E = ActOnPackExpansion(E.get(), Arg.getTemplateEllipsisLoc()); if (E.isInvalid()) return true; } TemplateArgument Result; - E = CheckTemplateArgument(NTTP, NTTPType, E.take(), Result); + E = CheckTemplateArgument(NTTP, NTTPType, E.get(), Result); if (E.isInvalid()) return true; @@ -3555,11 +3639,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, - SmallVectorImpl<TemplateArgument> &Converted, - bool *ExpansionIntoFixedList) { - if (ExpansionIntoFixedList) - *ExpansionIntoFixedList = false; - + SmallVectorImpl<TemplateArgument> &Converted) { TemplateParameterList *Params = Template->getTemplateParameters(); SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc(); @@ -3612,6 +3692,20 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, ArgumentPack.size(), Converted)) return true; + if (TemplateArgs[ArgIdx].getArgument().isPackExpansion() && + isa<TypeAliasTemplateDecl>(Template) && + !(Param + 1 == ParamEnd && (*Param)->isTemplateParameterPack() && + !getExpandedPackSize(*Param))) { + // Core issue 1430: we have a pack expansion as an argument to an + // alias template, and it's not part of a final parameter pack. This + // can't be canonicalized, so reject it now. + Diag(TemplateArgs[ArgIdx].getLocation(), + diag::err_alias_template_expansion_into_fixed_list) + << TemplateArgs[ArgIdx].getSourceRange(); + Diag((*Param)->getLocation(), diag::note_template_param_here); + return true; + } + // We're now done with this argument. ++ArgIdx; @@ -3658,9 +3752,6 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, ArgumentPack.data(), ArgumentPack.size())); ArgumentPack.clear(); - } else if (ExpansionIntoFixedList) { - // We have expanded a pack into a fixed list. - *ExpansionIntoFixedList = true; } return false; @@ -3738,7 +3829,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, if (E.isInvalid()) return true; - Expr *Ex = E.takeAs<Expr>(); + Expr *Ex = E.getAs<Expr>(); Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex); } else { TemplateTemplateParmDecl *TempParm @@ -3785,6 +3876,17 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, ++ArgIdx; } + // If we're performing a partial argument substitution, allow any trailing + // pack expansions; they might be empty. This can happen even if + // PartialTemplateArgs is false (the list of arguments is complete but + // still dependent). + if (ArgIdx < NumArgs && CurrentInstantiationScope && + CurrentInstantiationScope->getPartiallySubstitutedPack()) { + while (ArgIdx < NumArgs && + TemplateArgs[ArgIdx].getArgument().isPackExpansion()) + Converted.push_back(TemplateArgs[ArgIdx++].getArgument()); + } + // If we have any leftover arguments, then there were too many arguments. // Complain and fail. if (ArgIdx < NumArgs) @@ -3889,19 +3991,17 @@ bool UnnamedLocalNoLinkageFinder::VisitExtVectorType(const ExtVectorType* T) { bool UnnamedLocalNoLinkageFinder::VisitFunctionProtoType( const FunctionProtoType* T) { - for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(), - AEnd = T->arg_type_end(); - A != AEnd; ++A) { - if (Visit(*A)) + for (const auto &A : T->param_types()) { + if (Visit(A)) return true; } - return Visit(T->getResultType()); + return Visit(T->getReturnType()); } bool UnnamedLocalNoLinkageFinder::VisitFunctionNoProtoType( const FunctionNoProtoType* T) { - return Visit(T->getResultType()); + return Visit(T->getReturnType()); } bool UnnamedLocalNoLinkageFinder::VisitUnresolvedUsingType( @@ -4057,12 +4157,17 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param, // // C++11 allows these, and even in C++03 we allow them as an extension with // a warning. - if (LangOpts.CPlusPlus11 ? - Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_unnamed_type, - SR.getBegin()) != DiagnosticsEngine::Ignored || - Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_local_type, - SR.getBegin()) != DiagnosticsEngine::Ignored : - Arg->hasUnnamedOrLocalType()) { + bool NeedsCheck; + if (LangOpts.CPlusPlus11) + NeedsCheck = + !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_unnamed_type, + SR.getBegin()) || + !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_local_type, + SR.getBegin()); + else + NeedsCheck = Arg->hasUnnamedOrLocalType(); + + if (NeedsCheck) { UnnamedLocalNoLinkageFinder Finder(*this, SR); (void)Finder.Visit(Context.getCanonicalType(Arg)); } @@ -4091,7 +4196,7 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, ExprResult ArgRV = S.DefaultFunctionArrayConversion(Arg); if (ArgRV.isInvalid()) return NPV_Error; - Arg = ArgRV.take(); + Arg = ArgRV.get(); Expr::EvalResult EvalResult; SmallVector<PartialDiagnosticAt, 8> Notes; @@ -4149,10 +4254,9 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, if (Arg->isNullPointerConstant(S.Context, Expr::NPC_NeverValueDependent)) { std::string Code = "static_cast<" + ParamType.getAsString() + ">("; S.Diag(Arg->getExprLoc(), diag::err_template_arg_untyped_null_constant) - << ParamType - << FixItHint::CreateInsertion(Arg->getLocStart(), Code) - << FixItHint::CreateInsertion(S.PP.getLocForEndOfToken(Arg->getLocEnd()), - ")"); + << ParamType << FixItHint::CreateInsertion(Arg->getLocStart(), Code) + << FixItHint::CreateInsertion(S.getLocForEndOfToken(Arg->getLocEnd()), + ")"); S.Diag(Param->getLocation(), diag::note_template_param_here); return NPV_NullPointer; } @@ -4232,22 +4336,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, Expr *Arg = ArgIn; QualType ArgType = Arg->getType(); - // If our parameter has pointer type, check for a null template value. - if (ParamType->isPointerType() || ParamType->isNullPtrType()) { - switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) { - case NPV_NullPointer: - S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); - Converted = TemplateArgument(ParamType, /*isNullPtr*/true); - return false; - - case NPV_Error: - return true; - - case NPV_NotNullPointer: - break; - } - } - bool AddressTaken = false; SourceLocation AddrOpLoc; if (S.getLangOpts().MicrosoftExt) { @@ -4335,6 +4423,33 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, Arg = subst->getReplacement()->IgnoreImpCasts(); } + DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg); + ValueDecl *Entity = DRE ? DRE->getDecl() : nullptr; + + // If our parameter has pointer type, check for a null template value. + if (ParamType->isPointerType() || ParamType->isNullPtrType()) { + NullPointerValueKind NPV; + // dllimport'd entities aren't constant but are available inside of template + // arguments. + if (Entity && Entity->hasAttr<DLLImportAttr>()) + NPV = NPV_NotNullPointer; + else + NPV = isNullPointerValueTemplateArgument(S, Param, ParamType, ArgIn); + switch (NPV) { + case NPV_NullPointer: + S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); + Converted = TemplateArgument(S.Context.getCanonicalType(ParamType), + /*isNullPtr=*/true); + return false; + + case NPV_Error: + return true; + + case NPV_NotNullPointer: + break; + } + } + // Stop checking the precise nature of the argument if it is value dependent, // it should be checked when instantiated. if (Arg->isValueDependent()) { @@ -4351,7 +4466,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, return false; } - DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg); if (!DRE) { S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref) << Arg->getSourceRange(); @@ -4359,8 +4473,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, return true; } - ValueDecl *Entity = DRE->getDecl(); - // Cannot refer to non-static data members if (isa<FieldDecl>(Entity) || isa<IndirectFieldDecl>(Entity)) { S.Diag(Arg->getLocStart(), diag::err_template_arg_field) @@ -4522,7 +4634,10 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S, return true; case NPV_NullPointer: S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); - Converted = TemplateArgument(ParamType, /*isNullPtr*/true); + Converted = TemplateArgument(S.Context.getCanonicalType(ParamType), + /*isNullPtr*/true); + if (S.Context.getTargetInfo().getCXXABI().isMicrosoft()) + S.RequireCompleteType(Arg->getExprLoc(), ParamType, 0); return false; case NPV_NotNullPointer: break; @@ -4533,7 +4648,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S, ParamType.getNonReferenceType(), false, ObjCLifetimeConversion)) { Arg = S.ImpCastExprToType(Arg, ParamType, CK_NoOp, - Arg->getValueKind()).take(); + Arg->getValueKind()).get(); ResultArg = Arg; } else if (!S.Context.hasSameUnqualifiedType(Arg->getType(), ParamType.getNonReferenceType())) { @@ -4554,7 +4669,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S, // template-parameter shall be one of: [...] // // -- a pointer to member expressed as described in 5.3.1. - DeclRefExpr *DRE = 0; + DeclRefExpr *DRE = nullptr; // In C++98/03 mode, give an extension warning on any extra parentheses. // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773 @@ -4581,7 +4696,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S, if (UnOp->getOpcode() == UO_AddrOf) { DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr()); if (DRE && !DRE->getQualifier()) - DRE = 0; + DRE = nullptr; } } // A constant of pointer-to-member type. @@ -4600,7 +4715,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S, } } - DRE = 0; + DRE = nullptr; } if (!DRE) @@ -4654,7 +4769,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) { // FIXME: Produce a cloned, canonical expression? Converted = TemplateArgument(Arg); - return Owned(Arg); + return Arg; } // C++ [temp.arg.nontype]p5: @@ -4698,7 +4813,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // we should be able to diagnose that prior to instantiation. if (Arg->isValueDependent()) { Converted = TemplateArgument(Arg); - return Owned(Arg); + return Arg; } // C++ [temp.arg.nontype]p1: @@ -4731,7 +4846,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, ExprResult ArgResult = DefaultLvalueConversion(Arg); if (ArgResult.isInvalid()) return ExprError(); - Arg = ArgResult.take(); + Arg = ArgResult.get(); QualType ArgType = Arg->getType(); @@ -4756,15 +4871,15 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, public: TmplArgICEDiagnoser(QualType T) : T(T) { } - - virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, - SourceRange SR) { + + void diagnoseNotICE(Sema &S, SourceLocation Loc, + SourceRange SR) override { S.Diag(Loc, diag::err_template_arg_not_ice) << T << SR; } } Diagnoser(ArgType); Arg = VerifyIntegerConstantExpression(Arg, &Value, Diagnoser, - false).take(); + false).get(); if (!Arg) return ExprError(); } @@ -4779,11 +4894,11 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // Okay: no conversion necessary } else if (ParamType->isBooleanType()) { // This is an integral-to-boolean conversion. - Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take(); + Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).get(); } else if (IsIntegralPromotion(Arg, ArgType, ParamType) || !ParamType->isEnumeralType()) { // This is an integral promotion or conversion. - Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take(); + Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).get(); } else { // We can't perform this conversion. Diag(Arg->getLocStart(), @@ -4800,7 +4915,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // The argument is value-dependent. Create a new // TemplateArgument with the converted expression. Converted = TemplateArgument(Arg); - return Owned(Arg); + return Arg; } QualType IntegerType = Context.getCanonicalType(ParamType); @@ -4854,7 +4969,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, ParamType->isEnumeralType() ? Context.getCanonicalType(ParamType) : IntegerType); - return Owned(Arg); + return Arg; } QualType ArgType = Arg->getType(); @@ -4902,13 +5017,13 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, ParamType, Arg, Converted)) return ExprError(); - return Owned(Arg); + return Arg; } if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg, Converted)) return ExprError(); - return Owned(Arg); + return Arg; } if (ParamType->isPointerType()) { @@ -4923,7 +5038,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, ParamType, Arg, Converted)) return ExprError(); - return Owned(Arg); + return Arg; } if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) { @@ -4954,14 +5069,14 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, ParamType, Arg, Converted)) return ExprError(); - return Owned(Arg); + return Arg; } // Deal with parameters of type std::nullptr_t. if (ParamType->isNullPtrType()) { if (Arg->isTypeDependent() || Arg->isValueDependent()) { Converted = TemplateArgument(Arg); - return Owned(Arg); + return Arg; } switch (isNullPointerValueTemplateArgument(*this, Param, ParamType, Arg)) { @@ -4976,8 +5091,9 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, case NPV_NullPointer: Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); - Converted = TemplateArgument(ParamType, /*isNullPtr*/true); - return Owned(Arg); + Converted = TemplateArgument(Context.getCanonicalType(ParamType), + /*isNullPtr*/true); + return Arg; } } @@ -4988,7 +5104,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg, Converted)) return ExprError(); - return Owned(Arg); + return Arg; } /// \brief Check a template argument against its corresponding @@ -4997,7 +5113,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, /// 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, - const TemplateArgumentLoc &Arg, + TemplateArgumentLoc &Arg, unsigned ArgumentPackIndex) { TemplateName Name = Arg.getArgument().getAsTemplateOrTemplatePattern(); TemplateDecl *Template = Name.getAsTemplateDecl(); @@ -5085,7 +5201,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ClassType = Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext())); NestedNameSpecifier *Qualifier - = NestedNameSpecifier::Create(Context, 0, false, + = NestedNameSpecifier::Create(Context, nullptr, false, ClassType.getTypePtr()); CXXScopeSpec SS; SS.MakeTrivial(Context, Qualifier, Loc); @@ -5114,7 +5230,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(), ParamType.getUnqualifiedType(), false, ObjCLifetimeConversion)) - RefExpr = ImpCastExprToType(RefExpr.take(), ParamType.getUnqualifiedType(), CK_NoOp); + RefExpr = ImpCastExprToType(RefExpr.get(), ParamType.getUnqualifiedType(), CK_NoOp); assert(!RefExpr.isInvalid() && Context.hasSameType(((Expr*) RefExpr.get())->getType(), @@ -5134,7 +5250,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, if (T->isFunctionType() || T->isArrayType()) { // Decay functions and arrays. - RefExpr = DefaultFunctionArrayConversion(RefExpr.take()); + RefExpr = DefaultFunctionArrayConversion(RefExpr.get()); if (RefExpr.isInvalid()) return ExprError(); @@ -5211,12 +5327,13 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, if (OrigT->isEnumeralType()) { // FIXME: This is a hack. We need a better way to handle substituted // non-type template parameters. - E = CStyleCastExpr::Create(Context, OrigT, VK_RValue, CK_IntegralCast, E, 0, + E = CStyleCastExpr::Create(Context, OrigT, VK_RValue, CK_IntegralCast, E, + nullptr, Context.getTrivialTypeSourceInfo(OrigT, Loc), Loc, Loc); } - return Owned(E); + return E; } /// \brief Match two template parameters within template parameter lists. @@ -5450,18 +5567,19 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) { (S->getFlags() & Scope::TemplateParamScope) != 0) S = S->getParent(); - // C++ [temp]p2: - // A template-declaration can appear only as a namespace scope or - // class scope declaration. + // C++ [temp]p4: + // A template [...] shall not have C linkage. DeclContext *Ctx = S->getEntity(); - if (Ctx && isa<LinkageSpecDecl>(Ctx) && - cast<LinkageSpecDecl>(Ctx)->getLanguage() != LinkageSpecDecl::lang_cxx) + if (Ctx && Ctx->isExternCContext()) return Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage) << TemplateParams->getSourceRange(); while (Ctx && isa<LinkageSpecDecl>(Ctx)) Ctx = Ctx->getParent(); + // C++ [temp]p2: + // A template-declaration can appear only as a namespace scope or + // class scope declaration. if (Ctx) { if (Ctx->isFileContext()) return false; @@ -5598,13 +5716,37 @@ static bool CheckTemplateSpecializationScope(Sema &S, // A class template partial specialization may be declared or redeclared // in any namespace scope in which its definition may be defined (14.5.1 // and 14.5.2). - bool ComplainedAboutScope = false; - DeclContext *SpecializedContext + DeclContext *SpecializedContext = Specialized->getDeclContext()->getEnclosingNamespaceContext(); DeclContext *DC = S.CurContext->getEnclosingNamespaceContext(); - if ((!PrevDecl || - getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared || - getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){ + + // Make sure that this redeclaration (or definition) occurs in an enclosing + // namespace. + // Note that HandleDeclarator() performs this check for explicit + // specializations of function templates, static data members, and member + // functions, so we skip the check here for those kinds of entities. + // FIXME: HandleDeclarator's diagnostics aren't quite as good, though. + // Should we refactor that check, so that it occurs later? + if (!DC->Encloses(SpecializedContext) && + !(isa<FunctionTemplateDecl>(Specialized) || + isa<FunctionDecl>(Specialized) || + isa<VarTemplateDecl>(Specialized) || + isa<VarDecl>(Specialized))) { + if (isa<TranslationUnitDecl>(SpecializedContext)) + S.Diag(Loc, diag::err_template_spec_redecl_global_scope) + << EntityKind << Specialized; + else if (isa<NamespaceDecl>(SpecializedContext)) + S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope) + << EntityKind << Specialized + << cast<NamedDecl>(SpecializedContext); + else + llvm_unreachable("unexpected namespace context for specialization"); + + S.Diag(Specialized->getLocation(), diag::note_specialized_entity); + } else if ((!PrevDecl || + getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared || + getTemplateSpecializationKind(PrevDecl) == + TSK_ImplicitInstantiation)) { // C++ [temp.exp.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 @@ -5613,9 +5755,12 @@ static bool CheckTemplateSpecializationScope(Sema &S, // static data member of a class template shall be declared in the // namespace of which the class template is a member. // - // C++0x [temp.expl.spec]p2: + // C++11 [temp.expl.spec]p2: // An explicit specialization shall be declared in a namespace enclosing // the specialized template. + // C++11 [temp.explicit]p3: + // An explicit instantiation shall appear in an enclosing namespace of its + // template. if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) { bool IsCPlusPlus11Extension = DC->Encloses(SpecializedContext); if (isa<TranslationUnitDecl>(SpecializedContext)) { @@ -5636,46 +5781,42 @@ static bool CheckTemplateSpecializationScope(Sema &S, } S.Diag(Specialized->getLocation(), diag::note_specialized_entity); - ComplainedAboutScope = - !(IsCPlusPlus11Extension && S.getLangOpts().CPlusPlus11); } } - // Make sure that this redeclaration (or definition) occurs in an enclosing - // namespace. - // Note that HandleDeclarator() performs this check for explicit - // specializations of function templates, static data members, and member - // functions, so we skip the check here for those kinds of entities. - // FIXME: HandleDeclarator's diagnostics aren't quite as good, though. - // Should we refactor that check, so that it occurs later? - if (!ComplainedAboutScope && !DC->Encloses(SpecializedContext) && - !(isa<FunctionTemplateDecl>(Specialized) || isa<VarDecl>(Specialized) || - isa<FunctionDecl>(Specialized))) { - if (isa<TranslationUnitDecl>(SpecializedContext)) - S.Diag(Loc, diag::err_template_spec_redecl_global_scope) - << EntityKind << Specialized; - else if (isa<NamespaceDecl>(SpecializedContext)) - S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope) - << EntityKind << Specialized - << cast<NamedDecl>(SpecializedContext); - - S.Diag(Specialized->getLocation(), diag::note_specialized_entity); - } + return false; +} - // FIXME: check for specialization-after-instantiation errors and such. +static SourceRange findTemplateParameter(unsigned Depth, Expr *E) { + if (!E->isInstantiationDependent()) + return SourceLocation(); + DependencyChecker Checker(Depth); + Checker.TraverseStmt(E); + if (Checker.Match && Checker.MatchLoc.isInvalid()) + return E->getSourceRange(); + return Checker.MatchLoc; +} - return false; +static SourceRange findTemplateParameter(unsigned Depth, TypeLoc TL) { + if (!TL.getType()->isDependentType()) + return SourceLocation(); + DependencyChecker Checker(Depth); + Checker.TraverseTypeLoc(TL); + if (Checker.Match && Checker.MatchLoc.isInvalid()) + return TL.getSourceRange(); + return Checker.MatchLoc; } /// \brief Subroutine of Sema::CheckTemplatePartialSpecializationArgs /// that checks non-type template partial specialization arguments. static bool CheckNonTypeTemplatePartialSpecializationArgs( - Sema &S, NonTypeTemplateParmDecl *Param, const TemplateArgument *Args, - unsigned NumArgs) { + Sema &S, SourceLocation TemplateNameLoc, NonTypeTemplateParmDecl *Param, + const TemplateArgument *Args, unsigned NumArgs, bool IsDefaultArgument) { for (unsigned I = 0; I != NumArgs; ++I) { if (Args[I].getKind() == TemplateArgument::Pack) { if (CheckNonTypeTemplatePartialSpecializationArgs( - S, Param, Args[I].pack_begin(), Args[I].pack_size())) + S, TemplateNameLoc, Param, Args[I].pack_begin(), + Args[I].pack_size(), IsDefaultArgument)) return true; continue; @@ -5713,22 +5854,43 @@ static bool CheckNonTypeTemplatePartialSpecializationArgs( // shall not involve a template parameter of the partial // specialization except when the argument expression is a // simple identifier. - if (ArgExpr->isTypeDependent() || ArgExpr->isValueDependent()) { - S.Diag(ArgExpr->getLocStart(), - diag::err_dependent_non_type_arg_in_partial_spec) - << ArgExpr->getSourceRange(); + SourceRange ParamUseRange = + findTemplateParameter(Param->getDepth(), ArgExpr); + if (ParamUseRange.isValid()) { + if (IsDefaultArgument) { + S.Diag(TemplateNameLoc, + diag::err_dependent_non_type_arg_in_partial_spec); + S.Diag(ParamUseRange.getBegin(), + diag::note_dependent_non_type_default_arg_in_partial_spec) + << ParamUseRange; + } else { + S.Diag(ParamUseRange.getBegin(), + diag::err_dependent_non_type_arg_in_partial_spec) + << ParamUseRange; + } 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()) { - S.Diag(ArgExpr->getLocStart(), - diag::err_dependent_typed_non_type_arg_in_partial_spec) - << Param->getType() - << ArgExpr->getSourceRange(); - S.Diag(Param->getLocation(), diag::note_template_param_here); + // + // FIXME: We need to delay this check until instantiation in some cases: + // + // template<template<typename> class X> struct A { + // template<typename T, X<T> N> struct B; + // template<typename T> struct B<T, 0>; + // }; + // template<typename> using X = int; + // A<X>::B<int, 0> b; + ParamUseRange = findTemplateParameter( + Param->getDepth(), Param->getTypeSourceInfo()->getTypeLoc()); + if (ParamUseRange.isValid()) { + S.Diag(IsDefaultArgument ? TemplateNameLoc : ArgExpr->getLocStart(), + diag::err_dependent_typed_non_type_arg_in_partial_spec) + << Param->getType() << ParamUseRange; + S.Diag(Param->getLocation(), diag::note_template_param_here) + << (IsDefaultArgument ? ParamUseRange : SourceRange()); return true; } } @@ -5739,15 +5901,17 @@ static bool CheckNonTypeTemplatePartialSpecializationArgs( /// \brief Check the non-type template arguments of a class template /// partial specialization according to C++ [temp.class.spec]p9. /// +/// \param TemplateNameLoc the location of the template name. /// \param TemplateParams the template parameters of the primary class -/// template. -/// +/// template. +/// \param NumExplicit the number of explicitly-specified template arguments. /// \param TemplateArgs the template arguments of the class template -/// partial specialization. +/// partial specialization. /// -/// \returns true if there was an error, false otherwise. +/// \returns \c true if there was an error, \c false otherwise. static bool CheckTemplatePartialSpecializationArgs( - Sema &S, TemplateParameterList *TemplateParams, + Sema &S, SourceLocation TemplateNameLoc, + TemplateParameterList *TemplateParams, unsigned NumExplicit, SmallVectorImpl<TemplateArgument> &TemplateArgs) { const TemplateArgument *ArgList = TemplateArgs.data(); @@ -5757,7 +5921,8 @@ static bool CheckTemplatePartialSpecializationArgs( if (!Param) continue; - if (CheckNonTypeTemplatePartialSpecializationArgs(S, Param, &ArgList[I], 1)) + if (CheckNonTypeTemplatePartialSpecializationArgs( + S, TemplateNameLoc, Param, &ArgList[I], 1, I >= NumExplicit)) return true; } @@ -5769,23 +5934,23 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, SourceLocation ModulePrivateLoc, - CXXScopeSpec &SS, - TemplateTy TemplateD, - SourceLocation TemplateNameLoc, - SourceLocation LAngleLoc, - ASTTemplateArgsPtr TemplateArgsIn, - SourceLocation RAngleLoc, + TemplateIdAnnotation &TemplateId, AttributeList *Attr, MultiTemplateParamsArg TemplateParameterLists) { assert(TUK != TUK_Reference && "References are not specializations"); + CXXScopeSpec &SS = TemplateId.SS; + // NOTE: KWLoc is the location of the tag keyword. This will instead // store the location of the outermost template keyword in the declaration. SourceLocation TemplateKWLoc = TemplateParameterLists.size() > 0 - ? TemplateParameterLists[0]->getTemplateLoc() : SourceLocation(); + ? TemplateParameterLists[0]->getTemplateLoc() : KWLoc; + SourceLocation TemplateNameLoc = TemplateId.TemplateNameLoc; + SourceLocation LAngleLoc = TemplateId.LAngleLoc; + SourceLocation RAngleLoc = TemplateId.RAngleLoc; // Find the class template we're specializing - TemplateName Name = TemplateD.get(); + TemplateName Name = TemplateId.Template.get(); ClassTemplateDecl *ClassTemplate = dyn_cast_or_null<ClassTemplateDecl>(Name.getAsTemplateDecl()); @@ -5806,8 +5971,9 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, bool Invalid = false; TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( - TemplateNameLoc, TemplateNameLoc, SS, TemplateParameterLists, - TUK == TUK_Friend, isExplicitSpecialization, Invalid); + KWLoc, TemplateNameLoc, SS, &TemplateId, + TemplateParameterLists, TUK == TUK_Friend, isExplicitSpecialization, + Invalid); if (Invalid) return true; @@ -5858,11 +6024,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, << SourceRange(LAngleLoc, RAngleLoc); else isExplicitSpecialization = true; - } else if (TUK != TUK_Friend) { - Diag(KWLoc, diag::err_template_spec_needs_header) - << FixItHint::CreateInsertion(KWLoc, "template<> "); - TemplateKWLoc = KWLoc; - isExplicitSpecialization = true; + } else { + assert(TUK == TUK_Friend && "should have a 'template<>' for this decl"); } // Check that the specialization uses the same tag kind as the @@ -5882,10 +6045,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, } // Translate the parser's template argument list in our AST format. - TemplateArgumentListInfo TemplateArgs; - TemplateArgs.setLAngleLoc(LAngleLoc); - TemplateArgs.setRAngleLoc(RAngleLoc); - translateTemplateArguments(TemplateArgsIn, TemplateArgs); + TemplateArgumentListInfo TemplateArgs = + makeTemplateArgumentListInfo(*this, TemplateId); // Check for unexpanded parameter packs in any of the template arguments. for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) @@ -5904,7 +6065,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // corresponds to these arguments. if (isPartialSpecialization) { if (CheckTemplatePartialSpecializationArgs( - *this, ClassTemplate->getTemplateParameters(), Converted)) + *this, TemplateNameLoc, ClassTemplate->getTemplateParameters(), + TemplateArgs.size(), Converted)) return true; bool InstantiationDependent; @@ -5919,21 +6081,16 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, } } - void *InsertPos = 0; - ClassTemplateSpecializationDecl *PrevDecl = 0; + void *InsertPos = nullptr; + ClassTemplateSpecializationDecl *PrevDecl = nullptr; if (isPartialSpecialization) // FIXME: Template parameter list matters, too - PrevDecl - = ClassTemplate->findPartialSpecialization(Converted.data(), - Converted.size(), - InsertPos); + PrevDecl = ClassTemplate->findPartialSpecialization(Converted, InsertPos); else - PrevDecl - = ClassTemplate->findSpecialization(Converted.data(), - Converted.size(), InsertPos); + PrevDecl = ClassTemplate->findSpecialization(Converted, InsertPos); - ClassTemplateSpecializationDecl *Specialization = 0; + ClassTemplateSpecializationDecl *Specialization = nullptr; // Check whether we can declare a class template specialization in // the current scope. @@ -5945,24 +6102,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // The canonical type QualType CanonType; - if (PrevDecl && - (PrevDecl->getSpecializationKind() == TSK_Undeclared || - TUK == TUK_Friend)) { - // Since the only prior class template specialization with these - // arguments was referenced but not declared, or we're only - // referencing this specialization as a friend, reuse that - // declaration node as our own, updating its source location and - // the list of outer template parameters to reflect our new declaration. - Specialization = PrevDecl; - Specialization->setLocation(TemplateNameLoc); - if (TemplateParameterLists.size() > 0) { - Specialization->setTemplateParameterListsInfo(Context, - TemplateParameterLists.size(), - TemplateParameterLists.data()); - } - PrevDecl = 0; - CanonType = Context.getTypeDeclType(Specialization); - } else if (isPartialSpecialization) { + if (isPartialSpecialization) { // Build the canonical type that describes the converted template // arguments of the class template partial specialization. TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name); @@ -5985,6 +6125,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, Attr, TemplateParams, AS_none, /*ModulePrivateLoc=*/SourceLocation(), + /*FriendLoc*/SourceLocation(), TemplateParameterLists.size() - 1, TemplateParameterLists.data()); } @@ -6043,7 +6184,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, else Diag(Param->getLocation(), diag::note_partial_spec_unused_parameter) - << "<anonymous>"; + << "(anonymous)"; } } } @@ -6187,7 +6328,7 @@ Decl *Sema::ActOnTemplateDeclarator(Scope *S, Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, MultiTemplateParamsArg TemplateParameterLists, Declarator &D) { - assert(getCurFunctionDecl() == 0 && "Function parsing confused"); + assert(getCurFunctionDecl() == nullptr && "Function parsing confused"); DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); if (FTI.hasPrototype) { @@ -6210,10 +6351,8 @@ static void StripImplicitInstantiation(NamedDecl *D) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { FD->setInlineSpecified(false); - for (FunctionDecl::param_iterator I = FD->param_begin(), - E = FD->param_end(); - I != E; ++I) - (*I)->dropAttrs(); + for (auto I : FD->params()) + I->dropAttrs(); } } @@ -6407,8 +6546,12 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // For a given template and a given set of template-arguments, // - an explicit instantiation definition shall appear at most once // in a program, - Diag(NewLoc, diag::err_explicit_instantiation_duplicate) - << PrevDecl; + + // MSVCCompat: MSVC silently ignores duplicate explicit instantiations. + Diag(NewLoc, (getLangOpts().MSVCCompat) + ? diag::ext_explicit_instantiation_duplicate + : diag::err_explicit_instantiation_duplicate) + << PrevDecl; Diag(DiagLocForExplicitInstantiation(PrevDecl, PrevPointOfInstantiation), diag::note_previous_explicit_instantiation); HasNoEffect = true; @@ -6509,8 +6652,8 @@ bool Sema::CheckFunctionTemplateSpecialization( const FunctionProtoType *FPT = FT->castAs<FunctionProtoType>(); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.TypeQuals |= Qualifiers::Const; - FT = Context.getFunctionType(FPT->getResultType(), FPT->getArgTypes(), - EPI); + FT = Context.getFunctionType(FPT->getReturnType(), + FPT->getParamTypes(), EPI); } } @@ -6522,7 +6665,7 @@ bool Sema::CheckFunctionTemplateSpecialization( // specializing this template. // FIXME: It is somewhat wasteful to build TemplateDeductionInfo Info(FailedCandidates.getLocation()); - FunctionDecl *Specialization = 0; + FunctionDecl *Specialization = nullptr; if (TemplateDeductionResult TDK = DeduceTemplateArguments( cast<FunctionTemplateDecl>(FunTmpl->getFirstDecl()), ExplicitTemplateArgs, FT, Specialization, Info)) { @@ -6546,7 +6689,7 @@ bool Sema::CheckFunctionTemplateSpecialization( FD->getLocation(), PDiag(diag::err_function_template_spec_no_match) << FD->getDeclName(), PDiag(diag::err_function_template_spec_ambiguous) - << FD->getDeclName() << (ExplicitTemplateArgs != 0), + << FD->getDeclName() << (ExplicitTemplateArgs != nullptr), PDiag(diag::note_function_template_spec_matched)); if (Result == Candidates.end()) @@ -6615,7 +6758,7 @@ bool Sema::CheckFunctionTemplateSpecialization( const TemplateArgumentList* TemplArgs = new (Context) TemplateArgumentList(Specialization->getTemplateSpecializationArgs()); FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(), - TemplArgs, /*InsertPos=*/0, + TemplArgs, /*InsertPos=*/nullptr, SpecInfo->getTemplateSpecializationKind(), ExplicitTemplateArgs); @@ -6645,9 +6788,9 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { assert(!isa<TemplateDecl>(Member) && "Only for non-template members"); // Try to find the member we are instantiating. - NamedDecl *Instantiation = 0; - NamedDecl *InstantiatedFrom = 0; - MemberSpecializationInfo *MSInfo = 0; + NamedDecl *Instantiation = nullptr; + NamedDecl *InstantiatedFrom = nullptr; + MemberSpecializationInfo *MSInfo = nullptr; if (Previous.empty()) { // Nowhere to look anyway. @@ -6656,7 +6799,10 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { I != E; ++I) { NamedDecl *D = (*I)->getUnderlyingDecl(); if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { - if (Context.hasSameType(Function->getType(), Method->getType())) { + QualType Adjusted = Function->getType(); + if (!hasExplicitCallingConv(Adjusted)) + Adjusted = adjustCCAndNoReturn(Adjusted, Method->getType()); + if (Context.hasSameType(Adjusted, Method->getType())) { Instantiation = Method; InstantiatedFrom = Method->getInstantiatedFromMemberFunction(); MSInfo = Method->getMemberSpecializationInfo(); @@ -6877,8 +7023,8 @@ static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) { // name shall be a simple-template-id. // // C++98 has the same restriction, just worded differently. - for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep(); - NNS; NNS = NNS->getPrefix()) + for (NestedNameSpecifier *NNS = SS.getScopeRep(); NNS; + NNS = NNS->getPrefix()) if (const Type *T = NNS->getAsType()) if (isa<TemplateSpecializationType>(T)) return true; @@ -6951,10 +7097,9 @@ Sema::ActOnExplicitInstantiation(Scope *S, // Find the class template specialization declaration that // corresponds to these arguments. - void *InsertPos = 0; + void *InsertPos = nullptr; ClassTemplateSpecializationDecl *PrevDecl - = ClassTemplate->findSpecialization(Converted.data(), - Converted.size(), InsertPos); + = ClassTemplate->findSpecialization(Converted, InsertPos); TemplateSpecializationKind PrevDecl_TSK = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared; @@ -6968,7 +7113,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SS.isSet())) return true; - ClassTemplateSpecializationDecl *Specialization = 0; + ClassTemplateSpecializationDecl *Specialization = nullptr; bool HasNoEffect = false; if (PrevDecl) { @@ -6990,7 +7135,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, // (Other source locations will be updated later.) Specialization = PrevDecl; Specialization->setLocation(TemplateNameLoc); - PrevDecl = 0; + PrevDecl = nullptr; } } @@ -7074,6 +7219,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, // TSK_ExplicitInstantiationDefinition if (Old_TSK == TSK_ExplicitInstantiationDeclaration && TSK == TSK_ExplicitInstantiationDefinition) + // FIXME: Need to notify the ASTMutationListener that we did this. Def->setTemplateSpecializationKind(TSK); InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK); @@ -7102,7 +7248,8 @@ Sema::ActOnExplicitInstantiation(Scope *S, KWLoc, SS, Name, NameLoc, Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned, IsDependent, - SourceLocation(), false, TypeResult()); + SourceLocation(), false, TypeResult(), + /*IsTypeSpecifier*/false); assert(!IsDependent && "explicit instantiation of dependent name not yet handled"); if (!TagD) @@ -7342,13 +7489,8 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, } // Translate the parser's template argument list into our AST format. - TemplateArgumentListInfo TemplateArgs; - TemplateIdAnnotation *TemplateId = D.getName().TemplateId; - TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc); - TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc); - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), - TemplateId->NumArgs); - translateTemplateArguments(TemplateArgsPtr, TemplateArgs); + TemplateArgumentListInfo TemplateArgs = + makeTemplateArgumentListInfo(*this, *D.getName().TemplateId); DeclResult Res = CheckVarTemplateId(PrevTemplate, TemplateLoc, D.getIdentifierLoc(), TemplateArgs); @@ -7410,7 +7552,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, } // FIXME: Create an ExplicitInstantiation node? - return (Decl*) 0; + return (Decl*) nullptr; } // If the declarator is a template-id, translate the parser's template @@ -7418,12 +7560,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, bool HasExplicitTemplateArgs = false; TemplateArgumentListInfo TemplateArgs; if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { - TemplateIdAnnotation *TemplateId = D.getName().TemplateId; - TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc); - TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc); - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), - TemplateId->NumArgs); - translateTemplateArguments(TemplateArgsPtr, TemplateArgs); + TemplateArgs = makeTemplateArgumentListInfo(*this, *D.getName().TemplateId); HasExplicitTemplateArgs = true; } @@ -7455,10 +7592,11 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, continue; TemplateDeductionInfo Info(FailedCandidates.getLocation()); - FunctionDecl *Specialization = 0; + FunctionDecl *Specialization = nullptr; if (TemplateDeductionResult TDK = DeduceTemplateArguments(FunTmpl, - (HasExplicitTemplateArgs ? &TemplateArgs : 0), + (HasExplicitTemplateArgs ? &TemplateArgs + : nullptr), R, Specialization, Info)) { // Keep track of almost-matches. FailedCandidates.addCandidate() @@ -7511,7 +7649,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, // FIXME: We may still want to build some representation of this // explicit specialization. if (HasNoEffect) - return (Decl*) 0; + return (Decl*) nullptr; } Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); @@ -7519,7 +7657,11 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, if (Attr) ProcessDeclAttributeList(S, Specialization, Attr); - if (TSK == TSK_ExplicitInstantiationDefinition) + if (Specialization->isDefined()) { + // Let the ASTConsumer know that this function has been explicitly + // instantiated now, and its linkage might have changed. + Consumer.HandleTopLevelDecl(DeclGroupRef(Specialization)); + } else if (TSK == TSK_ExplicitInstantiationDefinition) InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization); // C++0x [temp.explicit]p2: @@ -7544,7 +7686,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, D.getCXXScopeSpec().isSet()); // FIXME: Create some kind of ExplicitInstantiationDecl here. - return (Decl*) 0; + return (Decl*) nullptr; } TypeResult @@ -7554,8 +7696,7 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // This has to hold, because SS is expected to be defined. assert(Name && "Expected a name in a dependent tag"); - NestedNameSpecifier *NNS - = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); + NestedNameSpecifier *NNS = SS.getScopeRep(); if (!NNS) return true; @@ -7641,8 +7782,7 @@ Sema::ActOnTypenameType(Scope *S, if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { // Construct a dependent template specialization type. assert(DTN && "dependent template has non-dependent name?"); - assert(DTN->getQualifier() - == static_cast<NestedNameSpecifier*>(SS.getScopeRep())); + assert(DTN->getQualifier() == SS.getScopeRep()); QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename, DTN->getQualifier(), DTN->getIdentifier(), @@ -7758,7 +7898,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, LookupResult Result(*this, Name, IILoc, LookupOrdinaryName); LookupQualifiedName(Result, Ctx); unsigned DiagID = 0; - Decl *Referenced = 0; + Decl *Referenced = nullptr; switch (Result.getResultKind()) { case LookupResult::NotFound: { // If we're looking up 'type' within a template named 'enable_if', produce |