diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp | 1265 |
1 files changed, 820 insertions, 445 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp index 8dda34c..ff8c4da 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp @@ -26,6 +26,8 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/PartialDiagnostic.h" +#include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" using namespace clang; using namespace sema; @@ -42,11 +44,16 @@ clang::getTemplateParamsRange(TemplateParameterList const * const *Ps, /// of a template and, if so, return that template declaration. Otherwise, /// returns NULL. static NamedDecl *isAcceptableTemplateName(ASTContext &Context, - NamedDecl *Orig) { + NamedDecl *Orig, + bool AllowFunctionTemplates) { NamedDecl *D = Orig->getUnderlyingDecl(); - if (isa<TemplateDecl>(D)) + if (isa<TemplateDecl>(D)) { + if (!AllowFunctionTemplates && isa<FunctionTemplateDecl>(D)) + return 0; + return Orig; + } if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { // C++ [temp.local]p1: @@ -76,13 +83,15 @@ static NamedDecl *isAcceptableTemplateName(ASTContext &Context, return 0; } -void Sema::FilterAcceptableTemplateNames(LookupResult &R) { +void Sema::FilterAcceptableTemplateNames(LookupResult &R, + bool AllowFunctionTemplates) { // The set of class templates we've already seen. llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates; LookupResult::Filter filter = R.makeFilter(); while (filter.hasNext()) { NamedDecl *Orig = filter.next(); - NamedDecl *Repl = isAcceptableTemplateName(Context, Orig); + NamedDecl *Repl = isAcceptableTemplateName(Context, Orig, + AllowFunctionTemplates); if (!Repl) filter.erase(); else if (Repl != Orig) { @@ -112,9 +121,10 @@ void Sema::FilterAcceptableTemplateNames(LookupResult &R) { filter.done(); } -bool Sema::hasAnyAcceptableTemplateNames(LookupResult &R) { +bool Sema::hasAnyAcceptableTemplateNames(LookupResult &R, + bool AllowFunctionTemplates) { for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) - if (isAcceptableTemplateName(Context, *I)) + if (isAcceptableTemplateName(Context, *I, AllowFunctionTemplates)) return true; return false; @@ -128,7 +138,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S, bool EnteringContext, TemplateTy &TemplateResult, bool &MemberOfUnknownSpecialization) { - assert(getLangOptions().CPlusPlus && "No template names in C!"); + assert(getLangOpts().CPlusPlus && "No template names in C!"); DeclarationName TName; MemberOfUnknownSpecialization = false; @@ -153,8 +163,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S, QualType ObjectType = ObjectTypePtr.get(); - LookupResult R(*this, TName, Name.getSourceRange().getBegin(), - LookupOrdinaryName); + LookupResult R(*this, TName, Name.getLocStart(), LookupOrdinaryName); LookupTemplateName(R, S, SS, ObjectType, EnteringContext, MemberOfUnknownSpecialization); if (R.empty()) return TNK_Non_template; @@ -249,6 +258,12 @@ void Sema::LookupTemplateName(LookupResult &Found, isDependent = ObjectType->isDependentType(); assert((isDependent || !ObjectType->isIncompleteType()) && "Caller should have completed object type"); + + // Template names cannot appear inside an Objective-C class or object type. + if (ObjectType->isObjCObjectOrInterfaceType()) { + Found.clear(); + return; + } } else if (SS.isSet()) { // This nested-name-specifier occurs after another nested-name-specifier, // so long into the context associated with the prior nested-name-specifier. @@ -261,13 +276,13 @@ void Sema::LookupTemplateName(LookupResult &Found, } bool ObjectTypeSearchedInScope = false; + bool AllowFunctionTemplatesInLookup = true; if (LookupCtx) { // Perform "qualified" name lookup into the declaration context we // computed, which is either the type of the base of a member access // expression or the declaration context associated with a prior // nested-name-specifier. LookupQualifiedName(Found, LookupCtx); - if (!ObjectType.isNull() && Found.empty()) { // C++ [basic.lookup.classref]p1: // In a class member access expression (5.2.5), if the . or -> token is @@ -280,6 +295,7 @@ void Sema::LookupTemplateName(LookupResult &Found, // or function template. if (S) LookupName(Found, S); ObjectTypeSearchedInScope = true; + AllowFunctionTemplatesInLookup = false; } } else if (isDependent && (!S || ObjectType.isNull())) { // We cannot look into a dependent object type or nested nme @@ -289,23 +305,31 @@ void Sema::LookupTemplateName(LookupResult &Found, } else { // Perform unqualified name lookup in the current scope. LookupName(Found, S); + + if (!ObjectType.isNull()) + AllowFunctionTemplatesInLookup = false; } if (Found.empty() && !isDependent) { // If we did not find any names, attempt to correct any typos. DeclarationName Name = Found.getLookupName(); Found.clear(); + // Simple filter callback that, for keywords, only accepts the C++ *_cast + CorrectionCandidateCallback FilterCCC; + FilterCCC.WantTypeSpecifiers = false; + FilterCCC.WantExpressionKeywords = false; + FilterCCC.WantRemainingKeywords = false; + FilterCCC.WantCXXNamedCasts = true; if (TypoCorrection Corrected = CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, - LookupCtx, false, - CTC_CXXCasts)) { + FilterCCC, LookupCtx)) { Found.setLookupName(Corrected.getCorrection()); if (Corrected.getCorrectionDecl()) Found.addDecl(Corrected.getCorrectionDecl()); FilterAcceptableTemplateNames(Found); if (!Found.empty()) { - std::string CorrectedStr(Corrected.getAsString(getLangOptions())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions())); + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); if (LookupCtx) Diag(Found.getNameLoc(), diag::err_no_member_template_suggest) << Name << LookupCtx << CorrectedQuotedStr << SS.getRange() @@ -323,7 +347,7 @@ void Sema::LookupTemplateName(LookupResult &Found, } } - FilterAcceptableTemplateNames(Found); + FilterAcceptableTemplateNames(Found, AllowFunctionTemplatesInLookup); if (Found.empty()) { if (isDependent) MemberOfUnknownSpecialization = true; @@ -339,7 +363,7 @@ void Sema::LookupTemplateName(LookupResult &Found, LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(), LookupOrdinaryName); LookupName(FoundOuter, S); - FilterAcceptableTemplateNames(FoundOuter); + FilterAcceptableTemplateNames(FoundOuter, /*AllowFunctionTemplates=*/false); if (FoundOuter.empty()) { // - if the name is not found, the name found in the class of the @@ -379,6 +403,7 @@ void Sema::LookupTemplateName(LookupResult &Found, /// specifier naming a dependent type. ExprResult Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool isAddressOfOperand, const TemplateArgumentListInfo *TemplateArgs) { @@ -398,20 +423,23 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, /*IsArrow*/ true, /*Op*/ SourceLocation(), SS.getWithLocInContext(Context), + TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs)); } - return BuildDependentDeclRefExpr(SS, NameInfo, TemplateArgs); + return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs); } ExprResult Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { return Owned(DependentScopeDeclRefExpr::Create(Context, SS.getWithLocInContext(Context), + TemplateKWLoc, NameInfo, TemplateArgs)); } @@ -420,12 +448,12 @@ Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS, /// 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) { +void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) { assert(PrevDecl->isTemplateParameter() && "Not a template parameter"); // Microsoft Visual C++ permits template parameters to be shadowed. - if (getLangOptions().MicrosoftExt) - return false; + if (getLangOpts().MicrosoftExt) + return; // C++ [temp.local]p4: // A template-parameter shall not be redeclared within its @@ -433,7 +461,7 @@ bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) { Diag(Loc, diag::err_template_param_shadow) << cast<NamedDecl>(PrevDecl)->getDeclName(); Diag(PrevDecl->getLocation(), diag::note_template_param_here); - return true; + return; } /// AdjustDeclIfTemplate - If the given decl happens to be a template, reset @@ -491,7 +519,6 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef, } llvm_unreachable("Unhandled parsed template argument"); - return TemplateArgumentLoc(); } /// \brief Translates template arguments as provided by the parser @@ -528,9 +555,10 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, NamedDecl *PrevDecl = LookupSingleName(S, ParamName, ParamNameLoc, LookupOrdinaryName, ForRedeclaration); - if (PrevDecl && PrevDecl->isTemplateParameter()) - Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc, - PrevDecl); + if (PrevDecl && PrevDecl->isTemplateParameter()) { + DiagnoseTemplateParameterShadow(ParamNameLoc, PrevDecl); + PrevDecl = 0; + } } SourceLocation Loc = ParamNameLoc; @@ -615,8 +643,12 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) { T->isNullPtrType() || // 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; + T->isDependentType()) { + // C++ [temp.param]p5: The top-level cv-qualifiers on the template-parameter + // are ignored when determining its type. + return T.getUnqualifiedType(); + } + // C++ [temp.param]p8: // // A non-type template-parameter of type "array of T" or @@ -652,9 +684,10 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, NamedDecl *PrevDecl = LookupSingleName(S, ParamName, D.getIdentifierLoc(), LookupOrdinaryName, ForRedeclaration); - if (PrevDecl && PrevDecl->isTemplateParameter()) - Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), - PrevDecl); + if (PrevDecl && PrevDecl->isTemplateParameter()) { + DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); + PrevDecl = 0; + } } T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc()); @@ -666,7 +699,7 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, bool IsParameterPack = D.hasEllipsis(); NonTypeTemplateParmDecl *Param = NonTypeTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(), - D.getSourceRange().getBegin(), + D.getLocStart(), D.getIdentifierLoc(), Depth, Position, ParamName, T, IsParameterPack, TInfo); @@ -839,7 +872,12 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, if (SS.isNotEmpty() && !SS.isInvalid()) { SemanticContext = computeDeclContext(SS, true); if (!SemanticContext) { - // FIXME: Produce a reasonable diagnostic here + // FIXME: Horrible, horrible hack! We can't currently represent this + // in the AST, and historically we have just ignored such friend + // class templates, so don't complain here. + if (TUK != TUK_Friend) + Diag(NameLoc, diag::err_template_qualified_declarator_no_match) + << SS.getScopeRep() << SS.getRange(); return true; } @@ -853,7 +891,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, ContextRAII SavedContext(*this, SemanticContext); if (RebuildTemplateParamsInCurrentInstantiation(TemplateParams)) Invalid = true; - } + } else if (TUK != TUK_Friend && TUK != TUK_Reference) + diagnoseQualifiedDeclaration(SS, SemanticContext, Name, NameLoc); LookupQualifiedName(Previous, SemanticContext); } else { @@ -987,9 +1026,11 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // If the name of the template was qualified, we must be defining the // template out-of-line. if (!SS.isInvalid() && !Invalid && !PrevClassTemplate && - !(TUK == TUK_Friend && CurContext->isDependentContext())) + !(TUK == TUK_Friend && CurContext->isDependentContext())) { Diag(NameLoc, diag::err_member_def_does_not_match) << Name << SemanticContext << SS.getRange(); + Invalid = true; + } } CXXRecordDecl *NewClass = @@ -1003,21 +1044,19 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, NumOuterTemplateParamLists, OuterTemplateParamLists); + // Add alignment attributes if necessary; these attributes are checked when + // the ASTContext lays out the structure. + AddAlignmentAttributesForRecord(NewClass); + AddMsStructLayoutForRecord(NewClass); + ClassTemplateDecl *NewTemplate = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc, DeclarationName(Name), TemplateParams, NewClass, PrevClassTemplate); NewClass->setDescribedClassTemplate(NewTemplate); - if (PrevClassTemplate && PrevClassTemplate->isModulePrivate()) { + if (ModulePrivateLoc.isValid()) NewTemplate->setModulePrivate(); - } else if (ModulePrivateLoc.isValid()) { - if (PrevClassTemplate && !PrevClassTemplate->isModulePrivate()) - diagnoseModulePrivateRedeclaration(NewTemplate, PrevClassTemplate, - ModulePrivateLoc); - else - NewTemplate->setModulePrivate(); - } // Build the type for the class template declaration now. QualType T = NewTemplate->getInjectedClassNameSpecialization(); @@ -1032,7 +1071,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, PrevClassTemplate->setMemberSpecialization(); // Set the access specifier. - if (!Invalid && TUK != TUK_Friend) + if (!Invalid && TUK != TUK_Friend && NewTemplate->getDeclContext()->isRecord()) SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS); // Set the lexical context of these templates @@ -1059,7 +1098,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // Friend templates are visible in fairly strange ways. if (!CurContext->isDependentContext()) { DeclContext *DC = SemanticContext->getRedeclContext(); - DC->makeDeclVisibleInContext(NewTemplate, /* Recoverable = */ false); + DC->makeDeclVisibleInContext(NewTemplate); if (Scope *EnclosingScope = getScopeForDeclContext(S, DC)) PushOnScopeChains(NewTemplate, EnclosingScope, /* AddToContext = */ false); @@ -1103,10 +1142,10 @@ static bool DiagnoseDefaultTemplateArgument(Sema &S, // template-argument, that declaration shall be a definition and shall be // the only declaration of the function template in the translation unit. // (C++98/03 doesn't have this wording; see DR226). - if (!S.getLangOptions().CPlusPlus0x) - S.Diag(ParamLoc, - diag::ext_template_parameter_default_in_function_template) - << DefArgRange; + S.Diag(ParamLoc, S.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_template_parameter_default_in_function_template + : diag::ext_template_parameter_default_in_function_template) + << DefArgRange; return false; case Sema::TPC_ClassTemplateMember: @@ -1131,7 +1170,7 @@ static bool DiagnoseDefaultTemplateArgument(Sema &S, // declaration (and it is a definition). Strange! } - return false; + llvm_unreachable("Invalid TemplateParamListContext!"); } /// \brief Check for unexpanded parameter packs within the template parameters @@ -1195,9 +1234,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, bool SawDefaultArgument = false; SourceLocation PreviousDefaultArgLoc; - bool SawParameterPack = false; - SourceLocation ParameterPackLoc; - // Dummy initialization to avoid warnings. TemplateParameterList::iterator OldParam = NewParams->end(); if (OldParams) @@ -1212,18 +1248,11 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, SourceLocation OldDefaultLoc; SourceLocation NewDefaultLoc; - // Variables used to diagnose missing default arguments + // Variable used to diagnose missing default arguments bool MissingDefaultArg = false; - // C++0x [temp.param]p11: - // If a template parameter of a primary class template or alias template - // is a template parameter pack, it shall be the last template parameter. - if (SawParameterPack && - (TPC == TPC_ClassTemplate || TPC == TPC_TypeAliasTemplate)) { - Diag(ParameterPackLoc, - diag::err_template_param_pack_must_be_last_template_parameter); - Invalid = true; - } + // Variable used to diagnose non-final parameter packs + bool SawParameterPack = false; if (TemplateTypeParmDecl *NewTypeParm = dyn_cast<TemplateTypeParmDecl>(*NewParam)) { @@ -1243,7 +1272,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, 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(); @@ -1288,7 +1316,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, assert(!NewNonTypeParm->hasDefaultArgument() && "Parameter packs can't have a default argument!"); SawParameterPack = true; - ParameterPackLoc = NewNonTypeParm->getLocation(); } else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() && NewNonTypeParm->hasDefaultArgument()) { OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc(); @@ -1313,16 +1340,16 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, } else if (SawDefaultArgument) MissingDefaultArg = true; } else { - // Check the presence of a default argument here. TemplateTemplateParmDecl *NewTemplateParm = cast<TemplateTemplateParmDecl>(*NewParam); // Check for unexpanded parameter packs, recursively. - if (DiagnoseUnexpandedParameterPacks(*this, NewTemplateParm)) { + if (::DiagnoseUnexpandedParameterPacks(*this, NewTemplateParm)) { Invalid = true; continue; } + // Check the presence of a default argument here. if (NewTemplateParm->hasDefaultArgument() && DiagnoseDefaultTemplateArgument(*this, TPC, NewTemplateParm->getLocation(), @@ -1336,7 +1363,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, assert(!NewTemplateParm->hasDefaultArgument() && "Parameter packs can't have a default argument!"); SawParameterPack = true; - ParameterPackLoc = NewTemplateParm->getLocation(); } else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() && NewTemplateParm->hasDefaultArgument()) { OldDefaultLoc = OldTemplateParm->getDefaultArgument().getLocation(); @@ -1363,6 +1389,16 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, MissingDefaultArg = true; } + // C++0x [temp.param]p11: + // If a template parameter of a primary class template or alias template + // is a template parameter pack, it shall be the last template parameter. + if (SawParameterPack && (NewParam + 1) != NewParamEnd && + (TPC == TPC_ClassTemplate || TPC == TPC_TypeAliasTemplate)) { + Diag((*NewParam)->getLocation(), + diag::err_template_param_pack_must_be_last_template_parameter); + Invalid = true; + } + if (RedundantDefaultArg) { // C++ [temp.param]p12: // A template-parameter shall not be given default arguments @@ -1878,7 +1914,6 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) { } } - QualType Sema::CheckTemplateIdType(TemplateName Name, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs) { @@ -1910,18 +1945,17 @@ 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)) + false, Converted, &ExpansionIntoFixedList)) return QualType(); - assert((Converted.size() == Template->getTemplateParameters()->size()) && - "Converted template argument list is too short!"); - QualType CanonType; bool InstantiationDependent = false; - if (TypeAliasTemplateDecl *AliasTemplate - = dyn_cast<TypeAliasTemplateDecl>(Template)) { + TypeAliasTemplateDecl *AliasTemplate = 0; + if (!ExpansionIntoFixedList && + (AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Template))) { // Find the canonical type for this type alias template specialization. TypeAliasDecl *Pattern = AliasTemplate->getTemplatedDecl(); if (Pattern->isInvalidDecl()) @@ -2037,11 +2071,12 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, } TypeResult -Sema::ActOnTemplateIdType(CXXScopeSpec &SS, +Sema::ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy TemplateD, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, - SourceLocation RAngleLoc) { + SourceLocation RAngleLoc, + bool IsCtorOrDtorName) { if (SS.isInvalid()) return true; @@ -2052,20 +2087,21 @@ Sema::ActOnTemplateIdType(CXXScopeSpec &SS, translateTemplateArguments(TemplateArgsIn, TemplateArgs); if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { - QualType T = Context.getDependentTemplateSpecializationType(ETK_None, - DTN->getQualifier(), - DTN->getIdentifier(), - TemplateArgs); - - // Build type-source information. + QualType T + = Context.getDependentTemplateSpecializationType(ETK_None, + DTN->getQualifier(), + DTN->getIdentifier(), + TemplateArgs); + // Build type-source information. TypeLocBuilder TLB; DependentTemplateSpecializationTypeLoc SpecTL = TLB.push<DependentTemplateSpecializationTypeLoc>(T); - SpecTL.setKeywordLoc(SourceLocation()); - SpecTL.setNameLoc(TemplateLoc); + SpecTL.setElaboratedKeywordLoc(SourceLocation()); + SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); + SpecTL.setTemplateKeywordLoc(TemplateKWLoc); + SpecTL.setTemplateNameLoc(TemplateLoc); SpecTL.setLAngleLoc(LAngleLoc); SpecTL.setRAngleLoc(RAngleLoc); - SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I) SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T)); @@ -2078,20 +2114,24 @@ Sema::ActOnTemplateIdType(CXXScopeSpec &SS, return true; // Build type-source information. - TypeLocBuilder TLB; + TypeLocBuilder TLB; TemplateSpecializationTypeLoc SpecTL = TLB.push<TemplateSpecializationTypeLoc>(Result); + SpecTL.setTemplateKeywordLoc(TemplateKWLoc); SpecTL.setTemplateNameLoc(TemplateLoc); SpecTL.setLAngleLoc(LAngleLoc); SpecTL.setRAngleLoc(RAngleLoc); for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i) SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo()); - if (SS.isNotEmpty()) { + // NOTE: avoid constructing an ElaboratedTypeLoc if this is a + // constructor or destructor name (in such a case, the scope specifier + // will be attached to the enclosing Decl or Expr node). + if (SS.isNotEmpty() && !IsCtorOrDtorName) { // Create an elaborated-type-specifier containing the nested-name-specifier. Result = Context.getElaboratedType(ETK_None, SS.getScopeRep(), Result); ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result); - ElabTL.setKeywordLoc(SourceLocation()); + ElabTL.setElaboratedKeywordLoc(SourceLocation()); ElabTL.setQualifierLoc(SS.getWithLocInContext(Context)); } @@ -2102,7 +2142,8 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, TypeSpecifierType TagSpec, SourceLocation TagLoc, CXXScopeSpec &SS, - TemplateTy TemplateD, + SourceLocation TemplateKWLoc, + TemplateTy TemplateD, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, @@ -2127,12 +2168,13 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, // Build type-source information. TypeLocBuilder TLB; DependentTemplateSpecializationTypeLoc SpecTL - = TLB.push<DependentTemplateSpecializationTypeLoc>(T); - SpecTL.setKeywordLoc(TagLoc); - SpecTL.setNameLoc(TemplateLoc); + = TLB.push<DependentTemplateSpecializationTypeLoc>(T); + SpecTL.setElaboratedKeywordLoc(TagLoc); + SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); + SpecTL.setTemplateKeywordLoc(TemplateKWLoc); + SpecTL.setTemplateNameLoc(TemplateLoc); SpecTL.setLAngleLoc(LAngleLoc); SpecTL.setRAngleLoc(RAngleLoc); - SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I) SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T)); @@ -2167,11 +2209,12 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, Diag(D->getLocation(), diag::note_previous_use); } } - + // Provide source-location information for the template specialization. TypeLocBuilder TLB; TemplateSpecializationTypeLoc SpecTL = TLB.push<TemplateSpecializationTypeLoc>(Result); + SpecTL.setTemplateKeywordLoc(TemplateKWLoc); SpecTL.setTemplateNameLoc(TemplateLoc); SpecTL.setLAngleLoc(LAngleLoc); SpecTL.setRAngleLoc(RAngleLoc); @@ -2179,18 +2222,19 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo()); // Construct an elaborated type containing the nested-name-specifier (if any) - // and keyword. + // and tag keyword. Result = Context.getElaboratedType(Keyword, SS.getScopeRep(), Result); ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result); - ElabTL.setKeywordLoc(TagLoc); + ElabTL.setElaboratedKeywordLoc(TagLoc); ElabTL.setQualifierLoc(SS.getWithLocInContext(Context)); return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result)); } ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, - const TemplateArgumentListInfo &TemplateArgs) { + const TemplateArgumentListInfo *TemplateArgs) { // FIXME: Can we do any checking at this point? I guess we could check the // template arguments that we have against the template name, if the template // name refers to a single template. That's not a terribly common case, @@ -2211,6 +2255,7 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), SS.getWithLocInContext(Context), + TemplateKWLoc, R.getLookupNameInfo(), RequiresADL, TemplateArgs, R.begin(), R.end()); @@ -2221,13 +2266,15 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, // We actually only call this from template instantiation. ExprResult Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo &TemplateArgs) { + const TemplateArgumentListInfo *TemplateArgs) { + assert(TemplateArgs || TemplateKWLoc.isValid()); DeclContext *DC; if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext() || RequireCompleteDeclContext(SS, DC)) - return BuildDependentDeclRefExpr(SS, NameInfo, &TemplateArgs); + return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs); bool MemberOfUnknownSpecialization; LookupResult R(*this, NameInfo, LookupOrdinaryName); @@ -2251,7 +2298,7 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, return ExprError(); } - return BuildTemplateIdExpr(SS, R, /* ADL */ false, TemplateArgs); + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*ADL*/ false, TemplateArgs); } /// \brief Form a dependent template name. @@ -2262,15 +2309,17 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, /// SS will be "MetaFun::", \p TemplateKWLoc contains the location /// of the "template" keyword, and "apply" is the \p Name. TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, - SourceLocation TemplateKWLoc, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Result) { - if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() && - !getLangOptions().CPlusPlus0x) - Diag(TemplateKWLoc, diag::ext_template_outside_of_template) + if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent()) + Diag(TemplateKWLoc, + getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_template_outside_of_template : + diag::ext_template_outside_of_template) << FixItHint::CreateRemoval(TemplateKWLoc); DeclContext *LookupCtx = 0; @@ -2305,7 +2354,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases())) { // This is a dependent template. Handle it below. } else if (TNK == TNK_Non_template) { - Diag(Name.getSourceRange().getBegin(), + Diag(Name.getLocStart(), diag::err_template_kw_refers_to_non_template) << GetNameFromUnqualifiedId(Name).getName() << Name.getSourceRange() @@ -2339,7 +2388,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, break; } - Diag(Name.getSourceRange().getBegin(), + Diag(Name.getLocStart(), diag::err_template_kw_refers_to_non_template) << GetNameFromUnqualifiedId(Name).getName() << Name.getSourceRange() @@ -2391,7 +2440,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, // Objective-C ARC: // If an explicitly-specified template argument type is a lifetime type // with no lifetime qualifier, the __strong lifetime qualifier is inferred. - if (getLangOptions().ObjCAutoRefCount && + if (getLangOpts().ObjCAutoRefCount && ArgType->isObjCLifetimeType() && !ArgType.getObjCLifetime()) { Qualifiers Qs; @@ -2729,9 +2778,14 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, CXXScopeSpec SS; SS.Adopt(Arg.getTemplateQualifierLoc()); + // FIXME: the template-template arg was a DependentTemplateName, + // 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), - NameInfo)); + TemplateKWLoc, + NameInfo, 0)); // If we parsed the template argument as a pack expansion, create a // pack expansion expression. @@ -2782,7 +2836,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, case TemplateArgument::Pack: llvm_unreachable("Caller must expand template argument packs"); - break; } return false; @@ -2828,33 +2881,55 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, // 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) - << getLangOptions().CPlusPlus0x; + << getLangOpts().CPlusPlus0x; return true; case TemplateArgument::Declaration: - llvm_unreachable( - "Declaration argument with template template parameter"); - break; + llvm_unreachable("Declaration argument with template template parameter"); case TemplateArgument::Integral: - llvm_unreachable( - "Integral argument with template template parameter"); - break; + llvm_unreachable("Integral argument with template template parameter"); case TemplateArgument::Pack: llvm_unreachable("Caller must expand template argument packs"); - break; } return false; } +/// \brief Diagnose an arity mismatch in the +static bool diagnoseArityMismatch(Sema &S, TemplateDecl *Template, + SourceLocation TemplateLoc, + TemplateArgumentListInfo &TemplateArgs) { + TemplateParameterList *Params = Template->getTemplateParameters(); + unsigned NumParams = Params->size(); + unsigned NumArgs = TemplateArgs.size(); + + SourceRange Range; + if (NumArgs > NumParams) + Range = SourceRange(TemplateArgs[NumParams].getLocation(), + TemplateArgs.getRAngleLoc()); + S.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; + S.Diag(Template->getLocation(), diag::note_template_decl_here) + << Params->getSourceRange(); + return true; +} + /// \brief Check that the given template argument list is well-formed /// for specializing the given template. bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, - SmallVectorImpl<TemplateArgument> &Converted) { + SmallVectorImpl<TemplateArgument> &Converted, + bool *ExpansionIntoFixedList) { + if (ExpansionIntoFixedList) + *ExpansionIntoFixedList = false; + TemplateParameterList *Params = Template->getTemplateParameters(); unsigned NumParams = Params->size(); unsigned NumArgs = TemplateArgs.size(); @@ -2864,27 +2939,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, bool HasParameterPack = NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack(); - - if ((NumArgs > NumParams && !HasParameterPack) || - (NumArgs < Params->getMinRequiredArguments() && - !PartialTemplateArgs)) { - // 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 @@ -2896,10 +2951,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, ParamEnd = Params->end(); unsigned ArgIdx = 0; LocalInstantiationScope InstScope(*this, true); + bool SawPackExpansion = false; while (Param != ParamEnd) { if (ArgIdx < NumArgs) { // If we have an expanded parameter pack, make sure we don't have too // many arguments. + // FIXME: This really should fall out from the normal arity checking. if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { if (NTTP->isExpandedParameterPack() && @@ -2933,6 +2990,15 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // Move to the next template parameter. ++Param; } + + // If this template argument is a pack expansion, record that fact + // and break out; we can't actually check any more. + if (TemplateArgs[ArgIdx].getArgument().isPackExpansion()) { + SawPackExpansion = true; + ++ArgIdx; + break; + } + ++ArgIdx; continue; } @@ -2952,7 +3018,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, if ((*Param)->isTemplateParameterPack()) break; - // We have a default template argument that we will use. + // Check whether we have a default argument. TemplateArgumentLoc Arg; // Retrieve the default template argument from the template @@ -2961,10 +3027,9 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // (when the template parameter was part of a nested template) into // the default argument. if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { - if (!TTP->hasDefaultArgument()) { - assert(Invalid && "Missing default argument"); - break; - } + if (!TTP->hasDefaultArgument()) + return diagnoseArityMismatch(*this, Template, TemplateLoc, + TemplateArgs); TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(*this, Template, @@ -2979,10 +3044,9 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, ArgType); } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { - if (!NTTP->hasDefaultArgument()) { - assert(Invalid && "Missing default argument"); - break; - } + if (!NTTP->hasDefaultArgument()) + return diagnoseArityMismatch(*this, Template, TemplateLoc, + TemplateArgs); ExprResult E = SubstDefaultTemplateArgument(*this, Template, TemplateLoc, @@ -2998,10 +3062,9 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, TemplateTemplateParmDecl *TempParm = cast<TemplateTemplateParmDecl>(*Param); - if (!TempParm->hasDefaultArgument()) { - assert(Invalid && "Missing default argument"); - break; - } + if (!TempParm->hasDefaultArgument()) + return diagnoseArityMismatch(*this, Template, TemplateLoc, + TemplateArgs); NestedNameSpecifierLoc QualifierLoc; TemplateName Name = SubstDefaultTemplateArgument(*this, Template, @@ -3039,12 +3102,71 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, ++ArgIdx; } + // If we saw a pack expansion, then directly convert the remaining arguments, + // because we don't know what parameters they'll match up with. + if (SawPackExpansion) { + bool AddToArgumentPack + = Param != ParamEnd && (*Param)->isTemplateParameterPack(); + while (ArgIdx < NumArgs) { + if (AddToArgumentPack) + ArgumentPack.push_back(TemplateArgs[ArgIdx].getArgument()); + else + Converted.push_back(TemplateArgs[ArgIdx].getArgument()); + ++ArgIdx; + } + + // Push the argument pack onto the list of converted arguments. + if (AddToArgumentPack) { + if (ArgumentPack.empty()) + Converted.push_back(TemplateArgument(0, 0)); + else { + Converted.push_back( + TemplateArgument::CreatePackCopy(Context, + ArgumentPack.data(), + ArgumentPack.size())); + ArgumentPack.clear(); + } + } else if (ExpansionIntoFixedList) { + // We have expanded a pack into a fixed list. + *ExpansionIntoFixedList = true; + } + + return Invalid; + } + + // If we have any leftover arguments, then there were too many arguments. + // Complain and fail. + if (ArgIdx < NumArgs) + return diagnoseArityMismatch(*this, Template, TemplateLoc, TemplateArgs); + + // If we have an expanded parameter pack, make sure we don't have too + // many arguments. + // FIXME: This really should fall out from the normal arity checking. + if (Param != ParamEnd) { + if (NonTypeTemplateParmDecl *NTTP + = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { + if (NTTP->isExpandedParameterPack() && + ArgumentPack.size() < NTTP->getNumExpansionTypes()) { + Diag(TemplateLoc, diag::err_template_arg_list_different_arity) + << false + << (isa<ClassTemplateDecl>(Template)? 0 : + isa<FunctionTemplateDecl>(Template)? 1 : + isa<TemplateTemplateParmDecl>(Template)? 2 : 3) + << Template; + Diag(Template->getLocation(), diag::note_template_decl_here) + << Params->getSourceRange(); + return true; + } + } + } + // Form argument packs for each of the parameter packs remaining. while (Param != ParamEnd) { // If we're checking a partial list of template arguments, don't fill // in arguments for non-template parameter packs. - if ((*Param)->isTemplateParameterPack()) { + if (!HasParameterPack) + return true; if (ArgumentPack.empty()) Converted.push_back(TemplateArgument(0, 0)); else { @@ -3053,7 +3175,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, ArgumentPack.size())); ArgumentPack.clear(); } - } + } else if (!PartialTemplateArgs) + return diagnoseArityMismatch(*this, Template, TemplateLoc, TemplateArgs); ++Param; } @@ -3261,13 +3384,19 @@ bool UnnamedLocalNoLinkageFinder::VisitAtomicType(const AtomicType* T) { bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) { if (Tag->getDeclContext()->isFunctionOrMethod()) { - S.Diag(SR.getBegin(), diag::ext_template_arg_local_type) + S.Diag(SR.getBegin(), + S.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_template_arg_local_type : + diag::ext_template_arg_local_type) << S.Context.getTypeDeclType(Tag) << SR; return true; } if (!Tag->getDeclName() && !Tag->getTypedefNameForAnonDecl()) { - S.Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR; + S.Diag(SR.getBegin(), + S.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_template_arg_unnamed_type : + diag::ext_template_arg_unnamed_type) << SR; S.Diag(Tag->getLocation(), diag::note_template_unnamed_type_here); return true; } @@ -3291,7 +3420,7 @@ bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier( case NestedNameSpecifier::TypeSpecWithTemplate: return Visit(QualType(NNS->getAsType(), 0)); } - return false; + llvm_unreachable("Invalid NestedNameSpecifier::Kind!"); } @@ -3317,9 +3446,14 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param, // compounded from any of these types shall not be used as a // template-argument for a template type-parameter. // - // C++0x allows these, and even in C++03 we allow them as an extension with + // C++11 allows these, and even in C++03 we allow them as an extension with // a warning. - if (!LangOpts.CPlusPlus0x && Arg->hasUnnamedOrLocalType()) { + if (LangOpts.CPlusPlus0x ? + 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()) { UnnamedLocalNoLinkageFinder Finder(*this, SR); (void)Finder.Visit(Context.getCanonicalType(Arg)); } @@ -3327,6 +3461,99 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param, return false; } +enum NullPointerValueKind { + NPV_NotNullPointer, + NPV_NullPointer, + NPV_Error +}; + +/// \brief Determine whether the given template argument is a null pointer +/// value of the appropriate type. +static NullPointerValueKind +isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, + QualType ParamType, Expr *Arg) { + if (Arg->isValueDependent() || Arg->isTypeDependent()) + return NPV_NotNullPointer; + + if (!S.getLangOpts().CPlusPlus0x) + return NPV_NotNullPointer; + + // Determine whether we have a constant expression. + ExprResult ArgRV = S.DefaultFunctionArrayConversion(Arg); + if (ArgRV.isInvalid()) + return NPV_Error; + Arg = ArgRV.take(); + + Expr::EvalResult EvalResult; + llvm::SmallVector<PartialDiagnosticAt, 8> Notes; + EvalResult.Diag = &Notes; + if (!Arg->EvaluateAsRValue(EvalResult, S.Context) || + EvalResult.HasSideEffects) { + SourceLocation DiagLoc = Arg->getExprLoc(); + + // If our only note is the usual "invalid subexpression" note, just point + // the caret at its location rather than producing an essentially + // redundant note. + if (Notes.size() == 1 && Notes[0].second.getDiagID() == + diag::note_invalid_subexpr_in_const_expr) { + DiagLoc = Notes[0].first; + Notes.clear(); + } + + S.Diag(DiagLoc, diag::err_template_arg_not_address_constant) + << Arg->getType() << Arg->getSourceRange(); + for (unsigned I = 0, N = Notes.size(); I != N; ++I) + S.Diag(Notes[I].first, Notes[I].second); + + S.Diag(Param->getLocation(), diag::note_template_param_here); + return NPV_Error; + } + + // C++11 [temp.arg.nontype]p1: + // - an address constant expression of type std::nullptr_t + if (Arg->getType()->isNullPtrType()) + return NPV_NullPointer; + + // - a constant expression that evaluates to a null pointer value (4.10); or + // - a constant expression that evaluates to a null member pointer value + // (4.11); or + if ((EvalResult.Val.isLValue() && !EvalResult.Val.getLValueBase()) || + (EvalResult.Val.isMemberPointer() && + !EvalResult.Val.getMemberPointerDecl())) { + // If our expression has an appropriate type, we've succeeded. + bool ObjCLifetimeConversion; + if (S.Context.hasSameUnqualifiedType(Arg->getType(), ParamType) || + S.IsQualificationConversion(Arg->getType(), ParamType, false, + ObjCLifetimeConversion)) + return NPV_NullPointer; + + // The types didn't match, but we know we got a null pointer; complain, + // then recover as if the types were correct. + S.Diag(Arg->getExprLoc(), diag::err_template_arg_wrongtype_null_constant) + << Arg->getType() << ParamType << Arg->getSourceRange(); + S.Diag(Param->getLocation(), diag::note_template_param_here); + return NPV_NullPointer; + } + + // If we don't have a null pointer value, but we do have a NULL pointer + // constant, suggest a cast to the appropriate type. + 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()), + ")"); + S.Diag(Param->getLocation(), diag::note_template_param_here); + return NPV_NullPointer; + } + + // FIXME: If we ever want to support general, address-constant expressions + // as non-type template arguments, we should return the ExprResult here to + // be interpreted by the caller. + return NPV_NotNullPointer; +} + /// \brief Checks whether the given template argument is the address /// of an object or function according to C++ [temp.arg.nontype]p1. static bool @@ -3339,6 +3566,21 @@ 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: + Converted = TemplateArgument((Decl *)0); + return false; + + case NPV_Error: + return true; + + case NPV_NotNullPointer: + break; + } + } + // See through any implicit casts we added to fix the type. Arg = Arg->IgnoreImpCasts(); @@ -3358,9 +3600,11 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773 bool ExtraParens = false; while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) { - if (!Invalid && !ExtraParens && !S.getLangOptions().CPlusPlus0x) { - S.Diag(Arg->getSourceRange().getBegin(), - diag::ext_template_arg_extra_parens) + if (!Invalid && !ExtraParens) { + S.Diag(Arg->getLocStart(), + S.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_template_arg_extra_parens : + diag::ext_template_arg_extra_parens) << Arg->getSourceRange(); ExtraParens = true; } @@ -3382,7 +3626,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, } } - if (S.getLangOptions().MicrosoftExt && isa<CXXUuidofExpr>(Arg)) { + if (S.getLangOpts().MicrosoftExt && isa<CXXUuidofExpr>(Arg)) { Converted = TemplateArgument(ArgIn); return false; } @@ -3391,62 +3635,78 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, dyn_cast<SubstNonTypeTemplateParmExpr>(Arg)) Arg = subst->getReplacement()->IgnoreImpCasts(); - DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg); - if (!DRE) { - S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref) - << Arg->getSourceRange(); - S.Diag(Param->getLocation(), diag::note_template_param_here); - return true; - } - // Stop checking the precise nature of the argument if it is value dependent, // it should be checked when instantiated. if (Arg->isValueDependent()) { Converted = TemplateArgument(ArgIn); return false; } + + DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg); + if (!DRE) { + S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref) + << Arg->getSourceRange(); + S.Diag(Param->getLocation(), diag::note_template_param_here); + return true; + } if (!isa<ValueDecl>(DRE->getDecl())) { - S.Diag(Arg->getSourceRange().getBegin(), + S.Diag(Arg->getLocStart(), diag::err_template_arg_not_object_or_func_form) << Arg->getSourceRange(); S.Diag(Param->getLocation(), diag::note_template_param_here); return true; } - NamedDecl *Entity = 0; + NamedDecl *Entity = DRE->getDecl(); // Cannot refer to non-static data members - if (FieldDecl *Field = dyn_cast<FieldDecl>(DRE->getDecl())) { - S.Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_field) + if (FieldDecl *Field = dyn_cast<FieldDecl>(Entity)) { + S.Diag(Arg->getLocStart(), diag::err_template_arg_field) << Field << Arg->getSourceRange(); S.Diag(Param->getLocation(), diag::note_template_param_here); return true; } // Cannot refer to non-static member functions - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(DRE->getDecl())) + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Entity)) { if (!Method->isStatic()) { - S.Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_method) + S.Diag(Arg->getLocStart(), diag::err_template_arg_method) << Method << Arg->getSourceRange(); S.Diag(Param->getLocation(), diag::note_template_param_here); return true; } + } - // Functions must have external linkage. - if (FunctionDecl *Func = dyn_cast<FunctionDecl>(DRE->getDecl())) { - if (!isExternalLinkage(Func->getLinkage())) { - S.Diag(Arg->getSourceRange().getBegin(), - diag::err_template_arg_function_not_extern) - << Func << Arg->getSourceRange(); - S.Diag(Func->getLocation(), diag::note_template_arg_internal_object) - << true; - return true; - } + FunctionDecl *Func = dyn_cast<FunctionDecl>(Entity); + VarDecl *Var = dyn_cast<VarDecl>(Entity); + + // A non-type template argument must refer to an object or function. + if (!Func && !Var) { + // We found something, but we don't know specifically what it is. + S.Diag(Arg->getLocStart(), diag::err_template_arg_not_object_or_func) + << Arg->getSourceRange(); + S.Diag(DRE->getDecl()->getLocation(), diag::note_template_arg_refers_here); + return true; + } - // Okay: we've named a function with external linkage. - Entity = Func; + // Address / reference template args must have external linkage in C++98. + if (Entity->getLinkage() == InternalLinkage) { + S.Diag(Arg->getLocStart(), S.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_template_arg_object_internal : + diag::ext_template_arg_object_internal) + << !Func << Entity << Arg->getSourceRange(); + S.Diag(Entity->getLocation(), diag::note_template_arg_internal_object) + << !Func; + } else if (Entity->getLinkage() == NoLinkage) { + S.Diag(Arg->getLocStart(), diag::err_template_arg_object_no_linkage) + << !Func << Entity << Arg->getSourceRange(); + S.Diag(Entity->getLocation(), diag::note_template_arg_internal_object) + << !Func; + return true; + } + if (Func) { // If the template parameter has pointer type, the function decays. if (ParamType->isPointerType() && !AddressTaken) ArgType = S.Context.getPointerType(Func->getType()); @@ -3469,27 +3729,24 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, ArgType = Func->getType(); } - } else if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) { - if (!isExternalLinkage(Var->getLinkage())) { - S.Diag(Arg->getSourceRange().getBegin(), - diag::err_template_arg_object_not_extern) - << Var << Arg->getSourceRange(); - S.Diag(Var->getLocation(), diag::note_template_arg_internal_object) - << true; - return true; - } - + } else { // A value of reference type is not an object. if (Var->getType()->isReferenceType()) { - S.Diag(Arg->getSourceRange().getBegin(), + S.Diag(Arg->getLocStart(), diag::err_template_arg_reference_var) << Var->getType() << Arg->getSourceRange(); S.Diag(Param->getLocation(), diag::note_template_param_here); return true; } - // Okay: we've named an object with external linkage - Entity = Var; + // A template argument must have static storage duration. + // FIXME: Ensure this works for thread_local as well as __thread. + if (Var->isThreadSpecified()) { + S.Diag(Arg->getLocStart(), diag::err_template_arg_thread_local) + << Arg->getSourceRange(); + S.Diag(Var->getLocation(), diag::note_template_arg_refers_here); + return true; + } // If the template parameter has pointer type, we must have taken // the address of this object. @@ -3536,13 +3793,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, S.Diag(Param->getLocation(), diag::note_template_param_here); } } - } else { - // We found something else, but we don't know specifically what it is. - S.Diag(Arg->getSourceRange().getBegin(), - diag::err_template_arg_not_object_or_func) - << Arg->getSourceRange(); - S.Diag(DRE->getDecl()->getLocation(), diag::note_template_arg_refers_here); - return true; } bool ObjCLifetimeConversion; @@ -3568,7 +3818,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, unsigned ArgQuals = ArgType.getCVRQualifiers(); if ((ParamQuals | ArgQuals) != ParamQuals) { - S.Diag(Arg->getSourceRange().getBegin(), + S.Diag(Arg->getLocStart(), diag::err_template_arg_ref_bind_ignores_quals) << ParamType << Arg->getType() << Arg->getSourceRange(); @@ -3597,16 +3847,47 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, // Create the template argument. Converted = TemplateArgument(Entity->getCanonicalDecl()); - S.MarkDeclarationReferenced(Arg->getLocStart(), Entity); + S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity); return false; } /// \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, - TemplateArgument &Converted) { +static bool CheckTemplateArgumentPointerToMember(Sema &S, + NonTypeTemplateParmDecl *Param, + QualType ParamType, + Expr *&ResultArg, + TemplateArgument &Converted) { bool Invalid = false; + // Check for a null pointer value. + Expr *Arg = ResultArg; + switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) { + case NPV_Error: + return true; + case NPV_NullPointer: + Converted = TemplateArgument((Decl *)0); + return false; + case NPV_NotNullPointer: + break; + } + + bool ObjCLifetimeConversion; + if (S.IsQualificationConversion(Arg->getType(), + ParamType.getNonReferenceType(), + false, ObjCLifetimeConversion)) { + Arg = S.ImpCastExprToType(Arg, ParamType, CK_NoOp, + Arg->getValueKind()).take(); + ResultArg = Arg; + } else if (!S.Context.hasSameUnqualifiedType(Arg->getType(), + ParamType.getNonReferenceType())) { + // We can't perform this conversion. + S.Diag(Arg->getLocStart(), diag::err_template_arg_not_convertible) + << Arg->getType() << ParamType << Arg->getSourceRange(); + S.Diag(Param->getLocation(), diag::note_template_param_here); + return true; + } + // See through any implicit casts we added to fix the type. while (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg)) Arg = Cast->getSubExpr(); @@ -3623,9 +3904,11 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773 bool ExtraParens = false; while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) { - if (!Invalid && !ExtraParens && !getLangOptions().CPlusPlus0x) { - Diag(Arg->getSourceRange().getBegin(), - diag::ext_template_arg_extra_parens) + if (!Invalid && !ExtraParens) { + S.Diag(Arg->getLocStart(), + S.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_template_arg_extra_parens : + diag::ext_template_arg_extra_parens) << Arg->getSourceRange(); ExtraParens = true; } @@ -3651,7 +3934,7 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, if (VD->getType()->isMemberPointerType()) { if (isa<NonTypeTemplateParmDecl>(VD) || (isa<VarDecl>(VD) && - Context.getCanonicalType(VD->getType()).isConstQualified())) { + S.Context.getCanonicalType(VD->getType()).isConstQualified())) { if (Arg->isTypeDependent() || Arg->isValueDependent()) Converted = TemplateArgument(Arg); else @@ -3665,8 +3948,8 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, } if (!DRE) - return Diag(Arg->getSourceRange().getBegin(), - diag::err_template_arg_not_pointer_to_member_form) + return S.Diag(Arg->getLocStart(), + diag::err_template_arg_not_pointer_to_member_form) << Arg->getSourceRange(); if (isa<FieldDecl>(DRE->getDecl()) || isa<CXXMethodDecl>(DRE->getDecl())) { @@ -3684,11 +3967,10 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, } // 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); + S.Diag(Arg->getLocStart(), + diag::err_template_arg_not_pointer_to_member_form) + << Arg->getSourceRange(); + S.Diag(DRE->getDecl()->getLocation(), diag::note_template_arg_refers_here); return true; } @@ -3704,7 +3986,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, QualType InstantiatedParamType, Expr *Arg, TemplateArgument &Converted, CheckTemplateArgumentKind CTAK) { - SourceLocation StartLoc = Arg->getSourceRange().getBegin(); + SourceLocation StartLoc = Arg->getLocStart(); // If either the parameter has a dependent type or the argument is // type-dependent, there's nothing we can check now. @@ -3720,13 +4002,77 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // 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->isIntegralOrEnumerationType()) { + // C++11: + // -- for a non-type template-parameter of integral or + // enumeration type, conversions permitted in a converted + // constant expression are applied. + // + // C++98: + // -- for a non-type template-parameter of integral or + // enumeration type, integral promotions (4.5) and integral + // conversions (4.7) are applied. + + if (CTAK == CTAK_Deduced && + !Context.hasSameUnqualifiedType(ParamType, Arg->getType())) { + // C++ [temp.deduct.type]p17: + // If, in the declaration of a function template with a non-type + // template-parameter, the non-type template-parameter is used + // in an expression in the function parameter-list and, if the + // corresponding template-argument is deduced, the + // template-argument type shall match the type of the + // template-parameter exactly, except that a template-argument + // deduced from an array bound may be of any integral type. + Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch) + << Arg->getType().getUnqualifiedType() + << ParamType.getUnqualifiedType(); + Diag(Param->getLocation(), diag::note_template_param_here); + return ExprError(); + } + + if (getLangOpts().CPlusPlus0x) { + // We can't check arbitrary value-dependent arguments. + // FIXME: If there's no viable conversion to the template parameter type, + // we should be able to diagnose that prior to instantiation. + if (Arg->isValueDependent()) { + Converted = TemplateArgument(Arg); + return Owned(Arg); + } + + // C++ [temp.arg.nontype]p1: + // A template-argument for a non-type, non-template template-parameter + // shall be one of: + // + // -- for a non-type template-parameter of integral or enumeration + // type, a converted constant expression of the type of the + // template-parameter; or + llvm::APSInt Value; + ExprResult ArgResult = + CheckConvertedConstantExpression(Arg, ParamType, Value, + CCEK_TemplateArg); + if (ArgResult.isInvalid()) + return ExprError(); + + // Widen the argument value to sizeof(parameter type). This is almost + // always a no-op, except when the parameter type is bool. In + // that case, this may extend the argument from 1 bit to 8 bits. + QualType IntegerType = ParamType; + if (const EnumType *Enum = IntegerType->getAs<EnumType>()) + IntegerType = Enum->getDecl()->getIntegerType(); + Value = Value.extOrTrunc(Context.getTypeSize(IntegerType)); + + Converted = TemplateArgument(Value, Context.getCanonicalType(ParamType)); + return ArgResult; + } + + ExprResult ArgResult = DefaultLvalueConversion(Arg); + if (ArgResult.isInvalid()) + return ExprError(); + Arg = ArgResult.take(); + + QualType ArgType = Arg->getType(); + // C++ [temp.arg.nontype]p1: // A template-argument for a non-type, non-template // template-parameter shall be one of: @@ -3737,16 +4083,16 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, SourceLocation NonConstantLoc; llvm::APSInt Value; if (!ArgType->isIntegralOrEnumerationType()) { - Diag(Arg->getSourceRange().getBegin(), + Diag(Arg->getLocStart(), diag::err_template_arg_not_integral_or_enumeral) << ArgType << Arg->getSourceRange(); Diag(Param->getLocation(), diag::note_template_param_here); return ExprError(); - } else if (!Arg->isValueDependent() && - !Arg->isIntegerConstantExpr(Value, Context, &NonConstantLoc)) { - Diag(NonConstantLoc, diag::err_template_arg_not_ice) - << ArgType << Arg->getSourceRange(); - return ExprError(); + } else if (!Arg->isValueDependent()) { + Arg = VerifyIntegerConstantExpression(Arg, &Value, + PDiag(diag::err_template_arg_not_ice) << ArgType, false).take(); + if (!Arg) + return ExprError(); } // From here on out, all we care about are the unqualified forms @@ -3757,19 +4103,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // Try to convert the argument to the parameter's type. if (Context.hasSameType(ParamType, ArgType)) { // Okay: no conversion necessary - } else if (CTAK == CTAK_Deduced) { - // C++ [temp.deduct.type]p17: - // If, in the declaration of a function template with a non-type - // template-parameter, the non-type template- parameter is used - // in an expression in the function parameter-list and, if the - // corresponding template-argument is deduced, the - // template-argument type shall match the type of the - // template-parameter exactly, except that a template-argument - // deduced from an array bound may be of any integral type. - Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch) - << ArgType << ParamType; - Diag(Param->getLocation(), diag::note_template_param_here); - return ExprError(); } else if (ParamType->isBooleanType()) { // This is an integral-to-boolean conversion. Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take(); @@ -3779,7 +4112,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take(); } else { // We can't perform this conversion. - Diag(Arg->getSourceRange().getBegin(), + Diag(Arg->getLocStart(), diag::err_template_arg_not_convertible) << Arg->getType() << InstantiatedParamType << Arg->getSourceRange(); Diag(Param->getLocation(), diag::note_template_param_here); @@ -3820,7 +4153,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // Complain if an unsigned parameter received a negative value. if (IntegerType->isUnsignedIntegerOrEnumerationType() && (OldValue.isSigned() && OldValue.isNegative())) { - Diag(Arg->getSourceRange().getBegin(), diag::warn_template_arg_negative) + Diag(Arg->getLocStart(), diag::warn_template_arg_negative) << OldValue.toString(10) << Value.toString(10) << Param->getType() << Arg->getSourceRange(); Diag(Param->getLocation(), diag::note_template_param_here); @@ -3835,7 +4168,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, else RequiredBits = OldValue.getMinSignedBits(); if (RequiredBits > AllowedBits) { - Diag(Arg->getSourceRange().getBegin(), + Diag(Arg->getLocStart(), diag::warn_template_arg_too_large) << OldValue.toString(10) << Value.toString(10) << Param->getType() << Arg->getSourceRange(); @@ -3850,25 +4183,9 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, return Owned(Arg); } + QualType ArgType = Arg->getType(); DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction - // C++0x [temp.arg.nontype]p5 bullets 2, 4 and 6 permit conversion - // from a template argument of type std::nullptr_t to a non-type - // template parameter of type pointer to object, pointer to - // function, or pointer-to-member, respectively. - if (ArgType->isNullPtrType()) { - if (ParamType->isPointerType() || ParamType->isMemberPointerType()) { - Converted = TemplateArgument((NamedDecl *)0); - return Owned(Arg); - } - - if (ParamType->isNullPtrType()) { - llvm::APSInt Zero(Context.getTypeSize(Context.NullPtrTy), true); - Converted = TemplateArgument(Zero, Context.NullPtrTy); - return Owned(Arg); - } - } - // 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 @@ -3897,7 +4214,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, ParamType, true, FoundResult)) { - if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) + if (DiagnoseUseOfDecl(Fn, Arg->getLocStart())) return ExprError(); Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn); @@ -3914,22 +4231,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, return Owned(Arg); } - bool ObjCLifetimeConversion; - if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType(), - false, ObjCLifetimeConversion)) { - Arg = ImpCastExprToType(Arg, ParamType, CK_NoOp, - Arg->getValueKind()).take(); - } else 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 ExprError(); - } - - if (CheckTemplateArgumentPointerToMember(Arg, Converted)) + if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg, + Converted)) return ExprError(); return Owned(Arg); } @@ -3964,7 +4267,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, ParamRefType->getPointeeType(), true, FoundResult)) { - if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) + if (DiagnoseUseOfDecl(Fn, Arg->getLocStart())) return ExprError(); Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn); @@ -3980,27 +4283,35 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, return Owned(Arg); } + // Deal with parameters of type std::nullptr_t. + if (ParamType->isNullPtrType()) { + if (Arg->isTypeDependent() || Arg->isValueDependent()) { + Converted = TemplateArgument(Arg); + return Owned(Arg); + } + + switch (isNullPointerValueTemplateArgument(*this, Param, ParamType, Arg)) { + case NPV_NotNullPointer: + Diag(Arg->getExprLoc(), diag::err_template_arg_not_convertible) + << Arg->getType() << ParamType; + Diag(Param->getLocation(), diag::note_template_param_here); + return ExprError(); + + case NPV_Error: + return ExprError(); + + case NPV_NullPointer: + Converted = TemplateArgument((Decl *)0); + return Owned(Arg);; + } + } + // -- For a non-type template-parameter of type pointer to data // member, qualification conversions (4.4) are applied. assert(ParamType->isMemberPointerType() && "Only pointers to members remain"); - bool ObjCLifetimeConversion; - if (Context.hasSameUnqualifiedType(ParamType, ArgType)) { - // Types match exactly: nothing more to do here. - } else if (IsQualificationConversion(ArgType, ParamType, false, - ObjCLifetimeConversion)) { - Arg = ImpCastExprToType(Arg, ParamType, CK_NoOp, - Arg->getValueKind()).take(); - } 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 ExprError(); - } - - if (CheckTemplateArgumentPointerToMember(Arg, Converted)) + if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg, + Converted)) return ExprError(); return Owned(Arg); } @@ -4059,6 +4370,18 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, SourceLocation Loc) { assert(Arg.getKind() == TemplateArgument::Declaration && "Only declaration template arguments permitted here"); + + // For a NULL non-type template argument, return nullptr casted to the + // parameter's type. + if (!Arg.getAsDecl()) { + return ImpCastExprToType( + new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc), + ParamType, + ParamType->getAs<MemberPointerType>() + ? CK_NullToMemberPointer + : CK_NullToPointer); + } + ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl()); if (VD->getDeclContext()->isRecord() && @@ -4426,6 +4749,9 @@ Sema::TemplateParameterListsAreEqual(TemplateParameterList *New, /// false. Otherwise, issues a diagnostic and returns true. bool Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) { + if (!S) + return false; + // Find the nearest enclosing declaration scope. while ((S->getFlags() & Scope::DeclScope) == 0 || (S->getFlags() & Scope::TemplateParamScope) != 0) @@ -4453,7 +4779,7 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) { /// \brief Determine what kind of template specialization the given declaration /// is. -static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) { +static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D) { if (!D) return TSK_Undeclared; @@ -4509,8 +4835,11 @@ static bool CheckTemplateSpecializationScope(Sema &S, EntityKind = 4; else if (isa<RecordDecl>(Specialized)) EntityKind = 5; + else if (isa<EnumDecl>(Specialized) && S.getLangOpts().CPlusPlus0x) + EntityKind = 6; else { - S.Diag(Loc, diag::err_template_spec_unknown_kind); + S.Diag(Loc, diag::err_template_spec_unknown_kind) + << S.getLangOpts().CPlusPlus0x; S.Diag(Specialized->getLocation(), diag::note_specialized_entity); return true; } @@ -4535,7 +4864,7 @@ static bool CheckTemplateSpecializationScope(Sema &S, } if (S.CurContext->isRecord() && !IsPartialSpecialization) { - if (S.getLangOptions().MicrosoftExt) { + if (S.getLangOpts().MicrosoftExt) { // Do not warn for class scope explicit specialization during // instantiation, warning was already emitted during pattern // semantic analysis. @@ -4549,12 +4878,21 @@ static bool CheckTemplateSpecializationScope(Sema &S, } } + if (S.CurContext->isRecord() && + !S.CurContext->Equals(Specialized->getDeclContext())) { + // Make sure that we're specializing in the right record context. + // Otherwise, things can go horribly wrong. + S.Diag(Loc, diag::err_template_spec_decl_class_scope) + << Specialized; + return true; + } + // C++ [temp.class.spec]p6: // 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 || @@ -4571,24 +4909,28 @@ static bool CheckTemplateSpecializationScope(Sema &S, // C++0x [temp.expl.spec]p2: // An explicit specialization shall be declared in a namespace enclosing // the specialized template. - if (!DC->InEnclosingNamespaceSetOf(SpecializedContext) && - !(S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext))) { - bool IsCPlusPlus0xExtension - = !S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext); - if (isa<TranslationUnitDecl>(SpecializedContext)) - S.Diag(Loc, IsCPlusPlus0xExtension - ? diag::ext_template_spec_decl_out_of_scope_global - : diag::err_template_spec_decl_out_of_scope_global) + if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) { + bool IsCPlusPlus0xExtension = DC->Encloses(SpecializedContext); + if (isa<TranslationUnitDecl>(SpecializedContext)) { + assert(!IsCPlusPlus0xExtension && + "DC encloses TU but isn't in enclosing namespace set"); + S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global) << EntityKind << Specialized; - else if (isa<NamespaceDecl>(SpecializedContext)) - S.Diag(Loc, IsCPlusPlus0xExtension - ? diag::ext_template_spec_decl_out_of_scope - : diag::err_template_spec_decl_out_of_scope) - << EntityKind << Specialized - << cast<NamedDecl>(SpecializedContext); + } else if (isa<NamespaceDecl>(SpecializedContext)) { + int Diag; + if (!IsCPlusPlus0xExtension) + Diag = diag::err_template_spec_decl_out_of_scope; + else if (!S.getLangOpts().CPlusPlus0x) + Diag = diag::ext_template_spec_decl_out_of_scope; + else + Diag = diag::warn_cxx98_compat_template_spec_decl_out_of_scope; + S.Diag(Loc, Diag) + << EntityKind << Specialized << cast<NamedDecl>(SpecializedContext); + } S.Diag(Specialized->getLocation(), diag::note_specialized_entity); - ComplainedAboutScope = true; + ComplainedAboutScope = + !(IsCPlusPlus0xExtension && S.getLangOpts().CPlusPlus0x); } } @@ -4718,23 +5060,6 @@ static bool CheckClassTemplatePartialSpecializationArgs(Sema &S, return false; } -/// \brief Retrieve the previous declaration of the given declaration. -static NamedDecl *getPreviousDecl(NamedDecl *ND) { - if (VarDecl *VD = dyn_cast<VarDecl>(ND)) - return VD->getPreviousDeclaration(); - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) - return FD->getPreviousDeclaration(); - if (TagDecl *TD = dyn_cast<TagDecl>(ND)) - return TD->getPreviousDeclaration(); - if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(ND)) - return TD->getPreviousDeclaration(); - if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND)) - return FTD->getPreviousDeclaration(); - if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND)) - return CTD->getPreviousDeclaration(); - return 0; -} - DeclResult Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, @@ -4875,9 +5200,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TemplateArgs, false, Converted)) return true; - assert((Converted.size() == ClassTemplate->getTemplateParameters()->size()) && - "Converted template argument list is too short!"); - // Find the class template (partial) specialization declaration that // corresponds to these arguments. if (isPartialSpecialization) { @@ -5005,17 +5327,13 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // partial specialization are deducible from the template // arguments. If not, this class template partial specialization // will never be used. - SmallVector<bool, 8> DeducibleParams; - DeducibleParams.resize(TemplateParams->size()); + llvm::SmallBitVector DeducibleParams(TemplateParams->size()); MarkUsedTemplateParameters(Partial->getTemplateArgs(), true, TemplateParams->getDepth(), DeducibleParams); - unsigned NumNonDeducible = 0; - for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) - if (!DeducibleParams[I]) - ++NumNonDeducible; - if (NumNonDeducible) { + if (!DeducibleParams.all()) { + unsigned NumNonDeducible = DeducibleParams.size()-DeducibleParams.count(); Diag(TemplateNameLoc, diag::warn_partial_specs_not_deducible) << (NumNonDeducible > 1) << SourceRange(TemplateNameLoc, RAngleLoc); @@ -5065,7 +5383,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // use occurs; no diagnostic is required. if (PrevDecl && PrevDecl->getPointOfInstantiation().isValid()) { bool Okay = false; - for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) { + for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) { // Is there any previous explicit specialization declaration? if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) { Okay = true; @@ -5174,7 +5492,7 @@ Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, Scope *ParentScope = FnBodyScope->getParent(); - D.setFunctionDefinition(true); + D.setFunctionDefinitionKind(FDK_Definition); Decl *DP = HandleDeclarator(ParentScope, D, move(TemplateParameterLists)); if (FunctionTemplateDecl *FunctionTemplate @@ -5189,6 +5507,7 @@ Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, /// \brief Strips various properties off an implicit instantiation /// that has just been explicitly specialized. static void StripImplicitInstantiation(NamedDecl *D) { + // FIXME: "make check" is clean if the call to dropAttrs() is commented out. D->dropAttrs(); if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { @@ -5196,6 +5515,23 @@ static void StripImplicitInstantiation(NamedDecl *D) { } } +/// \brief Compute the diagnostic location for an explicit instantiation +// declaration or definition. +static SourceLocation DiagLocForExplicitInstantiation( + NamedDecl* D, SourceLocation PointOfInstantiation) { + // Explicit instantiations following a specialization have no effect and + // hence no PointOfInstantiation. In that case, walk decl backwards + // until a valid name loc is found. + SourceLocation PrevDiagLoc = PointOfInstantiation; + for (Decl *Prev = D; Prev && !PrevDiagLoc.isValid(); + Prev = Prev->getPreviousDecl()) { + PrevDiagLoc = Prev->getLocation(); + } + assert(PrevDiagLoc.isValid() && + "Explicit instantiation without point of instantiation?"); + return PrevDiagLoc; +} + /// \brief Diagnose cases where we have an explicit template specialization /// before/after an explicit template instantiation, producing diagnostics /// for those cases where they are required and determining whether the @@ -5262,7 +5598,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // before the first use of that specialization that would cause an // implicit instantiation to take place, in every translation unit in // which such a use occurs; no diagnostic is required. - for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) { + for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) { // Is there any previous explicit specialization declaration? if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) return false; @@ -5275,7 +5611,6 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, return true; } - break; case TSK_ExplicitInstantiationDeclaration: switch (PrevTSK) { @@ -5306,14 +5641,15 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // translation unit, the definition shall follow the declaration. Diag(NewLoc, diag::err_explicit_instantiation_declaration_after_definition); - Diag(PrevPointOfInstantiation, + + // Explicit instantiations following a specialization have no effect and + // hence no PrevPointOfInstantiation. In that case, walk decl backwards + // until a valid name loc is found. + Diag(DiagLocForExplicitInstantiation(PrevDecl, PrevPointOfInstantiation), diag::note_explicit_instantiation_definition_here); - assert(PrevPointOfInstantiation.isValid() && - "Explicit instantiation without point of instantiation?"); HasNoEffect = true; return false; } - break; case TSK_ExplicitInstantiationDefinition: switch (PrevTSK) { @@ -5333,18 +5669,32 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // In C++98/03 mode, we only give an extension warning here, because it // is not harmful to try to explicitly instantiate something that // has been explicitly specialized. - if (!getLangOptions().CPlusPlus0x) { - Diag(NewLoc, diag::ext_explicit_instantiation_after_specialization) - << PrevDecl; - Diag(PrevDecl->getLocation(), - diag::note_previous_template_specialization); - } + Diag(NewLoc, getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_explicit_instantiation_after_specialization : + diag::ext_explicit_instantiation_after_specialization) + << PrevDecl; + Diag(PrevDecl->getLocation(), + diag::note_previous_template_specialization); HasNoEffect = true; return false; case TSK_ExplicitInstantiationDeclaration: // We're explicity instantiating a definition for something for which we // were previously asked to suppress instantiations. That's fine. + + // 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. + for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) { + // Is there any previous explicit specialization declaration? + if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) { + HasNoEffect = true; + break; + } + } + return false; case TSK_ExplicitInstantiationDefinition: @@ -5354,12 +5704,11 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // in a program, Diag(NewLoc, diag::err_explicit_instantiation_duplicate) << PrevDecl; - Diag(PrevPointOfInstantiation, + Diag(DiagLocForExplicitInstantiation(PrevDecl, PrevPointOfInstantiation), diag::note_previous_explicit_instantiation); HasNoEffect = true; return false; } - break; } llvm_unreachable("Missing specialization/instantiation case?"); @@ -5486,8 +5835,13 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, // Note: do not overwrite location info if previous template // specialization kind was explicit. TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind(); - if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation) + if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation) { Specialization->setLocation(FD->getLocation()); + // C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr + // function can differ from the template declaration with respect to + // the constexpr specifier. + Specialization->setConstexpr(FD->isConstexpr()); + } // FIXME: Check if the prior specialization has a point of instantiation. // If so, we have run afoul of . @@ -5601,6 +5955,14 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { InstantiatedFrom = PrevRecord->getInstantiatedFromMemberClass(); MSInfo = PrevRecord->getMemberSpecializationInfo(); } + } else if (isa<EnumDecl>(Member)) { + EnumDecl *PrevEnum; + if (Previous.isSingleResult() && + (PrevEnum = dyn_cast<EnumDecl>(Previous.getFoundDecl()))) { + Instantiation = PrevEnum; + InstantiatedFrom = PrevEnum->getInstantiatedFromMemberEnum(); + MSInfo = PrevEnum->getMemberSpecializationInfo(); + } } if (!Instantiation) { @@ -5639,7 +6001,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { // C++ [temp.expl.spec]p6: // If a template, a member template or the member of a class template is - // explicitly specialized then that spe- cialization shall be declared + // explicitly specialized then that specialization shall be declared // before the first use of that specialization that would cause an implicit // instantiation to take place, in every translation unit in which such a // use occurs; no diagnostic is required. @@ -5691,8 +6053,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { cast<VarDecl>(InstantiatedFrom), TSK_ExplicitSpecialization); MarkUnusedFileScopedDecl(InstantiationVar); - } else { - assert(isa<CXXRecordDecl>(Member) && "Only member classes remain"); + } else if (isa<CXXRecordDecl>(Member)) { CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation); if (InstantiationClass->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) { @@ -5704,6 +6065,18 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass( cast<CXXRecordDecl>(InstantiatedFrom), TSK_ExplicitSpecialization); + } else { + assert(isa<EnumDecl>(Member) && "Only member enums remain"); + EnumDecl *InstantiationEnum = cast<EnumDecl>(Instantiation); + if (InstantiationEnum->getTemplateSpecializationKind() == + TSK_ImplicitInstantiation) { + InstantiationEnum->setTemplateSpecializationKind( + TSK_ExplicitSpecialization); + InstantiationEnum->setLocation(Member->getLocation()); + } + + cast<EnumDecl>(Member)->setInstantiationOfMemberEnum( + cast<EnumDecl>(InstantiatedFrom), TSK_ExplicitSpecialization); } // Save the caller the trouble of having to figure out which declaration @@ -5728,45 +6101,41 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, return true; } - // C++0x [temp.explicit]p2: + // C++11 [temp.explicit]p3: // An explicit instantiation shall appear in an enclosing namespace of its - // template. + // template. If the name declared in the explicit instantiation is an + // unqualified name, the explicit instantiation shall appear in the + // namespace where its template is declared or, if that namespace is inline + // (7.3.1), any namespace from its enclosing namespace set. // // This is DR275, which we do not retroactively apply to C++98/03. - if (S.getLangOptions().CPlusPlus0x && - !CurContext->Encloses(OrigContext)) { - if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext)) + if (WasQualifiedName) { + if (CurContext->Encloses(OrigContext)) + return false; + } else { + if (CurContext->InEnclosingNamespaceSetOf(OrigContext)) + return false; + } + + if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext)) { + if (WasQualifiedName) S.Diag(InstLoc, - S.getLangOptions().CPlusPlus0x? - diag::err_explicit_instantiation_out_of_scope - : diag::warn_explicit_instantiation_out_of_scope_0x) + S.getLangOpts().CPlusPlus0x? + diag::err_explicit_instantiation_out_of_scope : + diag::warn_explicit_instantiation_out_of_scope_0x) << D << NS; else S.Diag(InstLoc, - S.getLangOptions().CPlusPlus0x? - diag::err_explicit_instantiation_must_be_global - : diag::warn_explicit_instantiation_out_of_scope_0x) - << D; - S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); - return false; - } - - // C++0x [temp.explicit]p2: - // If the name declared in the explicit instantiation is an unqualified - // name, the explicit instantiation shall appear in the namespace where - // its template is declared or, if that namespace is inline (7.3.1), any - // namespace from its enclosing namespace set. - if (WasQualifiedName) - return false; - - if (CurContext->InEnclosingNamespaceSetOf(OrigContext)) - return false; - - S.Diag(InstLoc, - S.getLangOptions().CPlusPlus0x? - diag::err_explicit_instantiation_unqualified_wrong_namespace - : diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x) - << D << OrigContext; + S.getLangOpts().CPlusPlus0x? + diag::err_explicit_instantiation_unqualified_wrong_namespace : + diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x) + << D << NS; + } else + S.Diag(InstLoc, + S.getLangOpts().CPlusPlus0x? + diag::err_explicit_instantiation_must_be_global : + diag::warn_explicit_instantiation_must_be_global_0x) + << D; S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); return false; } @@ -5776,7 +6145,7 @@ static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) { if (!SS.isSet()) return false; - // C++0x [temp.explicit]p2: + // C++11 [temp.explicit]p3: // If the explicit instantiation is for a member function, a member class // or a static data member of a class template specialization, the name of // the class template specialization in the qualified-id for the member @@ -5847,9 +6216,6 @@ Sema::ActOnExplicitInstantiation(Scope *S, TemplateArgs, false, Converted)) return true; - assert((Converted.size() == ClassTemplate->getTemplateParameters()->size()) && - "Converted template argument list is too short!"); - // Find the class template specialization declaration that // corresponds to these arguments. void *InsertPos = 0; @@ -5932,6 +6298,9 @@ Sema::ActOnExplicitInstantiation(Scope *S, Specialization->setExternLoc(ExternLoc); Specialization->setTemplateKeywordLoc(TemplateLoc); + if (Attr) + ProcessDeclAttributeList(S, Specialization, Attr); + // 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. @@ -6000,7 +6369,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, KWLoc, SS, Name, NameLoc, Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(*this, 0, 0), - Owned, IsDependent, false, false, + Owned, IsDependent, SourceLocation(), false, TypeResult()); assert(!IsDependent && "explicit instantiation of dependent name not yet handled"); @@ -6008,11 +6377,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, return true; TagDecl *Tag = cast<TagDecl>(TagD); - if (Tag->isEnum()) { - Diag(TemplateLoc, diag::err_explicit_instantiation_enum) - << Context.getTypeDeclType(Tag); - return true; - } + assert(!Tag->isEnum() && "shouldn't see enumerations here"); if (Tag->isInvalidDecl()) return true; @@ -6053,7 +6418,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, // Verify that it is okay to explicitly instantiate here. CXXRecordDecl *PrevDecl - = cast_or_null<CXXRecordDecl>(Record->getPreviousDeclaration()); + = cast_or_null<CXXRecordDecl>(Record->getPreviousDecl()); if (!PrevDecl && Record->getDefinition()) PrevDecl = Record; if (PrevDecl) { @@ -6120,7 +6485,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, DeclarationName Name = NameInfo.getName(); if (!Name) { if (!D.isInvalidType()) - Diag(D.getDeclSpec().getSourceRange().getBegin(), + Diag(D.getDeclSpec().getLocStart(), diag::err_explicit_instantiation_requires_name) << D.getDeclSpec().getSourceRange() << D.getSourceRange(); @@ -6161,9 +6526,11 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, // inline or constexpr specifiers. // Presumably, this also applies to member functions of class templates as // well. - if (D.getDeclSpec().isInlineSpecified() && getLangOptions().CPlusPlus0x) + if (D.getDeclSpec().isInlineSpecified()) Diag(D.getDeclSpec().getInlineSpecLoc(), - diag::err_explicit_instantiation_inline) + getLangOpts().CPlusPlus0x ? + diag::err_explicit_instantiation_inline : + diag::warn_explicit_instantiation_inline_0x) << FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc()); if (D.getDeclSpec().isConstexprSpecified()) // FIXME: Add a fix-it to remove the 'constexpr' and add a 'const' if one is @@ -6326,7 +6693,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, return true; } - FunctionDecl *PrevDecl = Specialization->getPreviousDeclaration(); + FunctionDecl *PrevDecl = Specialization->getPreviousDecl(); if (!PrevDecl && Specialization->isThisDeclarationADefinition()) PrevDecl = Specialization; @@ -6346,6 +6713,9 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, } Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); + AttributeList *Attr = D.getDeclSpec().getAttributes().getList(); + if (Attr) + ProcessDeclAttributeList(S, Specialization, Attr); if (TSK == TSK_ExplicitInstantiationDefinition) InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization); @@ -6402,7 +6772,7 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // Create type-source location information for this type. TypeLocBuilder TLB; DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(Result); - TL.setKeywordLoc(TagLoc); + TL.setElaboratedKeywordLoc(TagLoc); TL.setQualifierLoc(SS.getWithLocInContext(Context)); TL.setNameLoc(NameLoc); return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result)); @@ -6415,9 +6785,11 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, if (SS.isInvalid()) return true; - if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() && - !getLangOptions().CPlusPlus0x) - Diag(TypenameLoc, diag::ext_typename_outside_of_template) + if (TypenameLoc.isValid() && S && !S->getTemplateParamParent()) + Diag(TypenameLoc, + getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_typename_outside_of_template : + diag::ext_typename_outside_of_template) << FixItHint::CreateRemoval(TypenameLoc); NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); @@ -6429,12 +6801,12 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); if (isa<DependentNameType>(T)) { DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); - TL.setKeywordLoc(TypenameLoc); + TL.setElaboratedKeywordLoc(TypenameLoc); TL.setQualifierLoc(QualifierLoc); TL.setNameLoc(IdLoc); } else { ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); - TL.setKeywordLoc(TypenameLoc); + TL.setElaboratedKeywordLoc(TypenameLoc); TL.setQualifierLoc(QualifierLoc); cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc); } @@ -6443,18 +6815,21 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, } TypeResult -Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, - const CXXScopeSpec &SS, - SourceLocation TemplateLoc, +Sema::ActOnTypenameType(Scope *S, + SourceLocation TypenameLoc, + const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, TemplateTy TemplateIn, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc) { - if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() && - !getLangOptions().CPlusPlus0x) - Diag(TypenameLoc, diag::ext_typename_outside_of_template) - << FixItHint::CreateRemoval(TypenameLoc); + if (TypenameLoc.isValid() && S && !S->getTemplateParamParent()) + Diag(TypenameLoc, + getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_typename_outside_of_template : + diag::ext_typename_outside_of_template) + << FixItHint::CreateRemoval(TypenameLoc); // Translate the parser's template argument list in our AST format. TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); @@ -6475,11 +6850,12 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, TypeLocBuilder Builder; DependentTemplateSpecializationTypeLoc SpecTL = Builder.push<DependentTemplateSpecializationTypeLoc>(T); + SpecTL.setElaboratedKeywordLoc(TypenameLoc); + SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); + SpecTL.setTemplateKeywordLoc(TemplateKWLoc); + SpecTL.setTemplateNameLoc(TemplateNameLoc); SpecTL.setLAngleLoc(LAngleLoc); SpecTL.setRAngleLoc(RAngleLoc); - SpecTL.setKeywordLoc(TypenameLoc); - SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); - SpecTL.setNameLoc(TemplateNameLoc); for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); @@ -6489,22 +6865,20 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, if (T.isNull()) return true; - // Provide source-location information for the template specialization - // type. + // Provide source-location information for the template specialization type. TypeLocBuilder Builder; - TemplateSpecializationTypeLoc SpecTL + TemplateSpecializationTypeLoc SpecTL = Builder.push<TemplateSpecializationTypeLoc>(T); - - // FIXME: No place to set the location of the 'template' keyword! + SpecTL.setTemplateKeywordLoc(TemplateKWLoc); + SpecTL.setTemplateNameLoc(TemplateNameLoc); SpecTL.setLAngleLoc(LAngleLoc); SpecTL.setRAngleLoc(RAngleLoc); - SpecTL.setTemplateNameLoc(TemplateNameLoc); for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T); ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T); - TL.setKeywordLoc(TypenameLoc); + TL.setElaboratedKeywordLoc(TypenameLoc); TL.setQualifierLoc(SS.getWithLocInContext(Context)); TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T); @@ -6588,10 +6962,6 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, Referenced = Result.getFoundDecl(); break; - - llvm_unreachable("unresolved using decl in non-dependent context"); - return QualType(); - case LookupResult::FoundOverloaded: DiagID = diag::err_typename_nested_not_type; Referenced = *Result.begin(); @@ -6650,6 +7020,11 @@ namespace { this->Loc = Loc; this->Entity = Entity; } + + ExprResult TransformLambdaExpr(LambdaExpr *E) { + // Lambdas never need to be transformed. + return E; + } }; } @@ -6762,7 +7137,7 @@ std::string Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgument *Args, unsigned NumArgs) { - llvm::SmallString<128> Str; + SmallString<128> Str; llvm::raw_svector_ostream Out(Str); if (!Params || Params->size() == 0 || NumArgs == 0) |