diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 307edf77ebb58..03c3ff87604f2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -236,6 +236,16 @@ Bug Fixes to C++ Support direct-list-initialized from an array is corrected to direct-initialization. - Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327) +Improvements to C++ diagnostics +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Clang now more consistently adds a note pointing to the relevant template + parameter. Some diagnostics are reworded to better take advantage of this. +- Template Template Parameter diagnostics now stop referring to template + parameters as template arguments, in some circumstances, better hiding + from the users template template parameter partial ordering arcana. + + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed type checking when a statement expression ends in an l-value of atomic type. (#GH106576) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 73b00752e6b40..177b8d98db8d2 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5193,16 +5193,11 @@ def err_template_unnamed_class : Error< def err_template_param_list_different_arity : Error< "%select{too few|too many}0 template parameters in template " "%select{|template parameter }1redeclaration">; -def note_template_param_list_different_arity : Note< - "%select{too few|too many}0 template parameters in template template " - "argument">; def note_template_prev_declaration : Note< "previous template %select{declaration|template parameter}0 is here">; def err_template_param_different_kind : Error< "template parameter has a different kind in template " "%select{|template parameter }0redeclaration">; -def note_template_param_different_kind : Note< - "template parameter has a different kind in template argument">; def err_invalid_decl_specifier_in_nontype_parm : Error< "invalid declaration specifier in template non-type parameter">; @@ -5211,8 +5206,6 @@ def err_template_nontype_parm_different_type : Error< "template non-type parameter has a different type %0 in template " "%select{|template parameter }1redeclaration">; -def note_template_nontype_parm_different_type : Note< - "template non-type parameter has a different type %0 in template argument">; def note_template_nontype_parm_prev_declaration : Note< "previous non-type template parameter with type %0 is here">; def err_template_nontype_parm_bad_type : Error< @@ -5303,10 +5296,15 @@ def err_template_missing_args : Error< "%select{class template|function template|variable template|alias template|" "template template parameter|concept|template}0 %1 requires template " "arguments">; -def err_template_arg_list_different_arity : Error< - "%select{too few|too many}0 template arguments for " +def err_template_param_missing_arg : Error< + "missing template argument for template parameter">; +def err_template_template_param_missing_param : Error< + "no template parameter in this template template parameter " + "corresponds to non-defaulted template parameter of argument template">; +def err_template_too_many_args : Error< + "too many template arguments for " "%select{class template|function template|variable template|alias template|" - "template template parameter|concept|template}1 %2">; + "template template parameter|concept|template}0 %1">; def note_template_decl_here : Note<"template is declared here">; def note_template_decl_external : Note< "template declaration from hidden source: %0">; @@ -5344,11 +5342,8 @@ def err_template_arg_not_valid_template : Error< "template parameter">; def note_template_arg_refers_here_func : Note< "template argument refers to function template %0, here">; -def err_template_arg_template_params_mismatch : Error< - "template template argument has different template parameters than its " - "corresponding template template parameter">; def note_template_arg_template_params_mismatch : Note< - "template template argument has different template parameters than its " + "template template argument is incompatible with its " "corresponding template template parameter">; def err_non_deduced_mismatch : Error< "could not match %diff{$ against $|types}0,1">; @@ -5910,10 +5905,6 @@ def err_template_parameter_pack_non_pack : Error< "%select{template type|non-type template|template template}0 parameter" "%select{| pack}1 conflicts with previous %select{template type|" "non-type template|template template}0 parameter%select{ pack|}1">; -def note_template_parameter_pack_non_pack : Note< - "%select{template type|non-type template|template template}0 parameter" - "%select{| pack}1 does not match %select{template type|non-type template" - "|template template}0 parameter%select{ pack|}1 in template argument">; def note_template_parameter_pack_here : Note< "previous %select{template type|non-type template|template template}0 " "parameter%select{| pack}1 declared here">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ebdbc69384efb..53d17936673ce 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11820,7 +11820,7 @@ class Sema final : public SemaBase { bool *ConstraintsNotSatisfied = nullptr); bool CheckTemplateTypeArgument( - TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg, + TemplateArgumentLoc &Arg, SmallVectorImpl &SugaredConverted, SmallVectorImpl &CanonicalConverted); @@ -11856,9 +11856,13 @@ class Sema final : public SemaBase { bool PartialOrdering, bool *StrictPackMatch); + /// Print the given named declaration to a string, + /// using the current PrintingPolicy, except that + /// TerseOutput will always be set. + SmallString<128> toTerseString(const NamedDecl &D) const; + void NoteTemplateLocation(const NamedDecl &Decl, std::optional ParamRange = {}); - void NoteTemplateParameterLocation(const NamedDecl &Decl); /// Given a non-type template argument that refers to a /// declaration and the type of its corresponding non-type template @@ -11973,15 +11977,13 @@ class Sema final : public SemaBase { bool TemplateParameterListsAreEqual( const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, - TemplateParameterListEqualKind Kind, - SourceLocation TemplateArgLoc = SourceLocation()); + TemplateParameterListEqualKind Kind); - bool TemplateParameterListsAreEqual( - TemplateParameterList *New, TemplateParameterList *Old, bool Complain, - TemplateParameterListEqualKind Kind, - SourceLocation TemplateArgLoc = SourceLocation()) { + bool TemplateParameterListsAreEqual(TemplateParameterList *New, + TemplateParameterList *Old, bool Complain, + TemplateParameterListEqualKind Kind) { return TemplateParameterListsAreEqual(nullptr, New, nullptr, Old, Complain, - Kind, TemplateArgLoc); + Kind); } /// Check whether a template can be declared within this scope. @@ -12860,6 +12862,11 @@ class Sema final : public SemaBase { /// We are performing partial ordering for template template parameters. PartialOrderingTTP, + + /// We are Checking a Template Parameter, so for any diagnostics which + /// occur in this scope, we will add a context note which points to this + /// template parameter. + CheckTemplateParameter, } Kind; /// Was the enclosing context a non-instantiation SFINAE context? @@ -13087,6 +13094,11 @@ class Sema final : public SemaBase { PartialOrderingTTP, TemplateDecl *PArg, SourceRange InstantiationRange = SourceRange()); + struct CheckTemplateParameter {}; + /// \brief Note that we are checking a template parameter. + InstantiatingTemplate(Sema &SemaRef, CheckTemplateParameter, + NamedDecl *Param); + /// Note that we have finished instantiating this template. void Clear(); @@ -13120,6 +13132,13 @@ class Sema final : public SemaBase { InstantiatingTemplate &operator=(const InstantiatingTemplate &) = delete; }; + /// For any diagnostics which occur within its scope, adds a context note + /// pointing to the declaration of the template parameter. + struct CheckTemplateParameterRAII : InstantiatingTemplate { + CheckTemplateParameterRAII(Sema &S, NamedDecl *Param) + : InstantiatingTemplate(S, CheckTemplateParameter(), Param) {} + }; + bool SubstTemplateArgument(const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentLoc &Output, diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 1ea4a2e9e88cf..60e103e643e27 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -403,7 +403,8 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback { } private: - static std::string toString(CodeSynthesisContext::SynthesisKind Kind) { + static std::optional + toString(CodeSynthesisContext::SynthesisKind Kind) { switch (Kind) { case CodeSynthesisContext::TemplateInstantiation: return "TemplateInstantiation"; @@ -461,8 +462,10 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback { return "TypeAliasTemplateInstantiation"; case CodeSynthesisContext::PartialOrderingTTP: return "PartialOrderingTTP"; + case CodeSynthesisContext::CheckTemplateParameter: + return std::nullopt; } - return ""; + return std::nullopt; } template @@ -470,12 +473,14 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback { const CodeSynthesisContext &Inst) { std::string YAML; { + std::optional Entry = + getTemplightEntry(TheSema, Inst); + if (!Entry) + return; llvm::raw_string_ostream OS(YAML); llvm::yaml::Output YO(OS); - TemplightEntry Entry = - getTemplightEntry(TheSema, Inst); llvm::yaml::EmptyContext Context; - llvm::yaml::yamlize(YO, Entry, true, Context); + llvm::yaml::yamlize(YO, *Entry, true, Context); } Out << "---" << YAML << "\n"; } @@ -555,10 +560,13 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback { } template - static TemplightEntry getTemplightEntry(const Sema &TheSema, - const CodeSynthesisContext &Inst) { + static std::optional + getTemplightEntry(const Sema &TheSema, const CodeSynthesisContext &Inst) { TemplightEntry Entry; - Entry.Kind = toString(Inst.Kind); + std::optional Kind = toString(Inst.Kind); + if (!Kind) + return std::nullopt; + Entry.Kind = *Kind; Entry.Event = BeginInstantiation ? "Begin" : "End"; llvm::raw_string_ostream OS(Entry.Name); printEntryName(TheSema, Inst.Entity, OS); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 925af06894f72..a8c5947f65a87 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -7269,7 +7269,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S, void InitializationSequence::PrintInitLocationNote(Sema &S, const InitializedEntity &Entity) { - if (Entity.isParamOrTemplateParamKind() && Entity.getDecl()) { + if (Entity.isParameterKind() && Entity.getDecl()) { if (Entity.getDecl()->getLocation().isInvalid()) return; @@ -7278,9 +7278,8 @@ void InitializationSequence::PrintInitLocationNote(Sema &S, << Entity.getDecl()->getDeclName(); else S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_here); - } - else if (Entity.getKind() == InitializedEntity::EK_RelatedResult && - Entity.getMethodDecl()) + } else if (Entity.getKind() == InitializedEntity::EK_RelatedResult && + Entity.getMethodDecl()) S.Diag(Entity.getMethodDecl()->getLocation(), diag::note_method_return_type_change) << Entity.getMethodDecl()->getDeclName(); diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index ceb32ee15dfa3..4d278bbc67d28 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1506,14 +1506,13 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, TemplateParameterList *TemplateParams = getGenericLambdaTemplateParameterList(LSI, *this); if (TemplateParams) { - for (const auto *TP : TemplateParams->asArray()) { + for (auto *TP : TemplateParams->asArray()) { if (!TP->getIdentifier()) continue; + CheckTemplateParameterRAII CTP(*this, TP); for (const auto &Capture : Intro.Captures) { - if (Capture.Id == TP->getIdentifier()) { + if (Capture.Id == TP->getIdentifier()) Diag(Capture.Loc, diag::err_template_param_shadow) << Capture.Id; - NoteTemplateParameterLocation(*TP); - } } } } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index aecf8ed1b4e4d..f3af514596a7e 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1580,9 +1580,13 @@ llvm::DenseSet &Sema::getLookupModules() { unsigned N = CodeSynthesisContexts.size(); for (unsigned I = CodeSynthesisContextLookupModules.size(); I != N; ++I) { - Module *M = CodeSynthesisContexts[I].Entity ? - getDefiningModule(*this, CodeSynthesisContexts[I].Entity) : - nullptr; + auto &Ctx = CodeSynthesisContexts[I]; + // FIXME: Are there any other context kinds that shouldn't be looked at + // here? + if (Ctx.Kind == CodeSynthesisContext::PartialOrderingTTP || + Ctx.Kind == CodeSynthesisContext::CheckTemplateParameter) + continue; + Module *M = Ctx.Entity ? getDefiningModule(*this, Ctx.Entity) : nullptr; if (M && !LookupModulesCache.insert(M).second) M = nullptr; CodeSynthesisContextLookupModules.push_back(M); @@ -3703,7 +3707,8 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, TemplateParameterList *Params = FD->getTemplateParameters(); if (Params->size() == 1) { IsTemplate = true; - if (!Params->getParam(0)->isTemplateParameterPack() && !StringLit) { + NamedDecl *Param = Params->getParam(0); + if (!Param->isTemplateParameterPack() && !StringLit) { // Implied but not stated: user-defined integer and floating literals // only ever use numeric literal operator templates, not templates // taking a parameter of class type. @@ -3716,6 +3721,7 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, if (StringLit) { SFINAETrap Trap(*this); CheckTemplateArgumentInfo CTAI; + CheckTemplateParameterRAII CTP(*this, Param); TemplateArgumentLoc Arg(TemplateArgument(StringLit), StringLit); if (CheckTemplateArgument( Params->getParam(0), Arg, FD, R.getNameLoc(), R.getNameLoc(), diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 38fa3ff3ab5b4..3a1ed3ed8e677 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -869,9 +869,11 @@ void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl, ? diag::ext_template_param_shadow : (SupportedForCompatibility ? diag::ext_compat_template_param_shadow : diag::err_template_param_shadow); - const auto *ND = cast(PrevDecl); + auto *ND = cast(PrevDecl); + CheckTemplateParameterRAII CTP(*this, ND); + // FIXME: Don't put the name in the diagnostic, unless there is no source + // location. Diag(Loc, DiagId) << ND->getDeclName(); - NoteTemplateParameterLocation(*ND); } TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) { @@ -4824,7 +4826,7 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S, } bool Sema::CheckTemplateTypeArgument( - TemplateTypeParmDecl *Param, TemplateArgumentLoc &AL, + TemplateArgumentLoc &AL, SmallVectorImpl &SugaredConverted, SmallVectorImpl &CanonicalConverted) { const TemplateArgument &Arg = AL.getArgument(); @@ -4880,7 +4882,6 @@ bool Sema::CheckTemplateTypeArgument( ? diag::ext_ms_template_type_arg_missing_typename : diag::err_template_arg_must_be_type_suggest) << FixItHint::CreateInsertion(Loc, "typename "); - NoteTemplateParameterLocation(*Param); // Recover by synthesizing a type using the location information that we // already have. @@ -4918,7 +4919,6 @@ bool Sema::CheckTemplateTypeArgument( // is not a type. SourceRange SR = AL.getSourceRange(); Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR; - NoteTemplateParameterLocation(*Param); return true; } @@ -5208,8 +5208,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, CheckTemplateArgumentInfo &CTAI, CheckTemplateArgumentKind CTAK) { // Check template type parameters. - if (TemplateTypeParmDecl *TTP = dyn_cast(Param)) - return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI.SugaredConverted, + if (isa(Param)) + return CheckTemplateTypeArgument(ArgLoc, CTAI.SugaredConverted, CTAI.CanonicalConverted); const TemplateArgument &Arg = ArgLoc.getArgument(); @@ -5354,8 +5354,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, // therefore cannot be a non-type template argument. Diag(ArgLoc.getLocation(), diag::err_template_arg_must_be_expr) << ArgLoc.getSourceRange(); - NoteTemplateParameterLocation(*Param); - return true; case TemplateArgument::Type: { @@ -5375,7 +5373,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig) << SR << T; else Diag(SR.getBegin(), diag::err_template_arg_must_be_expr) << SR; - NoteTemplateParameterLocation(*Param); return true; } @@ -5466,11 +5463,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, } /// Diagnose a missing template argument. -template +template static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc, - TemplateDecl *TD, - const TemplateParmDecl *D, - TemplateArgumentListInfo &Args) { + TemplateDecl *TD, const TemplateParmDecl *D, + TemplateArgumentListInfo &Args, + bool MatchingTTP) { // Dig out the most recent declaration of the template parameter; there may be // declarations of the template that are more recent than TD. D = cast(cast(TD->getMostRecentDecl()) @@ -5488,16 +5485,12 @@ static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc, return true; } + SourceLocation DiagLoc = Args.getRAngleLoc(); // FIXME: If there's a more recent default argument that *is* visible, // diagnose that it was declared too late. - - TemplateParameterList *Params = TD->getTemplateParameters(); - - S.Diag(Loc, diag::err_template_arg_list_different_arity) - << /*not enough args*/0 - << (int)S.getTemplateNameKindForDiagnostics(TemplateName(TD)) - << TD; - S.NoteTemplateLocation(*TD, Params->getSourceRange()); + S.Diag(DiagLoc.isValid() ? DiagLoc : Loc, + MatchingTTP ? diag::err_template_template_param_missing_param + : diag::err_template_param_missing_arg); return true; } @@ -5536,6 +5529,8 @@ bool Sema::CheckTemplateArgumentList( Param = ParamBegin; Param != ParamEnd; /* increment in loop */) { + CheckTemplateParameterRAII CTP1(*this, *Param); + if (size_t ParamIdx = Param - ParamBegin; DefaultArgs && ParamIdx >= DefaultArgs.StartPos) { // All written arguments should have been consumed by this point. @@ -5572,11 +5567,9 @@ bool Sema::CheckTemplateArgumentList( continue; } else if (ArgIdx == NumArgs && !PartialTemplateArgs) { // Not enough arguments for this parameter pack. - Diag(TemplateLoc, diag::err_template_arg_list_different_arity) - << /*not enough args*/0 - << (int)getTemplateNameKindForDiagnostics(TemplateName(Template)) - << Template; - NoteTemplateLocation(*Template, Params->getSourceRange()); + Diag(RAngleLoc, CTAI.MatchingTTP + ? diag::err_template_template_param_missing_param + : diag::err_template_param_missing_arg); return true; } } @@ -5589,8 +5582,10 @@ bool Sema::CheckTemplateArgumentList( if (ArgIsExpansion && CTAI.MatchingTTP) { SmallVector Args(ParamEnd - Param); + CTP1.Clear(); // Will continue processing parameters below. for (TemplateParameterList::iterator First = Param; Param != ParamEnd; ++Param) { + CheckTemplateParameterRAII CTP2(*this, *Param); TemplateArgument &Arg = Args[Param - First]; Arg = ArgLoc.getArgument(); if (!(*Param)->isTemplateParameterPack() || @@ -5631,7 +5626,6 @@ bool Sema::CheckTemplateArgumentList( diag::err_template_expansion_into_fixed_list) << (isa(Template) ? 1 : 0) << ArgLoc.getSourceRange(); - NoteTemplateParameterLocation(**Param); return true; } } @@ -5738,14 +5732,14 @@ bool Sema::CheckTemplateArgumentList( if (!HasDefaultArg) { if (TemplateTypeParmDecl *TTP = dyn_cast(*Param)) return diagnoseMissingArgument(*this, TemplateLoc, Template, TTP, - NewArgs); + NewArgs, CTAI.MatchingTTP); if (NonTypeTemplateParmDecl *NTTP = dyn_cast(*Param)) return diagnoseMissingArgument(*this, TemplateLoc, Template, NTTP, - NewArgs); + NewArgs, CTAI.MatchingTTP); return diagnoseMissingArgument(*this, TemplateLoc, Template, cast(*Param), - NewArgs); + NewArgs, CTAI.MatchingTTP); } return true; } @@ -5801,8 +5795,7 @@ bool Sema::CheckTemplateArgumentList( // If we have any leftover arguments, then there were too many arguments. // Complain and fail. if (ArgIdx < NumArgs) { - Diag(TemplateLoc, diag::err_template_arg_list_different_arity) - << /*too many args*/1 + Diag(TemplateLoc, diag::err_template_too_many_args) << (int)getTemplateNameKindForDiagnostics(TemplateName(Template)) << Template << SourceRange(NewArgs[ArgIdx].getLocation(), NewArgs.getRAngleLoc()); @@ -6227,8 +6220,6 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, << Arg->getType() << Arg->getSourceRange(); for (unsigned I = 0, N = Notes.size(); I != N; ++I) S.Diag(Notes[I].first, Notes[I].second); - - S.NoteTemplateParameterLocation(*Param); return NPV_Error; } @@ -6253,8 +6244,7 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, // 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.NoteTemplateParameterLocation(*Param); + << Arg->getType() << ParamType << Arg->getSourceRange(); return NPV_NullPointer; } @@ -6263,8 +6253,7 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, // We could just return NPV_NotNullPointer, but we can print a better // message with the information we have here. S.Diag(Arg->getExprLoc(), diag::err_template_arg_invalid) - << EvalResult.Val.getAsString(S.Context, ParamType); - S.NoteTemplateParameterLocation(*Param); + << EvalResult.Val.getAsString(S.Context, ParamType); return NPV_Error; } @@ -6276,7 +6265,6 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), Code) << FixItHint::CreateInsertion(S.getLocForEndOfToken(Arg->getEndLoc()), ")"); - S.NoteTemplateParameterLocation(*Param); return NPV_NullPointer; } @@ -6317,7 +6305,6 @@ static bool CheckTemplateArgumentIsCompatibleWithParameter( S.Diag(Arg->getBeginLoc(), diag::err_template_arg_ref_bind_ignores_quals) << ParamType << Arg->getType() << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -6335,7 +6322,6 @@ static bool CheckTemplateArgumentIsCompatibleWithParameter( else S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_convertible) << ArgIn->getType() << ParamType << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -6478,7 +6464,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (!Entity) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref) << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6486,7 +6471,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (isa(Entity) || isa(Entity)) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_field) << Entity << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6495,7 +6479,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (!Method->isStatic()) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_method) << Method << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -6535,7 +6518,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (Var->getType()->isReferenceType()) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_reference_var) << Var->getType() << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6555,15 +6537,12 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (!S.Context.hasSameUnqualifiedType(Entity->getType(), ParamType.getNonReferenceType())) { S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer) - << ParamType; - S.NoteTemplateParameterLocation(*Param); + << ParamType; return true; } S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer) - << ParamType - << FixItHint::CreateRemoval(AddrOpLoc); - S.NoteTemplateParameterLocation(*Param); + << ParamType << FixItHint::CreateRemoval(AddrOpLoc); ArgType = Entity->getType(); } @@ -6584,15 +6563,12 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( ArgType = S.Context.getPointerType(Entity->getType()); if (!S.Context.hasSameUnqualifiedType(ArgType, ParamType)) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_address_of) - << ParamType; - S.NoteTemplateParameterLocation(*Param); + << ParamType; return true; } S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_address_of) - << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), "&"); - - S.NoteTemplateParameterLocation(*Param); + << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), "&"); } } @@ -6708,7 +6684,6 @@ CheckTemplateArgumentPointerToMember(Sema &S, NonTypeTemplateParmDecl *Param, // We can't perform this conversion. S.Diag(ResultArg->getBeginLoc(), diag::err_template_arg_not_convertible) << ResultArg->getType() << ParamType << ResultArg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6814,7 +6789,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, diag::err_non_type_template_parm_type_deduction_failure) << Param->getDeclName() << Param->getType() << Arg->getType() << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); return ExprError(); } } @@ -6823,10 +6797,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // declaration, but here we'll pass the argument location because that's // where the parameter type is deduced. ParamType = CheckNonTypeTemplateParameterType(ParamType, Arg->getExprLoc()); - if (ParamType.isNull()) { - NoteTemplateParameterLocation(*Param); + if (ParamType.isNull()) return ExprError(); - } } // We should have already dropped all cv-qualifiers by now. @@ -6858,9 +6830,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // not the type of the template argument deduced from A, against the // template parameter type. Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch) - << Arg->getType() - << ParamType.getUnqualifiedType(); - NoteTemplateParameterLocation(*Param); + << Arg->getType() << ParamType.getUnqualifiedType(); return ExprError(); } @@ -6955,10 +6925,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, Arg, ParamType, PartialOrderingTTP ? CCEK_InjectedTTP : CCEK_TemplateArg, Param); assert(!ArgResult.isUnset()); - if (ArgResult.isInvalid()) { - NoteTemplateParameterLocation(*Param); + if (ArgResult.isInvalid()) return ExprError(); - } } else { ArgResult = Arg; } @@ -7105,7 +7073,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (!ArgType->isIntegralOrEnumerationType()) { Diag(Arg->getBeginLoc(), diag::err_template_arg_not_integral_or_enumeral) << ArgType << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); return ExprError(); } else if (!Arg->isValueDependent()) { class TmplArgICEDiagnoser : public VerifyICEDiagnoser { @@ -7143,7 +7110,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // We can't perform this conversion. Diag(Arg->getBeginLoc(), diag::err_template_arg_not_convertible) << Arg->getType() << ParamType << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); return ExprError(); } @@ -7189,7 +7155,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, Diag(Arg->getBeginLoc(), diag::warn_template_arg_negative) << toString(OldValue, 10) << toString(Value, 10) << Param->getType() << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); } // Complain if we overflowed the template parameter's type. @@ -7200,12 +7165,10 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, RequiredBits = OldValue.getActiveBits() + 1; else RequiredBits = OldValue.getSignificantBits(); - if (RequiredBits > AllowedBits) { + if (RequiredBits > AllowedBits) Diag(Arg->getBeginLoc(), diag::warn_template_arg_too_large) << toString(OldValue, 10) << toString(Value, 10) << Param->getType() << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); - } } QualType T = ParamType->isEnumeralType() ? ParamType : IntegerType; @@ -7330,8 +7293,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, switch (isNullPointerValueTemplateArgument(*this, Param, ParamType, Arg)) { case NPV_NotNullPointer: Diag(Arg->getExprLoc(), diag::err_template_arg_not_convertible) - << Arg->getType() << ParamType; - NoteTemplateParameterLocation(*Param); + << Arg->getType() << ParamType; return ExprError(); case NPV_Error: @@ -7359,7 +7321,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, static void DiagnoseTemplateParameterListArityMismatch( Sema &S, TemplateParameterList *New, TemplateParameterList *Old, - Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc); + Sema::TemplateParameterListEqualKind Kind); bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, TemplateParameterList *Params, @@ -7429,7 +7391,6 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, Diag(Arg.getLocation(), diag::err_template_template_parameter_not_at_least_as_constrained) << Template << Param << Arg.getSourceRange(); - Diag(Param->getLocation(), diag::note_entity_declared_at) << Param; Diag(Template->getLocation(), diag::note_entity_declared_at) << Template; MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template, TemplateAC); @@ -7438,25 +7399,24 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, return false; } -static Sema::SemaDiagnosticBuilder noteLocation(Sema &S, const NamedDecl &Decl, - unsigned HereDiagID, - unsigned ExternalDiagID) { - if (Decl.getLocation().isValid()) - return S.Diag(Decl.getLocation(), HereDiagID); - +SmallString<128> Sema::toTerseString(const NamedDecl &D) const { SmallString<128> Str; llvm::raw_svector_ostream Out(Str); - PrintingPolicy PP = S.getPrintingPolicy(); + PrintingPolicy PP = getPrintingPolicy(); PP.TerseOutput = 1; - Decl.print(Out, PP); - return S.Diag(Decl.getLocation(), ExternalDiagID) << Out.str(); + D.print(Out, PP); + return Str; } +// FIXME: Transform this into a context note. void Sema::NoteTemplateLocation(const NamedDecl &Decl, std::optional ParamRange) { + bool HasLoc = Decl.getLocation().isValid(); SemaDiagnosticBuilder DB = - noteLocation(*this, Decl, diag::note_template_decl_here, - diag::note_template_decl_external); + Diag(Decl.getLocation(), HasLoc ? diag::note_template_decl_here + : diag::note_template_decl_external); + if (!HasLoc) + DB << toTerseString(Decl).str(); if (ParamRange && ParamRange->isValid()) { assert(Decl.getLocation().isValid() && "Parameter range has location when Decl does not"); @@ -7464,11 +7424,6 @@ void Sema::NoteTemplateLocation(const NamedDecl &Decl, } } -void Sema::NoteTemplateParameterLocation(const NamedDecl &Decl) { - noteLocation(*this, Decl, diag::note_template_param_here, - diag::note_template_param_external); -} - ExprResult Sema::BuildExpressionFromDeclTemplateArgument( const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc, NamedDecl *TemplateParam) { @@ -7745,21 +7700,17 @@ Sema::BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg, } /// Match two template parameters within template parameter lists. -static bool MatchTemplateParameterKind( - Sema &S, NamedDecl *New, - const Sema::TemplateCompareNewDeclInfo &NewInstFrom, NamedDecl *Old, - const NamedDecl *OldInstFrom, bool Complain, - Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) { +static bool +MatchTemplateParameterKind(Sema &S, NamedDecl *New, + const Sema::TemplateCompareNewDeclInfo &NewInstFrom, + NamedDecl *Old, const NamedDecl *OldInstFrom, + bool Complain, + Sema::TemplateParameterListEqualKind Kind) { // Check the actual kind (type, non-type, template). if (Old->getKind() != New->getKind()) { if (Complain) { - unsigned NextDiag = diag::err_template_param_different_kind; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_param_different_kind; - } - S.Diag(New->getLocation(), NextDiag) - << (Kind != Sema::TPL_TemplateMatch); + S.Diag(New->getLocation(), diag::err_template_param_different_kind) + << (Kind != Sema::TPL_TemplateMatch); S.Diag(Old->getLocation(), diag::note_template_prev_declaration) << (Kind != Sema::TPL_TemplateMatch); } @@ -7773,18 +7724,11 @@ static bool MatchTemplateParameterKind( // a parameter pack where the template template argument does not. if (Old->isTemplateParameterPack() != New->isTemplateParameterPack()) { if (Complain) { - unsigned NextDiag = diag::err_template_parameter_pack_non_pack; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, - diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_parameter_pack_non_pack; - } - unsigned ParamKind = isa(New)? 0 : isa(New)? 1 : 2; - S.Diag(New->getLocation(), NextDiag) - << ParamKind << New->isParameterPack(); + S.Diag(New->getLocation(), diag::err_template_parameter_pack_non_pack) + << ParamKind << New->isParameterPack(); S.Diag(Old->getLocation(), diag::note_template_parameter_pack_here) << ParamKind << Old->isParameterPack(); } @@ -7805,13 +7749,8 @@ static bool MatchTemplateParameterKind( QualType NewType = S.Context.getUnconstrainedType(NewNTTP->getType()); if (!S.Context.hasSameType(OldType, NewType)) { if (Complain) { - unsigned NextDiag = diag::err_template_nontype_parm_different_type; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, - diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_nontype_parm_different_type; - } - S.Diag(NewNTTP->getLocation(), NextDiag) + S.Diag(NewNTTP->getLocation(), + diag::err_template_nontype_parm_different_type) << NewNTTP->getType() << (Kind != Sema::TPL_TemplateMatch); S.Diag(OldNTTP->getLocation(), diag::note_template_nontype_parm_prev_declaration) @@ -7832,8 +7771,7 @@ static bool MatchTemplateParameterKind( OldTTP->getTemplateParameters(), Complain, (Kind == Sema::TPL_TemplateMatch ? Sema::TPL_TemplateTemplateParmMatch - : Kind), - TemplateArgLoc)) + : Kind))) return false; } @@ -7884,21 +7822,12 @@ static bool MatchTemplateParameterKind( /// Diagnose a known arity mismatch when comparing template argument /// lists. -static -void DiagnoseTemplateParameterListArityMismatch(Sema &S, - TemplateParameterList *New, - TemplateParameterList *Old, - Sema::TemplateParameterListEqualKind Kind, - SourceLocation TemplateArgLoc) { - unsigned NextDiag = diag::err_template_param_list_different_arity; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_param_list_different_arity; - } - S.Diag(New->getTemplateLoc(), NextDiag) - << (New->size() > Old->size()) - << (Kind != Sema::TPL_TemplateMatch) - << SourceRange(New->getTemplateLoc(), New->getRAngleLoc()); +static void DiagnoseTemplateParameterListArityMismatch( + Sema &S, TemplateParameterList *New, TemplateParameterList *Old, + Sema::TemplateParameterListEqualKind Kind) { + S.Diag(New->getTemplateLoc(), diag::err_template_param_list_different_arity) + << (New->size() > Old->size()) << (Kind != Sema::TPL_TemplateMatch) + << SourceRange(New->getTemplateLoc(), New->getRAngleLoc()); S.Diag(Old->getTemplateLoc(), diag::note_template_prev_declaration) << (Kind != Sema::TPL_TemplateMatch) << SourceRange(Old->getTemplateLoc(), Old->getRAngleLoc()); @@ -7907,11 +7836,10 @@ void DiagnoseTemplateParameterListArityMismatch(Sema &S, bool Sema::TemplateParameterListsAreEqual( const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, - TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) { + TemplateParameterListEqualKind Kind) { if (Old->size() != New->size()) { if (Complain) - DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, - TemplateArgLoc); + DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind); return false; } @@ -7929,21 +7857,18 @@ bool Sema::TemplateParameterListsAreEqual( OldParm != OldParmEnd; ++OldParm, ++NewParm) { if (NewParm == NewParmEnd) { if (Complain) - DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, - TemplateArgLoc); + DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind); return false; } if (!MatchTemplateParameterKind(*this, *NewParm, NewInstFrom, *OldParm, - OldInstFrom, Complain, Kind, - TemplateArgLoc)) + OldInstFrom, Complain, Kind)) return false; } // Make sure we exhausted all of the arguments. if (NewParm != NewParmEnd) { if (Complain) - DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, - TemplateArgLoc); + DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind); return false; } @@ -8238,7 +8163,6 @@ static bool CheckNonTypeTemplatePartialSpecializationArgs( S.Diag(IsDefaultArgument ? TemplateNameLoc : ArgExpr->getBeginLoc(), diag::err_dependent_typed_non_type_arg_in_partial_spec) << Param->getType(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -8262,6 +8186,7 @@ bool Sema::CheckTemplatePartialSpecializationArgs( if (!Param) continue; + CheckTemplateParameterRAII CTP(*this, Param); if (CheckNonTypeTemplatePartialSpecializationArgs(*this, TemplateNameLoc, Param, &TemplateArgs[I], 1, I >= NumExplicit)) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 627cd82ed1c77..5e006eab88c97 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3006,7 +3006,7 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, // arguments). S.Diag(Param->getLocation(), diag::err_template_arg_deduced_incomplete_pack) - << Arg << Param; + << Arg << Param; return true; } if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size())) @@ -3072,7 +3072,7 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments( for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) { NamedDecl *Param = TemplateParams->getParam(I); - + Sema::CheckTemplateParameterRAII CTP(S, Param); // C++0x [temp.arg.explicit]p3: // A trailing template parameter pack (14.5.3) not otherwise deduced will // be deduced to an empty sequence of template arguments. diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index fcb7671ed92f0..f2c0dfdf639a6 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -575,6 +575,7 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const { case BuildingDeductionGuides: case TypeAliasTemplateInstantiation: case PartialOrderingTTP: + case CheckTemplateParameter: return false; // This function should never be called when Kind's value is Memoization. @@ -809,7 +810,16 @@ Sema::InstantiatingTemplate::InstantiatingTemplate( Sema &SemaRef, SourceLocation ArgLoc, PartialOrderingTTP, TemplateDecl *PArg, SourceRange InstantiationRange) : InstantiatingTemplate(SemaRef, CodeSynthesisContext::PartialOrderingTTP, - ArgLoc, InstantiationRange, PArg) {} + ArgLoc, SourceRange(), PArg) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, + CheckTemplateParameter, + NamedDecl *Param) + : InstantiatingTemplate( + SemaRef, CodeSynthesisContext::CheckTemplateParameter, + Param->getLocation(), Param->getSourceRange(), Param) { + assert(Param->isTemplateParameter()); +} void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) { Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext; @@ -1251,12 +1261,18 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) { case CodeSynthesisContext::PartialOrderingTTP: DiagFunc(Active->PointOfInstantiation, PDiag(diag::note_template_arg_template_params_mismatch)); - if (SourceLocation ParamLoc = Active->Entity->getLocation(); - ParamLoc.isValid()) - DiagFunc(ParamLoc, PDiag(diag::note_template_prev_declaration) - << /*isTemplateTemplateParam=*/true - << Active->InstantiationRange); break; + case CodeSynthesisContext::CheckTemplateParameter: { + const auto &ND = *cast(Active->Entity); + if (SourceLocation Loc = ND.getLocation(); Loc.isValid()) { + DiagFunc(Loc, PDiag(diag::note_template_param_here) + << ND.getSourceRange()); + break; + } + DiagFunc(SourceLocation(), PDiag(diag::note_template_param_external) + << toTerseString(ND).str()); + break; + } } } } @@ -1300,6 +1316,7 @@ std::optional Sema::isSFINAEContext() const { case CodeSynthesisContext::DefaultTemplateArgumentChecking: case CodeSynthesisContext::RewritingOperatorAsSpaceship: case CodeSynthesisContext::PartialOrderingTTP: + case CodeSynthesisContext::CheckTemplateParameter: // A default template argument instantiation and substitution into // template parameters with arguments for prior parameters may or may // not be a SFINAE context; look further up the stack. @@ -2348,6 +2365,7 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr( ExprResult TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr( SubstNonTypeTemplateParmExpr *E) { + Sema::CheckTemplateParameterRAII CTP(SemaRef, E->getParameter()); ExprResult SubstReplacement = E->getReplacement(); if (!isa(SubstReplacement.get())) SubstReplacement = TransformExpr(E->getReplacement()); diff --git a/clang/test/AST/ByteCode/cxx1z.cpp b/clang/test/AST/ByteCode/cxx1z.cpp index 57f99235a2b20..ca5f10f6567b4 100644 --- a/clang/test/AST/ByteCode/cxx1z.cpp +++ b/clang/test/AST/ByteCode/cxx1z.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s // RUN: %clang_cc1 -std=c++17 -verify=ref,both %s -template struct A {}; +template struct A {}; // both-note 6{{template parameter is declared here}} namespace Temp { struct S { int n; }; constexpr S &addr(S &&s) { return s; } diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp index 06501de64916a..d39c2281ec146 100644 --- a/clang/test/AST/ByteCode/cxx20.cpp +++ b/clang/test/AST/ByteCode/cxx20.cpp @@ -897,7 +897,7 @@ namespace VirtDtor { } namespace TemporaryInNTTP { - template struct B { /* ... */ }; + template struct B { /* ... */ }; // both-note {{template parameter is declared here}} struct J1 { J1 *self=this; }; diff --git a/clang/test/AST/ByteCode/cxx98.cpp b/clang/test/AST/ByteCode/cxx98.cpp index c17049b01c1da..9af668029f8a3 100644 --- a/clang/test/AST/ByteCode/cxx98.cpp +++ b/clang/test/AST/ByteCode/cxx98.cpp @@ -6,7 +6,7 @@ namespace IntOrEnum { const int k = 0; const int &p = k; // both-note {{declared here}} - template struct S {}; + template struct S {}; // both-note {{template parameter is declared here}} S

s; // both-error {{not an integral constant expression}} \ // both-note {{read of variable 'p' of non-integral, non-enumeration type 'const int &'}} } diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp index cb3d6111fd2bf..48f856fdd2c07 100644 --- a/clang/test/AST/ByteCode/records.cpp +++ b/clang/test/AST/ByteCode/records.cpp @@ -413,7 +413,7 @@ namespace DeriveFailures { constexpr Derived(int i) : OtherVal(i) {} // ref-error {{never produces a constant expression}} \ // both-note {{non-constexpr constructor 'Base' cannot be used in a constant expression}} \ - // ref-note {{non-constexpr constructor 'Base' cannot be used in a constant expression}} + // ref-note {{non-constexpr constructor 'Base' cannot be used in a constant expression}} }; constexpr Derived D(12); // both-error {{must be initialized by a constant expression}} \ @@ -1740,9 +1740,9 @@ namespace CtorOfInvalidClass { // both-error {{must be initialized by a constant expression}} #if __cplusplus >= 202002L - template + template // both-note {{template parameter is declared here}} concept ReferenceOf = Q; - /// This calls a valid and constexpr copy constructor of InvalidCtor, + /// This calls a valid and constexpr copy constructor of InvalidCtor, /// but should still be rejected. template auto R, typename Rep> int F; // both-error {{non-type template argument is not a constant expression}} #endif diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp index 9632fda296aa1..fc4e359666ba9 100644 --- a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp @@ -33,5 +33,6 @@ namespace test1 { // specifiers. namespace test2 { template struct bar {}; + // expected-note@-1 {{template parameter is declared here}} template struct foo : bar {}; // expected-error {{use of class template 'foo' requires template arguments}} expected-note {{template is declared here}} } diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index 2bceb3e267790..57c99212f4c69 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -251,5 +251,5 @@ void P1957R2(void *a, int *b, Agg *c, int Agg::*d) { Agg tc = {c}; // expected-error {{cannot be narrowed}} expected-note {{}} Agg td = {d}; // expected-error {{cannot be narrowed}} expected-note {{}} } -template struct BoolParam {}; +template struct BoolParam {}; // expected-note {{template parameter is declared here}} BoolParam<&P1957R2> bp; // expected-error {{not allowed in a converted constant expression}} diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp index 282e71bbf3bda..c035aa3f4ec61 100644 --- a/clang/test/CXX/drs/cwg0xx.cpp +++ b/clang/test/CXX/drs/cwg0xx.cpp @@ -806,6 +806,7 @@ namespace cwg49 { // cwg49: 2.8 // since-cxx17-error@#cwg49-c {{non-type template argument is not a constant expression}} // since-cxx17-note@#cwg49-c {{read of non-constexpr variable 'q' is not allowed in a constant expression}} // since-cxx17-note@#cwg49-q {{declared here}} + // since-cxx17-note@#cwg49-A {{template parameter is declared here}} } // namespace cwg49 namespace cwg50 { // cwg50: 2.7 @@ -1018,9 +1019,9 @@ namespace cwg62 { // cwg62: 2.9 struct A { struct { int n; } b; }; - template struct X {}; - template T get() { return get(); } - template int take(T) { return 0; } + template struct X {}; // #cwg62-X + template T get() { return get(); } // #cwg62-get + template int take(T) { return 0; } // #cwg62-take X x1; A a = get(); @@ -1034,22 +1035,27 @@ namespace cwg62 { // cwg62: 2.9 X x2; // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-X {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} X x3; // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-X {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} NoNameForLinkagePtr p1 = get(); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-get {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} + // cxx98-note@-4 {{while substituting explicitly-specified template arguments}} NoNameForLinkagePtr p2 = get(); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-get {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} + // cxx98-note@-4 {{while substituting explicitly-specified template arguments}} int n1 = take(noNameForLinkagePtr); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-take {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting deduced template arguments}} + // cxx98-note@-4 {{while substituting deduced template arguments}} X x4; @@ -1057,18 +1063,24 @@ namespace cwg62 { // cwg62: 2.9 struct NoLinkage {}; X a; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} X b; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} get(); // cxx98-error@-1 {{template argument uses local type }} - // cxx98-note@-2 {{while substituting explicitly-specified template arguments}} + // cxx98-note@#cwg62-get {{template parameter is declared here}} + // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} get(); // cxx98-error@-1 {{template argument uses local type }} - // cxx98-note@-2 {{while substituting explicitly-specified template arguments}} + // cxx98-note@#cwg62-get {{template parameter is declared here}} + // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} X c; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} X d; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} } } // namespace cwg62 @@ -1135,10 +1147,11 @@ namespace cwg69 { // cwg69: 9 extern template void f(); // cxx98-error@-1 {{extern templates are a C++11 extension}} // expected-error@-2 {{explicit instantiation declaration of 'f' with internal linkage}} - template struct Q {}; + template struct Q {}; // #cwg69-Q Q<&f > q; // cxx98-error@-1 {{non-type template argument referring to function 'f' with internal linkage is a C++11 extension}} // cxx98-note@#cwg69-f {{non-type template argument refers to function here}} + // cxx98-note@#cwg69-Q {{template parameter is declared here}} } // namespace cwg69 namespace cwg70 { // cwg70: 2.7 diff --git a/clang/test/CXX/drs/cwg10xx.cpp b/clang/test/CXX/drs/cwg10xx.cpp index c5b96c4ab8ffc..10ee50558c7e8 100644 --- a/clang/test/CXX/drs/cwg10xx.cpp +++ b/clang/test/CXX/drs/cwg10xx.cpp @@ -43,6 +43,7 @@ namespace cwg1004 { // cwg1004: 5 template class U = T::template A> struct Third { }; // expected-error@-1 {{is a constructor name}} // expected-note@#cwg1004-t {{in instantiation of default argument}} + // expected-note@-3 {{template parameter is declared here}} Third > t; // #cwg1004-t } // namespace cwg1004 diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp index 9c72fefb5b65c..8a9f285673699 100644 --- a/clang/test/CXX/drs/cwg13xx.cpp +++ b/clang/test/CXX/drs/cwg13xx.cpp @@ -180,6 +180,7 @@ namespace cwg1315 { // cwg1315: partial // dependent type of T::value is not the same as 'int'. // A core issue will be opened to decide what is supposed to happen here. template struct C; + // expected-note@-1 {{template parameter is declared here}} template struct C; // expected-error@-1 {{type of specialized non-type template argument depends on a template parameter of the partial specialization}} } // namespace cwg1315 diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index 626473f11d3ec..5f40fe469b01b 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -26,6 +26,7 @@ S V; // #cwg1801-S-i // cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg1801-S {{template parameter is declared here}} // cxx17-error@#cwg1801-S-i {{non-type template argument refers to subobject '.i'}} +// cxx17-note@#cwg1801-S {{template parameter is declared here}} } // namespace cwg1801 namespace cwg1802 { // cwg1802: 3.1 @@ -381,13 +382,13 @@ struct A { struct B { void e(); }; - + void f(); - + struct D { void g(); }; - + T h(); template @@ -399,13 +400,13 @@ struct A { struct B { void e(); }; - + int f(); - + struct D { void g(); }; - + template int i(); }; @@ -430,11 +431,11 @@ class C { template friend void A::D::g(); // expected-warning@-1 {{dependent nested name specifier 'A::D::' for friend class declaration is not supported; turning off access control for 'C'}} - + template friend int *A::h(); // expected-warning@-1 {{dependent nested name specifier 'A::' for friend class declaration is not supported; turning off access control for 'C'}} - + template template friend T A::i(); @@ -451,7 +452,7 @@ template void A::f() { (void)c.private_int; } int A::f() { (void)c.private_int; return 0; } -// FIXME: both definition of 'D::g' are not friends, so they don't have access to 'private_int' +// FIXME: both definition of 'D::g' are not friends, so they don't have access to 'private_int' template void A::D::g() { (void)c.private_int; } void A::D::g() { (void)c.private_int; } diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index 15bcc20b7fa2a..51f320fc43cfa 100644 --- a/clang/test/CXX/drs/cwg1xx.cpp +++ b/clang/test/CXX/drs/cwg1xx.cpp @@ -26,18 +26,22 @@ namespace cwg100 { // cwg100: 2.7 // cxx98-14-error@#cwg100-a {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg100-A {{template parameter is declared here}} // since-cxx17-error@#cwg100-a {{pointer to string literal is not allowed in a template argument}} + // since-cxx17-note@#cwg100-A {{template parameter is declared here}} B<"bar"> b; // #cwg100-b // cxx98-14-error@#cwg100-b {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg100-B {{template parameter is declared here}} // since-cxx17-error@#cwg100-b {{reference to string literal is not allowed in a template argument}} + // since-cxx17-note@#cwg100-B {{template parameter is declared here}} C<"baz"> c; // #cwg100-c // cxx98-14-error@#cwg100-c {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg100-C {{template parameter is declared here}} // since-cxx17-error@#cwg100-c {{pointer to subobject of string literal is not allowed in a template argument}} + // since-cxx17-note@#cwg100-C {{template parameter is declared here}} D<*"quux"> d; // #cwg100-d // cxx98-14-error@#cwg100-d {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg100-D {{template parameter is declared here}} // since-cxx17-error@#cwg100-d {{reference to subobject of string literal is not allowed in a template argument}} + // since-cxx17-note@#cwg100-D {{template parameter is declared here}} } // namespace cwg100 namespace cwg101 { // cwg101: 3.5 @@ -152,15 +156,17 @@ namespace cwg112 { // cwg112: 3.1 volatile T a2[1] = {}; const Arr a3 = {}; // #cwg112-a3 volatile Arr a4 = {}; - template struct X {}; + template struct X {}; // #cwg112-X // FIXME: Test this somehow in C++11 and on. X x1; // cxx98-error@-1 {{non-type template argument referring to object 'a1' with internal linkage is a C++11 extension}} // cxx98-note@#cwg112-a1 {{non-type template argument refers to object here}} + // cxx98-note@#cwg112-X {{template parameter is declared here}} X x2; X x3; // cxx98-error@-1 {{non-type template argument referring to object 'a3' with internal linkage is a C++11 extension}} // cxx98-note@#cwg112-a3 {{non-type template argument refers to object here}} + // cxx98-note@#cwg112-X {{template parameter is declared here}} X x4; } // namespace cwg112 @@ -634,7 +640,7 @@ namespace example3 { struct Base { private: static const int i = 10; // #cwg138-ex3-Base-i - + public: struct Data; // Elaborated type specifier is not the sole constituent of declaration, @@ -648,7 +654,7 @@ struct Base { }; }; struct Data { - void f() { + void f() { int i2 = Base::i; // expected-error@-1 {{'i' is a private member of 'cwg138::example3::Base'}} // expected-note@#cwg138-ex3-Base-i {{declared private here}} @@ -1309,8 +1315,8 @@ namespace cwg184 { // cwg184: 2.7 template class T> void A::f() { // #cwg184-T T<> t; - // expected-error@-1 {{too few template arguments for template template parameter 'T'}} - // expected-note@#cwg184-T {{template is declared here}} + // expected-error@-1 {{missing template argument for template parameter}} + // expected-note@#cwg184-T {{template parameter is declared here}} } template class T> void A::g() { diff --git a/clang/test/CXX/drs/cwg20xx.cpp b/clang/test/CXX/drs/cwg20xx.cpp index 141a1012aef93..fd31a51f79ec5 100644 --- a/clang/test/CXX/drs/cwg20xx.cpp +++ b/clang/test/CXX/drs/cwg20xx.cpp @@ -27,7 +27,7 @@ int b = __builtin_addressof(b2)->foo; // cwg2009: na namespace cwg2026 { // cwg2026: 11 - template struct X {}; + template struct X {}; // #cwg2026-X const int a = a + 1; // #cwg2026-a // expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}} @@ -35,9 +35,11 @@ namespace cwg2026 { // cwg2026: 11 // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} // cxx98-note@-2 {{initializer of 'a' is not a constant expression}} // cxx98-note@#cwg2026-a {{declared here}} + // cxx98-note@#cwg2026-X {{template parameter is declared here}} // since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}} // since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}} // since-cxx11-note@#cwg2026-a {{declared here}} + // since-cxx11-note@#cwg2026-X {{template parameter is declared here}} #if __cplusplus >= 201103L constexpr int b = b; @@ -65,9 +67,11 @@ namespace cwg2026 { // cwg2026: 11 // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} // cxx98-note@-2 {{initializer of 'e' is not a constant expression}} // cxx98-note@#cwg2026-e {{declared here}} + // cxx98-note@#cwg2026-X {{template parameter is declared here}} // since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}} // since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}} // since-cxx11-note@#cwg2026-e {{declared here}} + // since-cxx11-note@#cwg2026-X {{template parameter is declared here}} #if __cplusplus >= 201103L static constexpr int f = f; @@ -149,7 +153,7 @@ namespace cwg2076 { // cwg2076: 13 operator string_view() const; }; - void foo(const string &); // #cwg2076-foo + void foo(const string &); // #cwg2076-foo void bar(string_view); // #cwg2076-bar void func(const string &arg) { @@ -429,7 +433,7 @@ int f() return 0; } } // namespace GH42233 -} // namespace cwg2091 +} // namespace cwg2091 namespace cwg2094 { // cwg2094: 5 struct A { int n; }; diff --git a/clang/test/CXX/drs/cwg21xx.cpp b/clang/test/CXX/drs/cwg21xx.cpp index 42a7c4d7bbded..97bf320658759 100644 --- a/clang/test/CXX/drs/cwg21xx.cpp +++ b/clang/test/CXX/drs/cwg21xx.cpp @@ -24,7 +24,7 @@ namespace std { } namespace cwg2100 { // cwg2100: 12 - template struct X {}; + template struct X {}; // #cwg2100-X template struct A { static const int n = 1; int f() { @@ -35,6 +35,7 @@ namespace cwg2100 { // cwg2100: 12 return X<&n>::n; // ok, value-dependent // cxx98-14-error@-1 {{non-type template argument refers to object 'n' that does not have linkage}} // cxx98-14-note@#cwg2100-n {{non-type template argument refers to object here}} + // cxx98-14-note@#cwg2100-X {{template parameter is declared here}} } }; template struct X

{ diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp index 6c420ecd4c91d..a616120b82063 100644 --- a/clang/test/CXX/drs/cwg3xx.cpp +++ b/clang/test/CXX/drs/cwg3xx.cpp @@ -317,18 +317,20 @@ namespace cwg319 { // cwg319: no typedef int (*pa)[n1]; pa parr; // ok, type has linkage despite using 'n1' - template struct X {}; + template struct X {}; // #cwg319-X void f() { struct A { int n; }; extern A a; // FIXME: ill-formed X xa; // cxx98-error@-1 {{template argument uses local type 'A'}} + // cxx98-note@#cwg319-X {{template parameter is declared here}} typedef A B; extern B b; // FIXME: ill-formed X xb; // cxx98-error@-1 {{template argument uses local type 'A'}} + // cxx98-note@#cwg319-X {{template parameter is declared here}} const int n = 1; typedef int (*C)[n]; @@ -997,6 +999,7 @@ namespace cwg354 { // cwg354: 3.1 c++11 // since-cxx17-note@#cwg354-ptr_mem {{template parameter is declared here}} ptr_mem<(int S::*)0> m1; // cxx98-error@-1 {{non-type template argument is not a pointer to member constant}} + // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}} ptr_mem<(float S::*)0> m2; // #cwg354-m2 // cxx98-error@#cwg354-m2 {{non-type template argument of type 'float S::*' cannot be converted to a value of type 'int S::*'}} // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}} @@ -1502,7 +1505,7 @@ namespace cwg389 { // cwg389: no typedef struct {} const C; // #cwg389-C typedef enum {} const D; // #cwg389-D }; - template struct T {}; + template struct T {}; // #cwg389-T struct WithLinkage1 {}; enum WithLinkage2 {}; @@ -1543,18 +1546,23 @@ namespace cwg389 { // cwg389: no typedef T BadArg1; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-no-link-1 {{unnamed type used in template argument was declared here}} typedef T BadArg2; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-no-link-2 {{unnamed type used in template argument was declared here}} typedef T BadArg3; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-C {{unnamed type used in template argument was declared here}} typedef T BadArg4; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-D {{unnamed type used in template argument was declared here}} typedef T BadArg5; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-C {{unnamed type used in template argument was declared here}} #endif diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp index 0debc104ac45b..78b03b3df2323 100644 --- a/clang/test/CXX/drs/cwg4xx.cpp +++ b/clang/test/CXX/drs/cwg4xx.cpp @@ -43,12 +43,15 @@ namespace cwg401 { // cwg401: 2.8 // expected-error@#cwg401-A {{'type' is a private member of 'cwg401::C'}} // expected-note@#cwg402-friend-A-C {{in instantiation of default argument for 'A' required here}} // expected-note@#cwg402-C-type {{implicitly declared private here}} + // expected-note@#cwg401-A {{template parameter is declared here}} // expected-error@#cwg401-A {{'type' is a protected member of 'cwg401::B'}} // expected-note@#cwg402-b {{in instantiation of default argument for 'A' required here}} // expected-note@#cwg402-B-type {{declared protected here}} + // expected-note@#cwg401-A {{template parameter is declared here}} // expected-error@#cwg401-A {{'type' is a private member of 'cwg401::D'}} // expected-note@#cwg402-d {{in instantiation of default argument for 'A' required here}} // expected-note@#cwg402-D-type {{implicitly declared private here}} + // expected-note@#cwg401-A {{template parameter is declared here}} class B { protected: typedef int type; // #cwg402-B-type @@ -80,8 +83,9 @@ namespace cwg401 { // cwg401: 2.8 // to not treat the default template argument as a SFINAE context in C++98. template void f(T) {} // #cwg402-f // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}} - // cxx98-error@-2 {{'type' is a protected member of 'cwg401::B'}} - // cxx98-note@-3 {{in instantiation of default argument for 'f' required here}} + // cxx98-note@-2 {{template parameter is declared here}} + // cxx98-error@-3 {{'type' is a protected member of 'cwg401::B'}} + // cxx98-note@-4 {{in instantiation of default argument for 'f' required here}} // cxx98-note@#cwg402-f-b {{while substituting deduced template arguments into function template 'f' [with T = B, U = (no value)]}} // cxx98-note@#cwg402-B-type {{declared protected here}} void g(B b) { f(b); } // #cwg402-f-b @@ -636,15 +640,17 @@ namespace cwg431 { // cwg431: 2.8 } // namespace cwg431 namespace cwg432 { // cwg432: 3.0 - template struct A {}; + template struct A {}; // #cwg432-A template struct B : A {}; // expected-error@-1 {{use of class template 'B' requires template arguments}} - // expected-note@-2 {{template is declared here}} + // expected-note@#cwg432-A {{template parameter is declared here}} + // expected-note@-3 {{template is declared here}} template struct C : A > {}; #if __cplusplus >= 201103L template struct D : decltype(A()) {}; // since-cxx11-error@-1 {{use of class template 'D' requires template arguments}} - // since-cxx11-note@-2 {{template is declared here}} + // since-cxx11-note@#cwg432-A {{template parameter is declared here}} + // since-cxx11-note@-3 {{template is declared here}} #endif } // namespace cwg432 @@ -1377,6 +1383,7 @@ namespace cwg487 { // cwg487: 2.7 namespace cwg488 { // cwg488: 2.9 c++11 template void f(T); + // cxx98-note@-1 {{template parameter is declared here}} void f(int); void g() { // FIXME: It seems CWG thought this should be a SFINAE failure prior to diff --git a/clang/test/CXX/drs/cwg6xx.cpp b/clang/test/CXX/drs/cwg6xx.cpp index fb6acde459d9c..11a77575c70c1 100644 --- a/clang/test/CXX/drs/cwg6xx.cpp +++ b/clang/test/CXX/drs/cwg6xx.cpp @@ -79,10 +79,11 @@ namespace cwg602 { // cwg602: 2.7 } // namespace cwg602 namespace cwg603 { // cwg603: 3.1 - template struct S {}; + template struct S {}; // #cwg603-S typedef S<'\001'> S1; typedef S<(1ul << __CHAR_BIT__) + 1> S1; // since-cxx11-error@-1 {{non-type template argument evaluates to 257, which cannot be narrowed to type 'unsigned char'}} + // since-cxx11-note@#cwg603-S {{template parameter is declared here}} } // namespace cwg603 // cwg604: na @@ -407,7 +408,7 @@ namespace cwg638 { // cwg638: no class X { typedef int type; - template friend struct A::B; + template friend struct A::B; // expected-warning@-1 {{dependent nested name specifier 'A::' for friend class declaration is not supported; turning off access control for 'X'}} template friend void A::f(); // expected-warning@-1 {{dependent nested name specifier 'A::' for friend class declaration is not supported; turning off access control for 'X'}} @@ -1078,7 +1079,7 @@ namespace cwg677 { // cwg677: no struct A { void *operator new(std::size_t); void operator delete(void*) = delete; // #cwg677-A-delete - // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} }; struct B { void *operator new(std::size_t); diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp index 3eedef3cf7712..f40e1af14d111 100644 --- a/clang/test/CXX/expr/expr.const/p3-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp @@ -4,7 +4,7 @@ // A converted constant expression of type T is a core constant expression, int nonconst = 8; // expected-note 3 {{here}} enum NonConstE : unsigned char { NCE = nonconst }; // expected-error {{enumerator value is not a constant expression}} expected-note {{read of non-const}} -template struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}} +template struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}} expected-note {{template parameter is declared here}} void NonConstF() { switch (nonconst) { case nonconst: // expected-error {{case value is not a constant expression}} expected-note {{read of non-const}} @@ -66,7 +66,7 @@ enum class EEE : unsigned short { e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}} f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}} }; -template using A = int; // cxx17-note 2{{template parameter is declared here}} +template using A = int; // expected-note 4{{template parameter is declared here}} using Int = A; using Int = A; // expected-error {{not implicitly convertible}} @@ -79,7 +79,8 @@ using Int = A<-3>; // expected-error {{template argument evaluates to -3, which // integral conversions as well as boolean conversions. // FIXME: Per core issue 1407, this is not correct. template struct Val { static constexpr T value = v; }; -// cxx17-note@-1 2{{template parameter is declared here}} +// cxx17-note@-1 1{{template parameter is declared here}} +// expected-note@-2 2{{template parameter is declared here}} static_assert(Val::value == 1, ""); // ok static_assert(Val::value == 0, ""); // ok static_assert(Val::value == 1, ""); // ok diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp index 5433cfb21955d..2572e766cb263 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp @@ -77,7 +77,7 @@ using r2i3 = r2; // expected-error{{constraints not satisfied for clas namespace ns2 { template struct identity {}; - template requires requires { typename identity; } // expected-note 2{{because 'typename identity' would be invalid: too few template arguments for class template 'identity'}} + template requires requires { typename identity; } // expected-note 2{{because 'typename identity' would be invalid: missing template argument for template parameter}} struct r4 {}; using r4i1 = r4; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = ]}} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp index 692958ef565cf..332f69bacb69e 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp @@ -9,7 +9,7 @@ template struct IP { // expected-note 6 {{template parameter is declar IP *ip2; }; -template struct IR {}; +template struct IR {}; // expected-note {{template parameter is declared here}} constexpr std::nullptr_t get_nullptr() { return nullptr; } diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp index 629000d88acc3..e979051e23419 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -31,16 +31,16 @@ namespace non_type_tmpl_param { // omitted if the name refers to a function or array and shall be omitted // if the corresopnding template-parameter is a reference; or namespace addr_of_obj_or_func { - template struct X0 { }; // expected-note 5{{here}} + template struct X0 { }; // expected-note 5{{here}} cxx17-note 2{{here}} #if __cplusplus >= 201103L // precxx17-note@-2 2{{template parameter is declared here}} #endif - template struct X1 { }; // cxx17-note {{here}} + template struct X1 { }; // cxx17-note {{here}} precxx17-note{{here}} #if __cplusplus <= 199711L // precxx17-note@-2 {{here}} #endif - template struct X2 { }; // expected-note 4{{here}} + template struct X2 { }; // expected-note 5{{here}} template struct X2k { }; // expected-note {{here}} template struct X3 { }; // expected-note 4{{here}} @@ -180,6 +180,7 @@ namespace addr_of_obj_or_func { namespace bad_args { template struct X0 { }; // precxx17-note 4{{template parameter is declared here}} + // cxx17-note@-1 3{{template parameter is declared here}} int i = 42; X0<&i + 2> x0a; // precxx17-error{{non-type template argument does not refer to any declaration}} \ cxx17-error {{non-type template argument is not a constant expression}} \ diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp index 034ad49d0715c..bb7512a95ed3b 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -48,9 +48,9 @@ namespace pointer_to_object_parameters { X(int, int); operator int() const; }; - - template struct A2; // expected-note 0-1{{template parameter is declared here}} - + + template struct A2; // expected-note 1-2{{template parameter is declared here}} + X *X_ptr; // expected-note 0-1{{declared here}} X an_X; X array_of_Xs[10]; @@ -131,16 +131,16 @@ namespace reference_parameters { S3 s3v; S3 s3cv; } - + namespace PR6250 { template void inc() { ref++; // expected-error{{read-only variable is not assignable}} } - + template void bind() { T &ref2 = ref; // expected-error{{drops 'const' qualifier}} } - + int counter; void test() { inc(); // expected-note{{instantiation of}} @@ -213,7 +213,7 @@ namespace reference_to_function { // (13.4). namespace pointer_to_member_function { struct X { }; - struct Y : X { + struct Y : X { int f(int); int g(int); int g(float); diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp index 3caed045c6688..2638bef8f20a0 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp @@ -20,39 +20,39 @@ eval> eE; // expected-error{{implicit instantiation of undefined t template< template // expected-error {{cannot be narrowed from type 'int' to 'short'}} // expected-error@-1 {{conversion from 'int' to 'void *' is not allowed in a converted constant expression}} - class TT // expected-note 2{{previous template template parameter is here}} + class TT // expected-note 2{{template parameter is declared here}} > struct X0 { }; template struct X0a; template struct X0b; template struct X0c; -template struct X0d; -template struct X0e; // expected-note{{template parameter is declared here}} +template struct X0d; // expected-note {{template parameter is declared here}} +template struct X0e; // expected-note {{template parameter is declared here}} X0 inst_x0a; X0 inst_x0b; X0 inst_x0c; -X0 inst_x0d; // expected-note {{has different template parameters}} -X0 inst_x0e; // expected-note{{template template argument has different template parameters than its corresponding template template parameter}} +X0 inst_x0d; // expected-note {{template template argument is incompatible}} +X0 inst_x0e; // expected-note {{template template argument is incompatible}} template // expected-error {{conversion from 'short' to 'void *' is not allowed in a converted constant expression}} // expected-error@-1 {{cannot be narrowed from type 'int' to 'short'}} - class TT // expected-note 2{{previous template template parameter is here}} + class TT // expected-note 2{{template parameter is declared here}} > struct X1 { }; template struct X1a; template struct X1b; template struct X1c; -template struct X1d; -template struct X1e; // expected-note{{template parameter is declared here}} +template struct X1d; // expected-note {{template parameter is declared here}} +template struct X1e; // expected-note {{template parameter is declared here}} X1 inst_x1a; X1 inst_x1b; X1 inst_x1c; X1 inst_sx1d; -X1 inst_ix1d; // expected-note {{has different template parameters}} -X1 inst_x1e; // expected-note {{has different template parameters}} +X1 inst_ix1d; // expected-note {{template template argument is incompatible}} +X1 inst_x1e; // expected-note {{template template argument is incompatible}} template class X2; // expected-note{{template is declared here}} \ // expected-note{{template is declared here}} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp index 342ffba53dbfa..5570a7f9d75de 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp @@ -13,12 +13,12 @@ template struct W { }; // #W S1 s11; S1 s12; // expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}} -// expected-note@#S1 {{'P' declared here}} +// expected-note@#S1 {{template parameter is declared here}} // expected-note@#Y {{'Y' declared here}} S1 s13; S1 s14; // expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}} -// expected-note@#S1 {{'P' declared here}} +// expected-note@#S1 {{template parameter is declared here}} // expected-note@#W {{'W' declared here}} // expected-note@#F 1-2{{similar constraint expressions not considered equivalent}} // expected-note@#C 1-2{{similar constraint}} @@ -43,12 +43,12 @@ template requires C class P> struct S4 { }; // #S4 S4 s41; S4 s42; // expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}} -// expected-note@#S4 {{'P' declared here}} +// expected-note@#S4 {{template parameter is declared here}} // expected-note@#Y {{'Y' declared here}} S4 s43; S4 s44; // expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}} -// expected-note@#S4 {{'P' declared here}} +// expected-note@#S4 {{template parameter is declared here}} // expected-note@#W {{'W' declared here}} template requires C typename U> struct S5 { diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp index 650f8585b115a..65f3e178ac963 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wvla %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s template struct A { @@ -13,7 +13,8 @@ template struct B { }; B b; // expected-note{{instantiation of}} -template int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}} +template // #f0-temphead +int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}} enum {e}; // expected-note@-1 {{unnamed type used in template argument was declared here}} @@ -22,6 +23,7 @@ void test_f0(int n) { // #here #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#f0-temphead {{template parameter is declared here}} #endif int vla[n]; // expected-warning {{variable length arrays in C++ are a Clang extension}} @@ -33,9 +35,9 @@ void test_f0(int n) { // #here } namespace N0 { - template void f0(R (*)(A1)); - template int f1(T); - template int f1(T, U); + template void f0(R (*)(A1)); // #f0 + template int f1(T); // #f1-1 + template int f1(T, U); // #f1-2 enum {e1}; #if __cplusplus <= 199711L // expected-note@-2 2{{unnamed type used in template argument was declared here}} @@ -51,7 +53,7 @@ namespace N0 { // expected-note@-2 {{unnamed type used in template argument was declared here}} #endif - template struct X; + template struct X; // cxx98-note {{template parameter is declared here}} template struct X { }; void f() { @@ -59,24 +61,28 @@ namespace N0 { #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#f0 {{template parameter is declared here}} #endif &f1<__typeof__(e1)>); #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting explicitly-specified template arguments}} + // expected-note@#f1-1 {{template parameter is declared here}} #endif int (*fp1)(int, __typeof__(e2)) = f1; #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#f1-2 {{template parameter is declared here}} #endif f1(e2); #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#f1-1 {{template parameter is declared here}} #endif f1(e2); diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp index 388a80ee765c8..cf01e406c14ad 100644 --- a/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp @@ -25,7 +25,7 @@ template struct X { template static int y; // expected-error 3{{cannot be deduced}} expected-note 3{{'Inner'}} template static int y; // expected-error {{does not specialize}} - template static int z; + template static int z; // expected-note {{template parameter is declared here}} template static int z; // expected-error {{not implicitly convertible}} }; template template int X::y; // expected-error {{cannot be deduced}} expected-note {{'Inner'}} @@ -33,4 +33,4 @@ template template int X::y; // exp template<> template int X::y; // expected-error {{does not specialize}} expected-note {{instantiation of}} X xi; -X xf; // expected-note {{instantiation of}} +X xf; // expected-note 2{{instantiation of}} diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp index ab4c663d24c7d..cab5c967b0c4f 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp @@ -14,10 +14,10 @@ struct is_same { }; namespace ExpandIntoFixed { - template, - typename W = V*> + template, + typename W = V*> class X0 { }; template @@ -26,24 +26,24 @@ namespace ExpandIntoFixed { typedef X0 type; }; - static_assert(is_same::type, + static_assert(is_same::type, X0, pair*>>::value, "fails with two default arguments"); - static_assert(is_same::type, + static_assert(is_same::type, X0>::value, "fails with one default argument"); - static_assert(is_same::type, + static_assert(is_same::type, X0>::value, "fails with no default arguments"); } namespace ExpandIntoFixedShifted { - template, - typename W = V*> + template, + typename W = V*> class X0 { }; template @@ -52,15 +52,15 @@ namespace ExpandIntoFixedShifted { typedef X0 type; }; - static_assert(is_same::type, + static_assert(is_same::type, X0, pair*>>::value, "fails with two default arguments"); - static_assert(is_same::type, + static_assert(is_same::type, X0>::value, "fails with one default argument"); - static_assert(is_same::type, + static_assert(is_same::type, X0>::value, "fails with no default arguments"); } @@ -76,11 +76,11 @@ namespace Deduction { } namespace PR9021a { - template + template struct A { }; template - struct B { + struct B { A a1; }; @@ -93,9 +93,9 @@ namespace PR9021b { template struct t2 { - + }; - + template class M> struct m { @@ -107,14 +107,14 @@ namespace PR9021b { } namespace PartialSpecialization { - template - struct X0; // expected-note 2{{template is declared here}} + template // expected-note {{template parameter is declared here}} + struct X0; // expected-note {{template is declared here}} template struct X0 { // expected-error {{class template partial specialization is not more specialized than the primary template}} }; - X0 x0i; // expected-error{{too few template arguments for class template 'X0'}} + X0 x0i; // expected-error{{missing template argument for template parameter}} X0 x0if; X0 x0ifd; } diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp index 30e7c65dac91c..c6e6038fb6ddf 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp @@ -48,7 +48,7 @@ namespace PacksAtDifferentLevels { int check1[X::Inner, pair, pair> - >::value == 1? 1 : -1]; + >::value == 1? 1 : -1]; template struct unsigned_tuple { }; template @@ -99,7 +99,7 @@ namespace PacksAtDifferentLevels { int check5[X2::Inner, pair, pair) - >::value == 1? 1 : -1]; + >::value == 1? 1 : -1]; template struct some_function_object { @@ -217,8 +217,8 @@ namespace ExpandingNonTypeTemplateParameters { template struct tuple_of_values { template // expected-error{{a non-type template parameter cannot have type 'float'}} \ - // expected-note{{template parameter is declared here}} - struct apply { // expected-note 2{{template is declared here}} + // expected-note 2{{template parameter is declared here}} + struct apply { // expected-note {{template is declared here}} typedef tuple...> type; }; }; @@ -236,7 +236,7 @@ namespace ExpandingNonTypeTemplateParameters { tuple_of_values::apply::type tv2; // expected-error{{non-type template parameter of reference type 'float &' cannot bind to template argument of type 'int'}} - tuple_of_values::apply::type tv3; // expected-error{{too few template arguments for class template 'apply'}} + tuple_of_values::apply::type tv3; // expected-error{{missing template argument for template parameter}} tuple_of_values::apply::type tv4; // expected-error{{too many template arguments for class template 'apply'}} } diff --git a/clang/test/CXX/temp/temp.deduct/p9.cpp b/clang/test/CXX/temp/temp.deduct/p9.cpp index 7b661c275211b..5f9ea27234c81 100644 --- a/clang/test/CXX/temp/temp.deduct/p9.cpp +++ b/clang/test/CXX/temp/temp.deduct/p9.cpp @@ -15,13 +15,14 @@ void test_f() { } template +// expected-note@-1 {{template parameter is declared here}} void g(T); void g(...); void test_g() { - g(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}} + g(0); // expected-error@-5 {{type 'int' cannot be used prior to '::'}} // expected-note@-4 {{in instantiation of default argument}} // expected-note@-2 {{while substituting deduced template arguments}} - // expected-note@-7 {{while substituting into a lambda expression here}} + // expected-note@-8 {{while substituting into a lambda expression here}} } template diff --git a/clang/test/CXX/temp/temp.param/p1.cpp b/clang/test/CXX/temp/temp.param/p1.cpp index e9a978961769c..e2eecdf0d4554 100644 --- a/clang/test/CXX/temp/temp.param/p1.cpp +++ b/clang/test/CXX/temp/temp.param/p1.cpp @@ -5,8 +5,9 @@ template class C> class D; // expected-error{{template template param struct A {}; -template // expected-error{{template parameter missing a default argument}} -class X0 {}; // expected-note{{template is declared here}} -X0 x0; // expected-error{{too few template arguments for class template 'X0'}} +class X0 {}; +X0 x0; // expected-error{{missing template argument for template parameter}} diff --git a/clang/test/CXX/temp/temp.param/p12.cpp b/clang/test/CXX/temp/temp.param/p12.cpp index 8317e7f24152c..e3dfb65d29461 100644 --- a/clang/test/CXX/temp/temp.param/p12.cpp +++ b/clang/test/CXX/temp/temp.param/p12.cpp @@ -32,9 +32,9 @@ template class =// expected-note {{previous template template parameter is here}} +template class =// expected-note {{template parameter is declared here}} Y1> // expected-error{{too many template arguments for class template 'Y1'}} - // expected-note@-1 {{template template argument has different template parameters than its corresponding template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} class C1 {}; C1<> c1; // expected-note{{while checking a default template argument}} diff --git a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp index 83144a494937b..402a205f1ea63 100644 --- a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp +++ b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp @@ -77,9 +77,9 @@ template struct wrap { template struct takedrop_impl; template struct takedrop_impl> { - template class ...Take, + template class ...Take, // expected-note 2{{template parameter is declared here}} template class ...Drop> - struct inner { // expected-note 2{{declared}} + struct inner { typedef types::type...> take; typedef types::type...> drop; }; @@ -87,11 +87,11 @@ template struct takedrop_impl> { template struct take { using type = typename takedrop_impl::type>:: - template inner::template inner...>::take; // expected-error {{too few template arguments}} + template inner::template inner...>::take; // expected-error {{missing template argument}} }; template struct drop { using type = typename takedrop_impl::type>:: - template inner::template inner...>::drop; // expected-error {{too few template arguments}} + template inner::template inner...>::drop; // expected-error {{missing template argument}} }; using T1 = take<3, int, char, double, long>::type; // expected-note {{previous}} @@ -118,7 +118,7 @@ using D3 = drop<5, int, char, double, long>::type; // expected-note {{in instant // implicitly a pack expansion. template struct DefArg { template class ...Classes> struct Inner { // expected-error {{default argument contains unexpanded parameter pack}} expected-note {{here}} - Inner(Classes<>...); // expected-error {{too few}} + Inner(Classes<>...); // expected-error {{missing template argument}} }; }; template struct vector {}; diff --git a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp index a3478c0669661..aa1666f6306d0 100644 --- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp +++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp @@ -59,7 +59,7 @@ namespace ConstDestruction { f(); } - template struct Z {}; + template struct Z {}; // expected-note {{template parameter is declared here}} Z z1; Z z2; // expected-error {{non-type template argument is not a constant expression}} expected-note-re {{in call to '{{.*}}.~D()'}} } diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp index ecb82372bcb47..cb048ecdf7001 100644 --- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp +++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp @@ -2,7 +2,7 @@ // RUN: %clang_cc1 -std=c++11 -verify=cxx11 %s // cxx11-no-diagnostics -template struct S; +template struct S; // cxx98-note {{template parameter is declared here}} template struct T { T() { diff --git a/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp b/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp index 741ebc5de41fc..749b45524f9e6 100644 --- a/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp +++ b/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp @@ -3,27 +3,27 @@ // RUN: not %clang_cc1 --std=c++1y -x c++ -fixit %t -DFIXING // RUN: %clang_cc1 --std=c++1y -x c++ %t -DFIXING -template -T pi = T(3.1415926535897932385); // expected-note {{template is declared here}} +template // expected-note {{template parameter is declared here}} +T pi = T(3.1415926535897932385); template int pi; #ifndef FIXING -template float pi<>; // expected-error {{too few template arguments for variable template 'pi'}} +template float pi<>; // expected-error {{missing template argument for template parameter}} template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}} #endif // Should recover as if definition template double pi_var = 5; // expected-error {{variable cannot be defined in an explicit instantiation; if this declaration is meant to be a variable definition, remove the 'template' keyword}} #ifndef FIXING -template +template T pi0 = T(3.1415926535897932385); // expected-note {{previous definition is here}} template int pi0 = 10; // expected-error {{variable cannot be defined in an explicit instantiation; if this declaration is meant to be a variable definition, remove the 'template' keyword}} \ expected-error{{redefinition of 'pi0' as different kind of symbol}} #endif -template +template T pi1 = T(3.1415926535897932385); // expected-note 0-2 {{here}} // Should recover as if specialization diff --git a/clang/test/CXX/temp/temp.spec/part.spec.cpp b/clang/test/CXX/temp/temp.spec/part.spec.cpp index 4b0fdb902633a..3923d160ef5cf 100644 --- a/clang/test/CXX/temp/temp.spec/part.spec.cpp +++ b/clang/test/CXX/temp/temp.spec/part.spec.cpp @@ -250,7 +250,7 @@ template class PCT1 {}; template class PCT2 {}; template class PCT3 {}; template class PCT4 {}; -template class PCT5 {}; +template class PCT5 {}; // expected-note {{template parameter is declared here}} template class PCT6 { // expected-note@+1 3{{implicitly declared private here}} template class NPCT1 {}; @@ -416,7 +416,7 @@ template class PCTT1 {}; template class PCTT2 {}; template class PCTT3 {}; template class PCTT4 {}; -template class PCTT5 {}; +template class PCTT5 {}; // expected-note {{template parameter is declared here}} template class PCTT6 { template class NCT1 {}; template class NCT2; // forward declaration diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp index 0283dba63b110..63fd997add4ec 100644 --- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp +++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp @@ -2,13 +2,13 @@ template void f(T); -template -struct A { }; // expected-note{{template is declared here}} +template // expected-note {{template parameter is declared here}} +struct A { }; struct X { template<> friend void f(int); // expected-error{{in a friend}} template<> friend class A; // expected-error{{cannot be a friend}} - + friend void f(float); // okay friend class A; // okay }; @@ -18,6 +18,6 @@ struct PR41792 { template <> friend void f<>(int); // expected-error@+2{{template specialization declaration cannot be a friend}} - // expected-error@+1{{too few template arguments for class template 'A'}} + // expected-error@+1{{missing template argument for template parameter}} template <> friend class A<>; }; diff --git a/clang/test/Misc/integer-literal-printing.cpp b/clang/test/Misc/integer-literal-printing.cpp index bd231a368fb70..bc52b3f044679 100644 --- a/clang/test/Misc/integer-literal-printing.cpp +++ b/clang/test/Misc/integer-literal-printing.cpp @@ -14,6 +14,7 @@ enum class boolTy : bool { template struct Type3Helper; template <> struct Type3Helper { typedef boolTy Ty; }; template ::Ty U> struct Type3 {}; +// expected-note@-1 {{template parameter is declared here}} // PR14386 enum class charTy : char { @@ -23,6 +24,7 @@ enum class charTy : char { template struct Type4Helper; template <> struct Type4Helper { typedef charTy Ty; }; template ::Ty U> struct Type4 {}; +// expected-note@-1 {{template parameter is declared here}} enum class scharTy : signed char { c = 0, @@ -31,6 +33,7 @@ enum class scharTy : signed char { template struct Type5Helper; template <> struct Type5Helper { typedef scharTy Ty; }; template ::Ty U> struct Type5 {}; +// expected-note@-1 {{template parameter is declared here}} enum class ucharTy : unsigned char { c = 0, @@ -39,6 +42,7 @@ enum class ucharTy : unsigned char { template struct Type6Helper; template <> struct Type6Helper { typedef ucharTy Ty; }; template ::Ty U> struct Type6 {}; +// expected-note@-1 {{template parameter is declared here}} enum class wcharTy : wchar_t { c = 0, @@ -47,6 +51,7 @@ enum class wcharTy : wchar_t { template struct Type7Helper; template <> struct Type7Helper { typedef wcharTy Ty; }; template ::Ty U> struct Type7 {}; +// expected-note@-1 {{template parameter is declared here}} enum class char16Ty : char16_t { c = 0, @@ -55,6 +60,7 @@ enum class char16Ty : char16_t { template struct Type8Helper; template <> struct Type8Helper { typedef char16Ty Ty; }; template ::Ty U> struct Type8 {}; +// expected-note@-1 {{template parameter is declared here}} enum class char32Ty : char16_t { c = 0, @@ -63,6 +69,7 @@ enum class char32Ty : char16_t { template struct Type9Helper; template <> struct Type9Helper { typedef char32Ty Ty; }; template ::Ty U> struct Type9 {}; +// expected-note@-1 {{template parameter is declared here}} void Function() { Function1(Type1<-42>()); // expected-error{{no matching function for call to 'Function1'}} diff --git a/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp b/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp index 73dff88e506b4..250b54ade0ecb 100644 --- a/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp +++ b/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp @@ -11,7 +11,7 @@ //--- mod.cppm export module mod; -template +template // expected-note 2{{template parameter is declared here}} concept ReferenceOf = Q; // expected-error@+2 {{unknown type name 'AngleIsInvalidNow'}} diff --git a/clang/test/Modules/missing-body-in-import.cpp b/clang/test/Modules/missing-body-in-import.cpp index b52ebba15087a..e25f7b5921301 100644 --- a/clang/test/Modules/missing-body-in-import.cpp +++ b/clang/test/Modules/missing-body-in-import.cpp @@ -29,6 +29,7 @@ export module mod2; import mod1; struct C: B { // expected-error {{non-type template argument is not a constant expression}} + // expected-note@mod1.cppm:11 {{template parameter is declared here}} constexpr C(int a) { } }; diff --git a/clang/test/Modules/template-default-args.cpp b/clang/test/Modules/template-default-args.cpp index 85b2a18d9e506..1d8de709fd598 100644 --- a/clang/test/Modules/template-default-args.cpp +++ b/clang/test/Modules/template-default-args.cpp @@ -22,7 +22,7 @@ template struct B; template struct C; template struct D {}; template struct F {}; -template struct G {}; +template struct G {}; // #G template struct J {}; template struct J; struct K : J<> {}; @@ -39,8 +39,10 @@ E<> e; F<> f; G<> g; // expected-error {{missing '#include "a.h"'; default argument of 'G' must be defined before it is used}} // expected-note@a.h:7 {{default argument declared here is not reachable}} +// expected-note@#G {{template parameter is declared here}} H<> h; // expected-error {{missing '#include "a.h"'; default argument of 'H' must be defined before it is used}} // expected-note@a.h:8 {{default argument declared here is not reachable}} +// expected-note@a.h:8 {{template parameter is declared here}} I<> i; L<> *l; END diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp index 9102bca8f6bb2..e47b4ef78afdf 100644 --- a/clang/test/Parser/MicrosoftExtensions.cpp +++ b/clang/test/Parser/MicrosoftExtensions.cpp @@ -126,7 +126,7 @@ void template_uuid() } -template // expected-note {{template parameter is declared here}} +template // expected-note 2{{template parameter is declared here}} class COM_CLASS_TEMPLATE { }; typedef COM_CLASS_TEMPLATE COM_TYPE_1; // expected-warning {{non-type template argument containing a dereference operation is a Microsoft extension}} diff --git a/clang/test/Parser/cxx-template-argument.cpp b/clang/test/Parser/cxx-template-argument.cpp index 3c2169f86d6e7..ffe53e7c6f77e 100644 --- a/clang/test/Parser/cxx-template-argument.cpp +++ b/clang/test/Parser/cxx-template-argument.cpp @@ -57,9 +57,9 @@ namespace PR13210 { // Don't emit spurious messages namespace pr16225add { - template struct Known { }; // expected-note 3 {{template is declared here}} + template struct Known { }; // expected-note 3{{template parameter is declared here}} template struct X; - template struct ABC; // expected-note {{template is declared here}} + template struct ABC; // expected-note {{template parameter is declared here}} template struct ABC2 {}; template struct foo : @@ -68,7 +68,7 @@ namespace pr16225add { template struct foo2 : UnknownBase, // expected-error {{no template named 'UnknownBase'}} - Known // expected-error {{too few template arguments for class template 'Known'}} + Known // expected-error {{missing template argument for template parameter}} { }; template struct foo3 : @@ -76,8 +76,8 @@ namespace pr16225add { { }; template struct foo4 : - UnknownBase >, // expected-error {{too few template arguments for class template 'ABC'}} - Known // expected-error {{too few template arguments for class template 'Known'}} + UnknownBase >, // expected-error {{missing template argument for template parameter}} + Known // expected-error {{missing template argument for template parameter}} { }; template struct foo5 : @@ -92,7 +92,7 @@ namespace pr16225add { #if __cplusplus <= 199711L // expected-error@-2 {{use '> >'}} #endif - Known // expected-error {{too few template arguments for class template 'Known'}} + Known // expected-error {{missing template argument for template parameter}} { }; template struct foo7 : diff --git a/clang/test/Parser/cxx-template-template-recovery.cpp b/clang/test/Parser/cxx-template-template-recovery.cpp index 5700b160cd364..2ece5a8ccdbea 100644 --- a/clang/test/Parser/cxx-template-template-recovery.cpp +++ b/clang/test/Parser/cxx-template-template-recovery.cpp @@ -1,33 +1,33 @@ // RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only %s namespace a { - template - concept C1 = true; // #C1 + template // #C1-T + concept C1 = true; template auto V1 = true; // #V1 namespace b { - template - concept C2 = true; // #C2 + template // #C2-T + concept C2 = true; template auto V2 = true; // #V2 } } -template -concept C3 = true; // #C3 +template // #C3-T +concept C3 = true; template auto V3 = true; // #V3 template