diff options
author | Matheus Izvekov <mizvekov@gmail.com> | 2025-01-31 17:51:18 -0300 |
---|---|---|
committer | Matheus Izvekov <mizvekov@gmail.com> | 2025-03-10 10:24:15 -0300 |
commit | 32717ea294ec6a84dede63be9c8f9da93155c21f (patch) | |
tree | 36d5d6cd776baf1129ed0ca91faf44e0ade8e844 | |
parent | 773e88f9d61399c566fed45bf7858922f09b8063 (diff) | |
download | llvm-users/mizvekov/clang-check-template-parameter-eval-context.zip llvm-users/mizvekov/clang-check-template-parameter-eval-context.tar.gz llvm-users/mizvekov/clang-check-template-parameter-eval-context.tar.bz2 |
Reland: [clang] Implement evaluation context for checking template parametersusers/mizvekov/clang-check-template-parameter-eval-context
Instead of manually adding a note pointing to the relevant template
parameter to every relevant error, which is very easy to miss,
this patch adds a new instantiation context note, so that this
can work using RAII magic.
This fixes a bunch of places where these notes were missing, and is
more future-proof.
Some diagnostics are reworked to make better use of this note:
- Errors about missing template arguments now refer to the parameter
which is missing an argument.
- Template Template parameter mismatches now refer to template
parameters as parameters instead of arguments.
It's likely this will add the note to some diagnostics where the
parameter is not super relevant, but this can be reworked with time
and the decrease in maintenance burden makes up for it.
This bypasses the templight dumper for the new context entry, as the
tests are very hard to update.
This depends on #125453, which is needed to avoid losing the context
note for errors occuring during template argument deduction.
Original PR: #126088
97 files changed, 633 insertions, 560 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 01b0188..748d683 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -300,6 +300,16 @@ Bug Fixes to C++ Support not in the last position. - Clang now correctly parses ``if constexpr`` expressions in immediate function context. (#GH123524) +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 eeb7e23..a32e9b3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5213,16 +5213,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">; @@ -5231,8 +5226,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< @@ -5323,10 +5316,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">; @@ -5364,11 +5362,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">; @@ -5933,10 +5928,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 9a312e1..d15630f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11828,7 +11828,7 @@ public: bool *ConstraintsNotSatisfied = nullptr); bool CheckTemplateTypeArgument( - TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg, + TemplateArgumentLoc &Arg, SmallVectorImpl<TemplateArgument> &SugaredConverted, SmallVectorImpl<TemplateArgument> &CanonicalConverted); @@ -11864,9 +11864,13 @@ public: 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<SourceRange> 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 @@ -11981,15 +11985,13 @@ public: 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. @@ -12869,6 +12871,11 @@ public: /// 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? @@ -13096,6 +13103,11 @@ public: 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(); @@ -13129,6 +13141,13 @@ public: 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 1ea4a2e..60e103e 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -403,7 +403,8 @@ public: } private: - static std::string toString(CodeSynthesisContext::SynthesisKind Kind) { + static std::optional<std::string> + toString(CodeSynthesisContext::SynthesisKind Kind) { switch (Kind) { case CodeSynthesisContext::TemplateInstantiation: return "TemplateInstantiation"; @@ -461,8 +462,10 @@ private: return "TypeAliasTemplateInstantiation"; case CodeSynthesisContext::PartialOrderingTTP: return "PartialOrderingTTP"; + case CodeSynthesisContext::CheckTemplateParameter: + return std::nullopt; } - return ""; + return std::nullopt; } template <bool BeginInstantiation> @@ -470,12 +473,14 @@ private: const CodeSynthesisContext &Inst) { std::string YAML; { + std::optional<TemplightEntry> Entry = + getTemplightEntry<BeginInstantiation>(TheSema, Inst); + if (!Entry) + return; llvm::raw_string_ostream OS(YAML); llvm::yaml::Output YO(OS); - TemplightEntry Entry = - getTemplightEntry<BeginInstantiation>(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 @@ private: } template <bool BeginInstantiation> - static TemplightEntry getTemplightEntry(const Sema &TheSema, - const CodeSynthesisContext &Inst) { + static std::optional<TemplightEntry> + getTemplightEntry(const Sema &TheSema, const CodeSynthesisContext &Inst) { TemplightEntry Entry; - Entry.Kind = toString(Inst.Kind); + std::optional<std::string> 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 56ec33f..edbd4c0 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -7271,7 +7271,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; @@ -7280,9 +7280,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 ceb32ee..4d278bb 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 aecf8ed..f3af5145 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1580,9 +1580,13 @@ llvm::DenseSet<Module*> &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 290862d..c97c0b1 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<NamedDecl>(PrevDecl); + auto *ND = cast<NamedDecl>(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) { @@ -4837,7 +4839,7 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S, } bool Sema::CheckTemplateTypeArgument( - TemplateTypeParmDecl *Param, TemplateArgumentLoc &AL, + TemplateArgumentLoc &AL, SmallVectorImpl<TemplateArgument> &SugaredConverted, SmallVectorImpl<TemplateArgument> &CanonicalConverted) { const TemplateArgument &Arg = AL.getArgument(); @@ -4893,7 +4895,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. @@ -4931,7 +4932,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; } @@ -5221,8 +5221,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, CheckTemplateArgumentInfo &CTAI, CheckTemplateArgumentKind CTAK) { // Check template type parameters. - if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) - return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI.SugaredConverted, + if (isa<TemplateTypeParmDecl>(Param)) + return CheckTemplateTypeArgument(ArgLoc, CTAI.SugaredConverted, CTAI.CanonicalConverted); const TemplateArgument &Arg = ArgLoc.getArgument(); @@ -5367,8 +5367,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: { @@ -5388,7 +5386,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; } @@ -5479,11 +5476,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, } /// Diagnose a missing template argument. -template<typename TemplateParmDecl> +template <typename TemplateParmDecl> 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<TemplateParmDecl>(cast<TemplateDecl>(TD->getMostRecentDecl()) @@ -5501,16 +5498,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; } @@ -5549,6 +5542,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. @@ -5585,11 +5580,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; } } @@ -5602,8 +5595,10 @@ bool Sema::CheckTemplateArgumentList( if (ArgIsExpansion && CTAI.MatchingTTP) { SmallVector<TemplateArgument, 4> 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() || @@ -5644,7 +5639,6 @@ bool Sema::CheckTemplateArgumentList( diag::err_template_expansion_into_fixed_list) << (isa<ConceptDecl>(Template) ? 1 : 0) << ArgLoc.getSourceRange(); - NoteTemplateParameterLocation(**Param); return true; } } @@ -5751,14 +5745,14 @@ bool Sema::CheckTemplateArgumentList( if (!HasDefaultArg) { if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) return diagnoseMissingArgument(*this, TemplateLoc, Template, TTP, - NewArgs); + NewArgs, CTAI.MatchingTTP); if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*Param)) return diagnoseMissingArgument(*this, TemplateLoc, Template, NTTP, - NewArgs); + NewArgs, CTAI.MatchingTTP); return diagnoseMissingArgument(*this, TemplateLoc, Template, cast<TemplateTemplateParmDecl>(*Param), - NewArgs); + NewArgs, CTAI.MatchingTTP); } return true; } @@ -5814,8 +5808,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()); @@ -6240,8 +6233,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; } @@ -6266,8 +6257,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; } @@ -6276,8 +6266,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; } @@ -6289,7 +6278,6 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), Code) << FixItHint::CreateInsertion(S.getLocForEndOfToken(Arg->getEndLoc()), ")"); - S.NoteTemplateParameterLocation(*Param); return NPV_NullPointer; } @@ -6330,7 +6318,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; } } @@ -6348,7 +6335,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; } } @@ -6491,7 +6477,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (!Entity) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref) << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6499,7 +6484,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (isa<FieldDecl>(Entity) || isa<IndirectFieldDecl>(Entity)) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_field) << Entity << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6508,7 +6492,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (!Method->isStatic()) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_method) << Method << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -6548,7 +6531,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; } @@ -6568,15 +6550,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(); } @@ -6597,15 +6576,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(), "&"); } } @@ -6721,7 +6697,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; } @@ -6827,7 +6802,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(); } } @@ -6836,10 +6810,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. @@ -6871,9 +6843,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(); } @@ -6968,10 +6938,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; } @@ -7118,7 +7086,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 { @@ -7156,7 +7123,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(); } @@ -7202,7 +7168,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. @@ -7213,12 +7178,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; @@ -7343,8 +7306,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: @@ -7372,7 +7334,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, @@ -7442,7 +7404,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); @@ -7451,25 +7412,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<SourceRange> 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"); @@ -7477,11 +7437,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) { @@ -7758,21 +7713,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); } @@ -7786,18 +7737,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<TemplateTypeParmDecl>(New)? 0 : isa<NonTypeTemplateParmDecl>(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(); } @@ -7818,13 +7762,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) @@ -7845,8 +7784,7 @@ static bool MatchTemplateParameterKind( OldTTP->getTemplateParameters(), Complain, (Kind == Sema::TPL_TemplateMatch ? Sema::TPL_TemplateTemplateParmMatch - : Kind), - TemplateArgLoc)) + : Kind))) return false; } @@ -7897,21 +7835,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()); @@ -7920,11 +7849,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; } @@ -7942,21 +7870,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; } @@ -8254,7 +8179,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; } } @@ -8278,6 +8202,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 e6ec4a7..a6090e4 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 19c27a7..847057a 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<NamedDecl>(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<TemplateDeductionInfo *> 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<ConstantExpr>(SubstReplacement.get())) SubstReplacement = TransformExpr(E->getReplacement()); diff --git a/clang/test/AST/ByteCode/cxx1z.cpp b/clang/test/AST/ByteCode/cxx1z.cpp index 57f9923..ca5f10f 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<typename T, T val> struct A {}; +template<typename T, T val> 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 06501de..d39c228 100644 --- a/clang/test/AST/ByteCode/cxx20.cpp +++ b/clang/test/AST/ByteCode/cxx20.cpp @@ -897,7 +897,7 @@ namespace VirtDtor { } namespace TemporaryInNTTP { - template<auto n> struct B { /* ... */ }; + template<auto n> 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 c17049b..9af6680 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<int n> struct S {}; + template<int n> struct S {}; // both-note {{template parameter is declared here}} S<p> 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 42b6d82..d125fb0 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 <typename T, auto Q> + template <typename T, auto Q>// 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<ReferenceOf<InvalidCtor> 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 9632fda..fc4e359 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 <class T> struct bar {}; + // expected-note@-1 {{template parameter is declared here}} template <class T> struct foo : bar<foo> {}; // 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 2bceb3e..57c9921 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<int> *c, int Agg<int>::*d) { Agg<bool> tc = {c}; // expected-error {{cannot be narrowed}} expected-note {{}} Agg<bool> td = {d}; // expected-error {{cannot be narrowed}} expected-note {{}} } -template<bool> struct BoolParam {}; +template<bool> 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 282e71b..c035aa3 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<typename T> struct X {}; - template<typename T> T get() { return get<T>(); } - template<typename T> int take(T) { return 0; } + template<typename T> struct X {}; // #cwg62-X + template<typename T> T get() { return get<T>(); } // #cwg62-get + template<typename T> int take(T) { return 0; } // #cwg62-take X<A> x1; A a = get<A>(); @@ -1034,22 +1035,27 @@ namespace cwg62 { // cwg62: 2.9 X<NoNameForLinkagePtr> 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<const NoNameForLinkagePtr> 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<NoNameForLinkagePtr>(); // 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<const NoNameForLinkagePtr>(); // 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<Danger> x4; @@ -1057,18 +1063,24 @@ namespace cwg62 { // cwg62: 2.9 struct NoLinkage {}; X<NoLinkage> a; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} X<const NoLinkage> b; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} get<NoLinkage>(); // 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<const NoLinkage>(); // 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<void (*)(NoLinkage A::*)> c; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} X<int NoLinkage::*> 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<char>(); // cxx98-error@-1 {{extern templates are a C++11 extension}} // expected-error@-2 {{explicit instantiation declaration of 'f' with internal linkage}} - template<void(*)()> struct Q {}; + template<void(*)()> struct Q {}; // #cwg69-Q Q<&f<int> > q; // cxx98-error@-1 {{non-type template argument referring to function 'f<int>' 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 c5b96c4..10ee505 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 T, template<class> 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<A<int> > t; // #cwg1004-t } // namespace cwg1004 diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp index 9c72fef..8a9f285 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 <typename T, int I> struct C; + // expected-note@-1 {{template parameter is declared here}} template <typename T> struct C<T, T::value>; // 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 5b4551b..2b635af 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -26,6 +26,7 @@ S<i> 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 diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index 4a5394b..e59bc71 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<const volatile T*> struct X {}; + template<const volatile T*> struct X {}; // #cwg112-X // FIXME: Test this somehow in C++11 and on. X<a1> 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<a2> x2; X<a3> 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<a4> 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 @@ public: }; }; 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<template<typename TT> class T> void A<T>::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<template<typename TT = char> class T> void A<T>::g() { diff --git a/clang/test/CXX/drs/cwg20xx.cpp b/clang/test/CXX/drs/cwg20xx.cpp index 141a101..fd31a51f 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<int> struct X {}; + template<int> 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 42a7c4d..97bf320 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<const int *P, bool = true> struct X {}; + template<const int *P, bool = true> struct X {}; // #cwg2100-X template<typename T> 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<const int *P> struct X<P> { diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp index 164cc26..424f73a 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<typename> struct X {}; + template<typename> struct X {}; // #cwg319-X void f() { struct A { int n; }; extern A a; // FIXME: ill-formed X<A> 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<B> 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<typename> struct T {}; + template<typename> struct T {}; // #cwg389-T struct WithLinkage1 {}; enum WithLinkage2 {}; @@ -1543,18 +1546,23 @@ namespace cwg389 { // cwg389: no typedef T<WithoutLinkage1> 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<WithoutLinkage2> 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<WithoutLinkage3> 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<WithoutLinkage4> 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<WithoutLinkage5> 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 d76c601..6a46e2f 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<C>' 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<B>' 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<D>' 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<class T, class U = typename T::type> 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<B>' 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<B>' 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<typename T> struct A {}; + template<typename T> struct A {}; // #cwg432-A template<typename T> struct B : A<B> {}; // 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<typename T> struct C : A<C<T> > {}; #if __cplusplus >= 201103L template<typename T> struct D : decltype(A<D>()) {}; // 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 <typename T> 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 e2eb009..09ad567 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<unsigned char> struct S {}; + template<unsigned char> 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 diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp index 3eedef3..f40e1af 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<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}} +template<int = nonconst> 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<unsigned char> using A = int; // cxx17-note 2{{template parameter is declared here}} +template<unsigned char> using A = int; // expected-note 4{{template parameter is declared here}} using Int = A<E6>; using Int = A<EE::EE32>; // 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<typename T, T v> 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<bool, E1>::value == 1, ""); // ok static_assert(Val<bool, '\0'>::value == 0, ""); // ok static_assert(Val<bool, U'\1'>::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 5433cfb..2572e76 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<int, int>; // expected-error{{constraints not satisfied for clas namespace ns2 { template<typename T, typename U> struct identity {}; - template<typename... Ts> requires requires { typename identity<Ts...>; } // expected-note 2{{because 'typename identity<Ts...>' would be invalid: too few template arguments for class template 'identity'}} + template<typename... Ts> requires requires { typename identity<Ts...>; } // expected-note 2{{because 'typename identity<Ts...>' would be invalid: missing template argument for template parameter}} struct r4 {}; using r4i1 = r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int>]}} 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 692958e..332f69b 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<int *ip> struct IP { // expected-note 6 {{template parameter is declar IP<ip> *ip2; }; -template<int &ip> struct IR {}; +template<int &ip> 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 629000d..e979051 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 <int* p> struct X0 { }; // expected-note 5{{here}} + template <int* p> struct X0 { }; // expected-note 5{{here}} cxx17-note 2{{here}} #if __cplusplus >= 201103L // precxx17-note@-2 2{{template parameter is declared here}} #endif - template <int (*fp)(int)> struct X1 { }; // cxx17-note {{here}} + template <int (*fp)(int)> struct X1 { }; // cxx17-note {{here}} precxx17-note{{here}} #if __cplusplus <= 199711L // precxx17-note@-2 {{here}} #endif - template <int &p> struct X2 { }; // expected-note 4{{here}} + template <int &p> struct X2 { }; // expected-note 5{{here}} template <const int &p> struct X2k { }; // expected-note {{here}} template <int (&fp)(int)> struct X3 { }; // expected-note 4{{here}} @@ -180,6 +180,7 @@ namespace addr_of_obj_or_func { namespace bad_args { template <int* N> 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 034ad49..bb7512a 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<X const *Ptr> struct A2; // expected-note 0-1{{template parameter is declared here}} - + + template<X const *Ptr> 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<vi> s3v; S3<cvi> s3cv; } - + namespace PR6250 { template <typename T, const T &ref> void inc() { ref++; // expected-error{{read-only variable is not assignable}} } - + template<typename T, const T &ref> void bind() { T &ref2 = ref; // expected-error{{drops 'const' qualifier}} } - + int counter; void test() { inc<int, counter>(); // 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 3caed04..2638bef 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<E<int, float>> eE; // expected-error{{implicit instantiation of undefined t template< template <int ...N> // 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<int I, int J, int ...Rest> struct X0a; template<int ...Rest> struct X0b; template<int I, long J> struct X0c; -template<int I, short J> struct X0d; -template<int I, void *J> struct X0e; // expected-note{{template parameter is declared here}} +template<int I, short J> struct X0d; // expected-note {{template parameter is declared here}} +template<int I, void *J> struct X0e; // expected-note {{template parameter is declared here}} X0<X0a> inst_x0a; X0<X0b> inst_x0b; X0<X0c> inst_x0c; -X0<X0d> inst_x0d; // expected-note {{has different template parameters}} -X0<X0e> inst_x0e; // expected-note{{template template argument has different template parameters than its corresponding template template parameter}} +X0<X0d> inst_x0d; // expected-note {{template template argument is incompatible}} +X0<X0e> inst_x0e; // expected-note {{template template argument is incompatible}} template<typename T, template <T ...N> // 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<int I, int J, int ...Rest> struct X1a; template<long I, long ...Rest> struct X1b; template<short I, short J> struct X1c; -template<short I, long J> struct X1d; -template<short I, void *J> struct X1e; // expected-note{{template parameter is declared here}} +template<short I, long J> struct X1d; // expected-note {{template parameter is declared here}} +template<short I, void *J> struct X1e; // expected-note {{template parameter is declared here}} X1<int, X1a> inst_x1a; X1<long, X1b> inst_x1b; X1<short, X1c> inst_x1c; X1<short, X1d> inst_sx1d; -X1<int, X1d> inst_ix1d; // expected-note {{has different template parameters}} -X1<short, X1e> inst_x1e; // expected-note {{has different template parameters}} +X1<int, X1d> inst_ix1d; // expected-note {{template template argument is incompatible}} +X1<short, X1e> inst_x1e; // expected-note {{template template argument is incompatible}} template <int> 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 342ffba..5570a7f 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<F> struct W { }; // #W S1<X> s11; S1<Y> 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<Z> s13; S1<W> 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<template<typename T> requires C<T> class P> struct S4 { }; // #S4 S4<X> s41; S4<Y> 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<Z> s43; S4<W> 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<template<typename T> requires C<T> 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 650f858..65f3e17 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<class T> struct A { @@ -13,7 +13,8 @@ template<typename T> struct B { }; B<function> b; // expected-note{{instantiation of}} -template <typename T> int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}} +template <typename T> // #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 <typename R, typename A1> void f0(R (*)(A1)); - template <typename T> int f1(T); - template <typename T, typename U> int f1(T, U); + template <typename R, typename A1> void f0(R (*)(A1)); // #f0 + template <typename T> int f1(T); // #f1-1 + template <typename T, typename U> 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<typename T> struct X; + template<typename T> struct X; // cxx98-note {{template parameter is declared here}} template<typename T> struct X<T*> { }; 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 388a80e..cf01e40 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<typename Outer> struct X { template<typename Inner> static int y<Outer>; // expected-error 3{{cannot be deduced}} expected-note 3{{'Inner'}} template<typename Inner> static int y<Inner>; // expected-error {{does not specialize}} - template<typename, int> static int z; + template<typename, int> static int z; // expected-note {{template parameter is declared here}} template<Outer N> static int z<int, N>; // expected-error {{not implicitly convertible}} }; template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-error {{cannot be deduced}} expected-note {{'Inner'}} @@ -33,4 +33,4 @@ template<typename Outer> template<typename Inner> int X<Outer>::y<Inner>; // exp template<> template<typename Inner> int X<int>::y<Inner>; // expected-error {{does not specialize}} expected-note {{instantiation of}} X<int> xi; -X<int*> xf; // expected-note {{instantiation of}} +X<int*> 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 ab4c663d..cab5c96 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<T, T> { }; namespace ExpandIntoFixed { - template<typename T, - typename U, - typename V = pair<T, U>, - typename W = V*> + template<typename T, + typename U, + typename V = pair<T, U>, + typename W = V*> class X0 { }; template<typename ...Ts> @@ -26,24 +26,24 @@ namespace ExpandIntoFixed { typedef X0<Ts...> type; }; - static_assert(is_same<X1<int, int>::type, + static_assert(is_same<X1<int, int>::type, X0<int, int, pair<int, int>, pair<int, int>*>>::value, "fails with two default arguments"); - static_assert(is_same<X1<int, int, float>::type, + static_assert(is_same<X1<int, int, float>::type, X0<int, int, float, float*>>::value, "fails with one default argument"); - static_assert(is_same<X1<int, int, float, double>::type, + static_assert(is_same<X1<int, int, float, double>::type, X0<int, int, float, double>>::value, "fails with no default arguments"); } namespace ExpandIntoFixedShifted { - template<typename T, - typename U, - typename V = pair<T, U>, - typename W = V*> + template<typename T, + typename U, + typename V = pair<T, U>, + typename W = V*> class X0 { }; template<typename ...Ts> @@ -52,15 +52,15 @@ namespace ExpandIntoFixedShifted { typedef X0<char, Ts...> type; }; - static_assert(is_same<X1<int>::type, + static_assert(is_same<X1<int>::type, X0<char, int, pair<char, int>, pair<char, int>*>>::value, "fails with two default arguments"); - static_assert(is_same<X1<int, float>::type, + static_assert(is_same<X1<int, float>::type, X0<char, int, float, float*>>::value, "fails with one default argument"); - static_assert(is_same<X1<int, float, double>::type, + static_assert(is_same<X1<int, float, double>::type, X0<char, int, float, double>>::value, "fails with no default arguments"); } @@ -76,11 +76,11 @@ namespace Deduction { } namespace PR9021a { - template<typename, typename> + template<typename, typename> struct A { }; template<typename ...T> - struct B { + struct B { A<T...> a1; }; @@ -93,9 +93,9 @@ namespace PR9021b { template<class, class> struct t2 { - + }; - + template<template<class...> class M> struct m { @@ -107,14 +107,14 @@ namespace PR9021b { } namespace PartialSpecialization { - template<typename T, typename U, typename V = U> - struct X0; // expected-note 2{{template is declared here}} + template<typename T, typename U, typename V = U> // expected-note {{template parameter is declared here}} + struct X0; // expected-note {{template is declared here}} template<typename ...Ts> struct X0<Ts...> { // expected-error {{class template partial specialization is not more specialized than the primary template}} }; - X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}} + X0<int> x0i; // expected-error{{missing template argument for template parameter}} X0<int, float> x0if; X0<int, float, double> 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 30e7c65..c6e6038 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<short, int>::Inner<tuple<pair<short, unsigned short>, pair<int, unsigned int>, pair<long, unsigned long>> - >::value == 1? 1 : -1]; + >::value == 1? 1 : -1]; template<unsigned ...Values> struct unsigned_tuple { }; template<typename ...Types> @@ -99,7 +99,7 @@ namespace PacksAtDifferentLevels { int check5[X2<short, int>::Inner<int(pair<short, unsigned short>, pair<int, unsigned int>, pair<long, unsigned long>) - >::value == 1? 1 : -1]; + >::value == 1? 1 : -1]; template<typename T, typename U> struct some_function_object { @@ -217,8 +217,8 @@ namespace ExpandingNonTypeTemplateParameters { template<typename ...Types> struct tuple_of_values { template<Types ...Values> // 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<value_c<Types, Values>...> type; }; }; @@ -236,7 +236,7 @@ namespace ExpandingNonTypeTemplateParameters { tuple_of_values<int&, float&>::apply<i, i>::type tv2; // expected-error{{non-type template parameter of reference type 'float &' cannot bind to template argument of type 'int'}} - tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{too few template arguments for class template 'apply'}} + tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{missing template argument for template parameter}} tuple_of_values<int&, float&>::apply<i, f, i>::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 7b661c2..5f9ea27 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 <class T, unsigned = sizeof([]() { T::invalid; })> +// 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 <class T> diff --git a/clang/test/CXX/temp/temp.param/p1.cpp b/clang/test/CXX/temp/temp.param/p1.cpp index e9a9789..e2eecdf 100644 --- a/clang/test/CXX/temp/temp.param/p1.cpp +++ b/clang/test/CXX/temp/temp.param/p1.cpp @@ -5,8 +5,9 @@ template<template<> class C> class D; // expected-error{{template template param struct A {}; -template<class M, - class T = A, // expected-note{{previous default template argument defined here}} +template<class M, + class T // expected-note {{template parameter is declared here}} + = A, // expected-note{{previous default template argument defined here}} class C> // expected-error{{template parameter missing a default argument}} -class X0 {}; // expected-note{{template is declared here}} -X0<int> x0; // expected-error{{too few template arguments for class template 'X0'}} +class X0 {}; +X0<int> 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 8317e7f..e3dfb65 100644 --- a/clang/test/CXX/temp/temp.param/p12.cpp +++ b/clang/test/CXX/temp/temp.param/p12.cpp @@ -32,9 +32,9 @@ template<int N, class B3n; // Check validity of default arguments -template<template<class, int> class =// expected-note {{previous template template parameter is here}} +template<template<class, int> 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 83144a4..402a205 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<typename T> struct wrap { template<typename T> struct takedrop_impl; template<place...X> struct takedrop_impl<places<X...>> { - template<template<decltype(X)> class ...Take, + template<template<decltype(X)> class ...Take, // expected-note 2{{template parameter is declared here}} template<place > class ...Drop> - struct inner { // expected-note 2{{declared}} + struct inner { typedef types<typename Take<_>::type...> take; typedef types<typename Drop<_>::type...> drop; }; @@ -87,11 +87,11 @@ template<place...X> struct takedrop_impl<places<X...>> { template<unsigned N, typename...Ts> struct take { using type = typename takedrop_impl<typename make_places<N>::type>:: - template inner<wrap<Ts>::template inner...>::take; // expected-error {{too few template arguments}} + template inner<wrap<Ts>::template inner...>::take; // expected-error {{missing template argument}} }; template<unsigned N, typename...Ts> struct drop { using type = typename takedrop_impl<typename make_places<N>::type>:: - template inner<wrap<Ts>::template inner...>::drop; // expected-error {{too few template arguments}} + template inner<wrap<Ts>::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<typename ...Default> struct DefArg { template<template<typename T = Default> 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<typename T> 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 a3478c0..aa1666f 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<D{1, true}>(); } - template<D d> struct Z {}; + template<D d> struct Z {}; // expected-note {{template parameter is declared here}} Z<D{2, true}> z1; Z<D{2, false}> 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 ecb8237..cb048ec 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<int n> struct S; +template<int n> struct S; // cxx98-note {{template parameter is declared here}} template<int n> 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 741ebc5..749b455 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<typename T> -T pi = T(3.1415926535897932385); // expected-note {{template is declared here}} +template<typename T> // expected-note {{template parameter is declared here}} +T pi = T(3.1415926535897932385); template int pi<int>; #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<typename T> +template<typename T> 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<typename T> +template<typename T> 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 4b0fdb9..3923d16 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 <typename T> class PCT1 {}; template <typename T1, typename T2> class PCT2 {}; template <int X> class PCT3 {}; template <void (TestClass::*)()> class PCT4 {}; -template <void (*)()> class PCT5 {}; +template <void (*)()> class PCT5 {}; // expected-note {{template parameter is declared here}} template <typename T> class PCT6 { // expected-note@+1 3{{implicitly declared private here}} template <typename NT> class NPCT1 {}; @@ -416,7 +416,7 @@ template <typename T1, typename T2> class PCTT1 {}; template <typename T1, typename T2, typename T3> class PCTT2 {}; template <typename T, int X> class PCTT3 {}; template <typename T, void (TestClass::*)()> class PCTT4 {}; -template <typename T, void (*)()> class PCTT5 {}; +template <typename T, void (*)()> class PCTT5 {}; // expected-note {{template parameter is declared here}} template <typename T1, typename T2> class PCTT6 { template <typename NT> class NCT1 {}; template <typename NT> 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 0283dba..63fd997 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<typename T> void f(T); -template<typename T> -struct A { }; // expected-note{{template is declared here}} +template<typename T> // expected-note {{template parameter is declared here}} +struct A { }; struct X { template<> friend void f<int>(int); // expected-error{{in a friend}} template<> friend class A<int>; // expected-error{{cannot be a friend}} - + friend void f<float>(float); // okay friend class A<float>; // 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 bd231a3..bc52b3f0 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 <boolTy T> struct Type3Helper; template <> struct Type3Helper<boolTy::b> { typedef boolTy Ty; }; template <boolTy T, typename Type3Helper<T>::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 <charTy T> struct Type4Helper; template <> struct Type4Helper<charTy::c> { typedef charTy Ty; }; template <charTy T, typename Type4Helper<T>::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 <scharTy T> struct Type5Helper; template <> struct Type5Helper<scharTy::c> { typedef scharTy Ty; }; template <scharTy T, typename Type5Helper<T>::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 <ucharTy T> struct Type6Helper; template <> struct Type6Helper<ucharTy::c> { typedef ucharTy Ty; }; template <ucharTy T, typename Type6Helper<T>::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 <wcharTy T> struct Type7Helper; template <> struct Type7Helper<wcharTy::c> { typedef wcharTy Ty; }; template <wcharTy T, typename Type7Helper<T>::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 <char16Ty T> struct Type8Helper; template <> struct Type8Helper<char16Ty::c> { typedef char16Ty Ty; }; template <char16Ty T, typename Type8Helper<T>::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 <char32Ty T> struct Type9Helper; template <> struct Type9Helper<char32Ty::c> { typedef char32Ty Ty; }; template <char32Ty T, typename Type9Helper<T>::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 73dff88..250b54a 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 <typename T, auto Q> +template <typename T, auto Q> // 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 b52ebba..e25f7b5 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 <A{"a", "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 85b2a18..1d8de70 100644 --- a/clang/test/Modules/template-default-args.cpp +++ b/clang/test/Modules/template-default-args.cpp @@ -22,7 +22,7 @@ template<typename T = int> struct B; template<typename T = int> struct C; template<typename T> struct D {}; template<typename T> struct F {}; -template<typename T> struct G {}; +template<typename T> struct G {}; // #G template<typename T> struct J {}; template<typename T = int> 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 9102bca..e47b4ef 100644 --- a/clang/test/Parser/MicrosoftExtensions.cpp +++ b/clang/test/Parser/MicrosoftExtensions.cpp @@ -126,7 +126,7 @@ void template_uuid() } -template <class T, const GUID* g = &__uuidof(T)> // expected-note {{template parameter is declared here}} +template <class T, const GUID* g = &__uuidof(T)> // expected-note 2{{template parameter is declared here}} class COM_CLASS_TEMPLATE { }; typedef COM_CLASS_TEMPLATE<struct_with_uuid, &*&__uuidof(struct_with_uuid)> 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 3c2169f..ffe53e7 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<class T1, typename T2> struct Known { }; // expected-note 3 {{template is declared here}} + template<class T1, typename T2> struct Known { }; // expected-note 3{{template parameter is declared here}} template<class T1, typename T2> struct X; - template<class T1, typename T2> struct ABC; // expected-note {{template is declared here}} + template<class T1, typename T2> struct ABC; // expected-note {{template parameter is declared here}} template<int N1, int N2> struct ABC2 {}; template<class T1, typename T2> struct foo : @@ -68,7 +68,7 @@ namespace pr16225add { template<class T1, typename T2> struct foo2 : UnknownBase<T1,T2>, // expected-error {{no template named 'UnknownBase'}} - Known<T1> // expected-error {{too few template arguments for class template 'Known'}} + Known<T1> // expected-error {{missing template argument for template parameter}} { }; template<class T1, typename T2> struct foo3 : @@ -76,8 +76,8 @@ namespace pr16225add { { }; template<class T1, typename T2> struct foo4 : - UnknownBase<T1,ABC<T2> >, // expected-error {{too few template arguments for class template 'ABC'}} - Known<T1> // expected-error {{too few template arguments for class template 'Known'}} + UnknownBase<T1,ABC<T2> >, // expected-error {{missing template argument for template parameter}} + Known<T1> // expected-error {{missing template argument for template parameter}} { }; template<class T1, typename T2> struct foo5 : @@ -92,7 +92,7 @@ namespace pr16225add { #if __cplusplus <= 199711L // expected-error@-2 {{use '> >'}} #endif - Known<T1> // expected-error {{too few template arguments for class template 'Known'}} + Known<T1> // expected-error {{missing template argument for template parameter}} { }; template<class T1, typename T2, int N> struct foo7 : diff --git a/clang/test/Parser/cxx-template-template-recovery.cpp b/clang/test/Parser/cxx-template-template-recovery.cpp index 5700b16..2ece5a8cc 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 <typename T> - concept C1 = true; // #C1 + template <typename T> // #C1-T + concept C1 = true; template <typename T> auto V1 = true; // #V1 namespace b { - template <typename T> - concept C2 = true; // #C2 + template <typename T> // #C2-T + concept C2 = true; template <typename T> auto V2 = true; // #V2 } } -template <typename T> -concept C3 = true; // #C3 +template <typename T> // #C3-T +concept C3 = true; template <typename T> auto V3 = true; // #V3 template <template <typename T> typename C> constexpr bool test = true; -static_assert(test<a::C1>); // expected-error {{too few template arguments for concept 'C1'}} \ - // expected-note@#C1 {{here}} -static_assert(test<a::b::C2>); // expected-error {{too few template arguments for concept 'C2'}} \ - // expected-note@#C2 {{here}} -static_assert(test<C3>); // expected-error {{too few template arguments for concept 'C3'}} \ - // expected-note@#C3 {{here}} +static_assert(test<a::C1>); // expected-error {{missing template argument for template parameter}} \ + // expected-note@#C1-T {{here}} +static_assert(test<a::b::C2>); // expected-error {{missing template argument for template parameter}} \ + // expected-note@#C2-T {{here}} +static_assert(test<C3>); // expected-error {{missing template argument for template parameter}} \ + // expected-note@#C3-T {{here}} static_assert(test<a::V1>); // expected-error {{use of variable template 'a::V1' requires template arguments}} \ // expected-note@#V1 {{here}} diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp index a1594333..eda8cb7 100644 --- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp @@ -11,7 +11,7 @@ A(int) -> A<int>; // Make sure we still correctly parse cases where a template can appear without arguments. namespace template_template_arg { template<template<typename> typename> struct X {}; - template<typename> struct Y {}; + template<typename> struct Y {}; // expected-note 2{{template parameter is declared here}} X<A> xa; Y<A> ya; // expected-error {{requires template arguments}} @@ -36,10 +36,10 @@ namespace template_template_arg { namespace template_template_arg_pack { template<template<typename> typename...> struct XP {}; - template<typename...> struct YP {}; + template<typename...> struct YP {}; // expected-note 2{{template parameter is declared here}} struct Z { template<typename T> struct Q {}; }; // expected-note 2{{here}} - + template<typename T> using ZId = Z; template<typename ...Ts> struct A { @@ -116,7 +116,7 @@ namespace stmt { } namespace expr { - template<typename T> struct U {}; + template<typename T> struct U {}; // expected-note {{template parameter is declared here}} void j() { (void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}} (void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}} @@ -217,7 +217,7 @@ namespace typename_specifier { } namespace parenthesized { - template<typename T> struct X { X(T); }; + template<typename T> struct X { X(T); }; auto n = (X([]{})); } diff --git a/clang/test/SemaCXX/access-base-class.cpp b/clang/test/SemaCXX/access-base-class.cpp index 47d0f02..7d5fe38 100644 --- a/clang/test/SemaCXX/access-base-class.cpp +++ b/clang/test/SemaCXX/access-base-class.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s namespace T1 { - + class A { }; class B : private A { }; // expected-note {{declared private here}} @@ -10,7 +10,7 @@ void f(B* b) { } -namespace T2 { +namespace T2 { class A { }; class B : A { }; // expected-note {{implicitly declared private here}} @@ -24,7 +24,7 @@ void f(B* b) { namespace T3 { class A { }; -class B : public A { }; +class B : public A { }; void f(B* b) { A *a = b; @@ -50,30 +50,30 @@ void f(D *d) { namespace T5 { class A {}; - + class B : private A { void f(B *b) { A *a = b; } - }; + }; } namespace T6 { class C; - + class A {}; // expected-note{{member is declared here}} - + class B : private A { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}} void f(C* c); }; - - class C : public B { + + class C : public B { void f(C *c) { A* a = c; // expected-error {{cannot cast 'C' to its private base class 'A'}} \ // expected-error {{'A' is a private member of 'T6::A'}} } }; - + void B::f(C *c) { A *a = c; } @@ -82,7 +82,7 @@ namespace T6 { namespace T7 { class A {}; class B : public A {}; - class C : private B { + class C : private B { void f(C *c) { A* a = c; // okay } @@ -98,7 +98,7 @@ struct flag { template <class T> struct trait : flag<sizeof(T)> {}; // expected-note 2{{here}} -template <class T, bool Inferred = trait<T>::value> // expected-note {{here}} +template <class T, bool Inferred = trait<T>::value> // expected-note 2{{here}} struct a {}; template <class T> diff --git a/clang/test/SemaCXX/alias-template.cpp b/clang/test/SemaCXX/alias-template.cpp index b49d36a..90095b3 100644 --- a/clang/test/SemaCXX/alias-template.cpp +++ b/clang/test/SemaCXX/alias-template.cpp @@ -167,7 +167,10 @@ namespace SFINAE { f<E>(); } - template<typename T, typename U = EnableIf<is_enum<T>>> struct fail1 {}; // expected-note {{here}} + template<typename T, + typename U = // expected-note {{template parameter is declared here}} + EnableIf<is_enum<T>>> // expected-note {{in instantiation of template type alias 'EnableIf' requested here}} + struct fail1 {}; template<typename T> struct fail2 : DisableIf<is_enum<T>> {}; // expected-note {{here}} fail1<int> f1; // expected-note {{here}} diff --git a/clang/test/SemaCXX/anonymous-struct.cpp b/clang/test/SemaCXX/anonymous-struct.cpp index 7530982..51066a4 100644 --- a/clang/test/SemaCXX/anonymous-struct.cpp +++ b/clang/test/SemaCXX/anonymous-struct.cpp @@ -27,7 +27,7 @@ struct E { }; }; -template <class T> void foo(T); +template <class T> void foo(T); // #foo typedef struct { // expected-error {{anonymous non-C-compatible type given name for linkage purposes by typedef declaration after its linkage was computed; add a tag name here to establish linkage prior to definition}} // expected-note@-1 {{unnamed type used in template argument was declared here}} @@ -36,6 +36,7 @@ typedef struct { // expected-error {{anonymous non-C-compatible type given name #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#foo {{template parameter is declared here}} #endif } } A; // expected-note {{type is given name 'A' for linkage purposes by this typedef declaration}} diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index c35f3a5..0fb0727 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -102,7 +102,7 @@ static_assert(n9 == 123, ""); } namespace TemplateArgumentConversion { - template<int n> struct IntParam {}; + template<int n> struct IntParam {}; // expected-note {{template parameter is declared here}} using IntParam0 = IntParam<0>; using IntParam0 = IntParam<id(0)>; @@ -1529,7 +1529,7 @@ namespace MutableMembers { constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}} // Here's one reason why allowing this would be a disaster... - template<int n> struct Id { int k = n; }; + template<int n> struct Id { int k = n; }; // expected-note {{template parameter is declared here}} int f() { constexpr MM m = { 0 }; ++m.n; diff --git a/clang/test/SemaCXX/constant-expression.cpp b/clang/test/SemaCXX/constant-expression.cpp index cc041a4..d984ced 100644 --- a/clang/test/SemaCXX/constant-expression.cpp +++ b/clang/test/SemaCXX/constant-expression.cpp @@ -99,7 +99,7 @@ void diags(int n) { namespace IntOrEnum { const int k = 0; const int &p = k; // expected-note {{declared here}} - template<int n> struct S {}; + template<int n> struct S {}; // expected-note {{template parameter is declared here}} S<p> s; // expected-error {{not an integral constant expression}} expected-note {{read of variable 'p' of non-integral, non-enumeration type 'const int &'}} } diff --git a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp index c8204c2..6b8495e 100644 --- a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp +++ b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp @@ -74,6 +74,7 @@ namespace DependentDefaultCtorExceptionSpec { }; struct InstantiateFromAnotherClass { template <class B, class T = decltype(static_cast<bool (B::*)(int)>(&B::foo))> // expected-note {{in instantiation of function template specialization}} + // expected-note@-1 {{template parameter is declared here}} InstantiateFromAnotherClass(B *) {} // expected-note {{in instantiation of default argument}} }; NoexceptWithThis<int> f{}; diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index fef4674..931acfd 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -201,7 +201,7 @@ struct A { using mem_ptr_type = int (A::*)(int); -template<mem_ptr_type ptr> +template<mem_ptr_type ptr> // expected-note 2{{template parameter is declared here}} struct C {}; C<&A::f> c; diff --git a/clang/test/SemaCXX/cxx98-compat-flags.cpp b/clang/test/SemaCXX/cxx98-compat-flags.cpp index 6ffb3a5..3986251 100644 --- a/clang/test/SemaCXX/cxx98-compat-flags.cpp +++ b/clang/test/SemaCXX/cxx98-compat-flags.cpp @@ -1,7 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -verify %s // RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Wno-binary-literal -Werror %s -template<typename T> int TemplateFn(T) { return 0; } +template<typename T> // expected-note 2{{template parameter is declared here}} +int TemplateFn(T) { return 0; } void LocalTemplateArg() { struct S {}; TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}} diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp index d31d95a..99ed494 100644 --- a/clang/test/SemaCXX/cxx98-compat.cpp +++ b/clang/test/SemaCXX/cxx98-compat.cpp @@ -173,7 +173,8 @@ struct DelegCtor { template<int n = 0> void DefaultFuncTemplateArg(); // expected-warning {{default template arguments for a function template are incompatible with C++98}} -template<typename T> int TemplateFn(T) { return 0; } +template<typename T> // expected-note 2{{template parameter is declared here}} +int TemplateFn(T) { return 0; } void LocalTemplateArg() { struct S {}; TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}} @@ -188,7 +189,7 @@ int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{ #ifndef CXX17COMPAT namespace RedundantParensInAddressTemplateParam { int n; - template<int*p> struct S {}; + template<int*p> struct S {}; // expected-note 2{{template parameter is declared here}} S<(&n)> s; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}} S<(((&n)))> t; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}} } @@ -311,7 +312,7 @@ namespace LiteralUCNs { // template argument evaluation rules. #ifndef CXX17COMPAT namespace NonTypeTemplateArgs { - template<typename T, T v> struct S {}; + template<typename T, T v> struct S {}; // expected-note 2{{template parameter is declared here}} const int k = 5; // expected-note {{here}} static void f() {} // expected-note {{here}} S<const int&, k> s1; // expected-warning {{non-type template argument referring to object 'k' with internal linkage is incompatible with C++98}} @@ -320,8 +321,8 @@ namespace NonTypeTemplateArgs { namespace NullPointerTemplateArg { struct A {}; - template<int*> struct X {}; - template<int A::*> struct Y {}; + template<int*> struct X {}; // expected-note {{template parameter is declared here}} + template<int A::*> struct Y {}; // expected-note {{template parameter is declared here}} X<(int*)0> x; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}} Y<(int A::*)0> y; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}} } diff --git a/clang/test/SemaCXX/implicit-member-functions.cpp b/clang/test/SemaCXX/implicit-member-functions.cpp index 1554b1a..b48f937 100644 --- a/clang/test/SemaCXX/implicit-member-functions.cpp +++ b/clang/test/SemaCXX/implicit-member-functions.cpp @@ -63,6 +63,7 @@ namespace Recursion { template<typename T, typename = typename InvokeCopyConstructor<typename T::type>::type> // expected-note@-1 {{in instantiation of template class}} + // expected-note@-2 {{template parameter is declared here}} A(const T &); // expected-note@-1 {{in instantiation of default argument}} }; diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 2d2dde8..f411ef5 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -442,7 +442,7 @@ struct A { // expected-error@-1 {{field has incomplete type 'void'}} }; -template <typename F> +template <typename F> // cxx03-note {{template parameter is declared here}} void g(F f) { auto a = A<decltype(f())>(); // expected-note@-1 {{in instantiation of template class 'PR20731::A<void>' requested here}} @@ -499,12 +499,14 @@ namespace error_in_transform_prototype { namespace PR21857 { template<typename Fn> struct fun : Fn { + // cxx03-note@-1 {{template parameter is declared here}} fun() = default; using Fn::operator(); }; template<typename Fn> fun<Fn> wrap(Fn fn); // cxx03-warning {{template argument uses unnamed type}} + // cxx03-note@-1 {{template parameter is declared here}} auto x = wrap([](){}); // cxx03-warning {{template argument uses unnamed type}} cxx03-note 2 {{unnamed type used in template argument was declared here}} - // cxx03-note@-1 {{while substituting deduced template arguments into function template}} + // cxx03-note@-1 2{{while substituting deduced template arguments into function template}} } namespace PR13987 { diff --git a/clang/test/SemaCXX/make_integer_seq.cpp b/clang/test/SemaCXX/make_integer_seq.cpp index 71b7b82..7fca9ed 100644 --- a/clang/test/SemaCXX/make_integer_seq.cpp +++ b/clang/test/SemaCXX/make_integer_seq.cpp @@ -48,5 +48,6 @@ using illformed2 = ErrorSeq<int, -5>; // expected-note{{in instantiation}} template <typename T, T N> void f() {} __make_integer_seq<f, int, 0> x; // expected-error{{template template parameter must be a class template or type alias template}} -__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{different template parameters}} +__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{template template argument is incompatible}} // expected-error@make_integer_seq.cpp:* {{template argument for template template parameter must be a class template or type alias template}} +// expected-note@*:* 3{{template parameter from hidden source: template <class, type-parameter-1-0 ...> class}} diff --git a/clang/test/SemaCXX/type-trait-common-type.cpp b/clang/test/SemaCXX/type-trait-common-type.cpp index 7190dca..a59e032 100644 --- a/clang/test/SemaCXX/type-trait-common-type.cpp +++ b/clang/test/SemaCXX/type-trait-common-type.cpp @@ -5,10 +5,12 @@ # error #endif -// expected-note@*:* {{template declaration from hidden source: template <template <class ...> class, template <class> class, class, class ...>}} +// expected-note@*:* {{template parameter from hidden source: template <class ...> class}} +// expected-note@*:* {{template parameter from hidden source: class ...}} +// expected-note@*:* 2{{template parameter from hidden source: template <class ...> class}} void test() { - __builtin_common_type<> a; // expected-error {{too few template arguments for template '__builtin_common_type'}} + __builtin_common_type<> a; // expected-error {{missing template argument for template parameter}} __builtin_common_type<1> b; // expected-error {{template argument for template template parameter must be a class template or type alias template}} __builtin_common_type<int, 1> c; // expected-error {{template argument for template template parameter must be a class template or type alias template}} } diff --git a/clang/test/SemaCXX/undefined-internal.cpp b/clang/test/SemaCXX/undefined-internal.cpp index 9745f09..7f46623 100644 --- a/clang/test/SemaCXX/undefined-internal.cpp +++ b/clang/test/SemaCXX/undefined-internal.cpp @@ -209,9 +209,11 @@ namespace OverloadUse { t<f>(&n, &n); // expected-note {{used here}} #if __cplusplus < 201103L // expected-warning@-3 {{non-type template argument referring to function 'f' with internal linkage}} - // expected-note@-4 {{while substituting explicitly-specified template arguments}} - // expected-warning@-4 {{non-type template argument referring to function 'f' with internal linkage}} + // expected-note@-7 {{template parameter is declared here}} // expected-note@-5 {{while substituting explicitly-specified template arguments}} + // expected-warning@-5 {{non-type template argument referring to function 'f' with internal linkage}} + // expected-note@-9 {{template parameter is declared here}} + // expected-note@-7 {{while substituting explicitly-specified template arguments}} #endif } } diff --git a/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp index 79c9d33..1fe0916 100644 --- a/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp +++ b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp @@ -10,6 +10,7 @@ template <> struct [[deprecated]] traits<int> {}; // expected-note {{'traits<int>' has been explicitly marked deprecated here}} template<typename T, typename Trait = traits<T>> // expected-warning {{'traits<int>' is deprecated}} + // expected-note@-1 {{template parameter is declared here}} struct basic_string {}; // should not warn, defined and used in system headers diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl index 941e0a9..e62cc8d 100644 --- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl @@ -8,7 +8,7 @@ typedef vector<double, 3> double3; // expected-error@+1 {{class template 'RWBuffer' requires template arguments}} RWBuffer BufferErr1; -// expected-error@+1 {{too few template arguments for class template 'RWBuffer'}} +// expected-error@+1 {{missing template argument for template parameter}} RWBuffer<> BufferErr2; // test implicit RWBuffer concept @@ -39,7 +39,7 @@ template<typename T> struct TemplatedVector { // structs not allowed // expected-error@+4 {{constraints not satisfied for class template 'RWBuffer'}} -// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}} +// expected-note@*:* {{template parameter from hidden source: typename element_type}} // expected-note@*:* {{because 's' does not satisfy '__is_typed_resource_element_compatible'}} // expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(s)' evaluated to false}} RWBuffer<s> r6; diff --git a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl index fb14429..d5e2142 100644 --- a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl @@ -1,31 +1,31 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify %s
-
-typedef vector<float, 3> float3;
-
-StructuredBuffer<float3> Buffer;
-
-// expected-error@+2 {{class template 'StructuredBuffer' requires template arguments}}
-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_structured_resource_element_compatible<element_type> class StructuredBuffer {}}}
-StructuredBuffer BufferErr1;
-
-// expected-error@+2 {{too few template arguments for class template 'StructuredBuffer'}}
-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_structured_resource_element_compatible<element_type> class StructuredBuffer {}}}
-StructuredBuffer<> BufferErr2;
-
-// test elements of 0 size
-// expected-error@+3{{constraints not satisfied for class template 'StructuredBuffer' [with element_type = int[0]]}}
-// expected-note@*:*{{because 'int[0]' does not satisfy '__is_structured_resource_element_compatible'}}
-// expected-note@*:*{{because 'sizeof(int[0]) >= 1UL' (0 >= 1) evaluated to false}}
-StructuredBuffer<int[0]> BufferErr3;
-
-// In C++, empty structs do have a size of 1. So should HLSL.
-// The concept will accept empty structs as element types, despite it being unintuitive.
-struct Empty {};
-StructuredBuffer<Empty> BufferErr4;
-
-
-[numthreads(1,1,1)]
-void main() {
- (void)Buffer.__handle; // expected-error {{'__handle' is a private member of 'hlsl::StructuredBuffer<vector<float, 3>>'}}
- // expected-note@* {{implicitly declared private here}}
-}
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -fsyntax-only -verify %s + +typedef vector<float, 3> float3; + +StructuredBuffer<float3> Buffer; + +// expected-error@+2 {{class template 'StructuredBuffer' requires template arguments}} +// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_structured_resource_element_compatible<element_type> class StructuredBuffer {}}} +StructuredBuffer BufferErr1; + +// expected-error@+2 {{missing template argument for template parameter}} +// expected-note@*:* {{template parameter from hidden source: typename element_type}} +StructuredBuffer<> BufferErr2; + +// test elements of 0 size +// expected-error@+3{{constraints not satisfied for class template 'StructuredBuffer' [with element_type = int[0]]}} +// expected-note@*:*{{because 'int[0]' does not satisfy '__is_structured_resource_element_compatible'}} +// expected-note@*:*{{because 'sizeof(int[0]) >= 1UL' (0 >= 1) evaluated to false}} +StructuredBuffer<int[0]> BufferErr3; + +// In C++, empty structs do have a size of 1. So should HLSL. +// The concept will accept empty structs as element types, despite it being unintuitive. +struct Empty {}; +StructuredBuffer<Empty> BufferErr4; + + +[numthreads(1,1,1)] +void main() { + (void)Buffer.__handle; // expected-error {{'__handle' is a private member of 'hlsl::StructuredBuffer<vector<float, 3>>'}} + // expected-note@* {{implicitly declared private here}} +} diff --git a/clang/test/SemaObjCXX/parameterized_classes_subst.mm b/clang/test/SemaObjCXX/parameterized_classes_subst.mm index 8aacf21..e113bea 100644 --- a/clang/test/SemaObjCXX/parameterized_classes_subst.mm +++ b/clang/test/SemaObjCXX/parameterized_classes_subst.mm @@ -408,7 +408,7 @@ void testVariadicInstantiation() { // -------------------------------------------------------------------------- // Parameterized classes are not templates // -------------------------------------------------------------------------- -template<template<typename T, typename U> class TT> +template<template<typename T, typename U> class TT> // expected-note {{template parameter is declared here}} struct AcceptsTemplateTemplate { }; typedef AcceptsTemplateTemplate<NSMutableDictionary> TemplateTemplateFail1; // expected-error{{template argument for template template parameter must be a class template or type alias template}} diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp index ab5cad7..c27b193 100644 --- a/clang/test/SemaTemplate/alias-templates.cpp +++ b/clang/test/SemaTemplate/alias-templates.cpp @@ -278,12 +278,12 @@ namespace PR31514 { namespace an_alias_template_is_not_a_class_template { template<typename T> using Foo = int; // expected-note 3{{here}} Foo x; // expected-error {{use of alias template 'Foo' requires template arguments}} - Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}} + Foo<> y; // expected-error {{missing template argument for template parameter}} int z = Foo(); // expected-error {{use of alias template 'Foo' requires template arguments}} template<template<typename> class Bar> void f() { // expected-note 3{{here}} Bar x; // expected-error {{use of template template parameter 'Bar' requires template arguments}} - Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}} + Bar<> y; // expected-error {{missing template argument for template parameter}} int z = Bar(); // expected-error {{use of template template parameter 'Bar' requires template arguments}} } } @@ -304,11 +304,12 @@ namespace resolved_nttp { using TB = int (*)(int (*)[1], int (*)[2], int (*)[3]); template <typename T, int ...M> struct C { - template <T... N> using Fn = T(int(*...A)[N]); + template <T... N> // expected-note 3{{template parameter is declared here}} + using Fn = T(int(*...A)[N]); Fn<1, M..., 4> *p; // expected-error-re 3{{evaluates to {{[234]}}, which cannot be narrowed to type 'bool'}} }; using TC = decltype(C<int, 2, 3>::p); using TC = int (*)(int (*)[1], int (*)[2], int (*)[3], int (*)[4]); - using TC2 = decltype(C<bool, 2, 3>::p); // expected-note {{instantiation of}} + using TC2 = decltype(C<bool, 2, 3>::p); // expected-note 3{{instantiation of}} } diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp index 06333c8..8b27981 100644 --- a/clang/test/SemaTemplate/cwg2398.cpp +++ b/clang/test/SemaTemplate/cwg2398.cpp @@ -264,7 +264,7 @@ namespace classes { template<class T, class U> struct A {}; template<template<class> class TT> auto f(TT<int> a) { return a; } - // expected-note@-1 2{{substitution failure: too few template arguments}} + // expected-note@-1 2{{no template parameter}} A<int, float> v1; A<int, double> v2; @@ -280,7 +280,7 @@ namespace classes { static constexpr auto val = E1; }; template <template <class T3> class TT> void f(TT<int> v) { - // expected-note@-1 {{substitution failure: too few template arguments}} + // expected-note@-1 {{no template parameter}} static_assert(v.val == 3); }; void test() { @@ -313,7 +313,7 @@ namespace classes { } template <template <class T2, int V3> class TT2> auto g(TT2<double, 1>) { - // expected-note@-1 {{too few template arguments for class template 'A'}} + // expected-note@-1 {{no template parameter}} return f(TT2<int, 2>()); } @@ -347,11 +347,11 @@ namespace packs { namespace t1 { template<template<int, int...> class> struct A {}; // expected-error@-1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-2 {{template parameter is declared here}} - template<char> struct B; + template<char> struct B; // expected-note {{template parameter is declared here}} template struct A<B>; - // expected-note@-1 {{has different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} } // namespace t1 namespace t2 { template<template<char, int...> class> struct A {}; @@ -361,11 +361,11 @@ namespace packs { namespace t3 { template<template<int...> class> struct A {}; // expected-error@-1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-2 {{template parameter is declared here}} - template<char> struct B; + template<char> struct B; // expected-note {{template parameter is declared here}} template struct A<B>; - // expected-note@-1 {{has different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} } // namespace t3 namespace t4 { template<template<char...> class> struct A {}; @@ -501,7 +501,7 @@ namespace constraints { // expected-note@-1 {{similar constraint expressions not considered equivalent}} namespace t1 { - template<template<C1, class... T1s> class TT1> // expected-note {{TT1' declared here}} + template<template<C1, class... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<D1, class T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; @@ -513,7 +513,7 @@ namespace constraints { template struct A<B>; } // namespace t2 namespace t3 { - template<template<C1, class... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C1, class... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<C2, class T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; @@ -521,7 +521,7 @@ namespace constraints { } // namespace t2 namespace t4 { // FIXME: This should be accepted. - template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<C1 T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; @@ -529,14 +529,14 @@ namespace constraints { } // namespace t4 namespace t5 { // FIXME: This should be accepted - template<template<C2... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C2... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<C1 T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} } // namespace t5 namespace t6 { - template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<C2 T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; @@ -555,14 +555,14 @@ namespace constraints { template struct A<B>; } // namespace t8 namespace t9 { - template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<D1 T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} } // namespace t9 namespace t10 { - template<template<class...> requires C1<int> class TT1> // expected-note {{'TT1' declared here}} + template<template<class...> requires C1<int> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<class> requires C2<int> struct B {}; // expected-note {{'B' declared here}} diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp index 5ea34c0..fdf666b 100644 --- a/clang/test/SemaTemplate/default-arguments.cpp +++ b/clang/test/SemaTemplate/default-arguments.cpp @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -template<typename T, int N = 2> struct X; // expected-note{{template is declared here}} +template<typename T, int N = 2> struct X; // expected-note {{template parameter is declared here}} X<int, 1> *x1; X<int> *x2; -X<> *x3; // expected-error{{too few template arguments for class template 'X'}} +X<> *x3; // expected-error{{missing template argument for template parameter}} template<typename U = float, int M> struct X; @@ -20,6 +20,7 @@ template<class T> struct a { }; template<> struct a<int> { static const bool v = true; }; template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}} + // expected-note@-1 {{template parameter is declared here}} template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}} template struct p<int>; @@ -50,12 +51,14 @@ template<typename T> struct X1 { }; template<typename T> struct X2 { template<typename U = typename X1<T>::type> // expected-error{{no type named 'type' in 'X1<int>'}} \ - // expected-error{{no type named 'type' in 'X1<char>'}} - struct Inner1 { }; // expected-note{{template is declared here}} + // expected-error{{no type named 'type' in 'X1<char>'}} \ + // expected-note {{template parameter is declared here}} + struct Inner1 { }; template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \ - // expected-error{{no member named 'value' in 'X1<char>'}} - struct NonType1 { }; // expected-note{{template is declared here}} + // expected-error{{no member named 'value' in 'X1<char>'}} \ + // expected-note {{template parameter is declared here}} + struct NonType1 { }; template<T Value> struct Inner2 { }; @@ -74,10 +77,10 @@ struct X2 { X2<int> x2i; // expected-note{{in instantiation of template class 'X2<int>' requested here}} X2<int>::Inner1<float> x2iif; -X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}} +X2<int>::Inner1<> x2bad; // expected-error{{missing template argument for template parameter}} X2<int>::NonType1<'a'> x2_nontype1; -X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}} +X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{missing template argument for template parameter}} // Check multi-level substitution into template type arguments X2<int>::Inner3<float>::VeryInner<> vi; @@ -112,12 +115,12 @@ template<typename T, template<typename> class X = T::template apply> int array4[is_same<X4<add_pointer>, X4<add_pointer, add_pointer::apply> >::value? 1 : -1]; -template<int> struct X5 {}; +template<int> struct X5 {}; // expected-note {{template parameter is declared here}} template<long long> struct X5b {}; template<typename T, template<T> class B = X5> // expected-error {{cannot be narrowed from type 'long long' to 'int'}} - // expected-note@-1 {{has different template parameters}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-1 {{template template argument is incompatible}} + // expected-note@-2 {{template parameter is declared here}} struct X6 {}; X6<int> x6a; diff --git a/clang/test/SemaTemplate/instantiate-member-pointers.cpp b/clang/test/SemaTemplate/instantiate-member-pointers.cpp index 4757870..4eeaa3d 100644 --- a/clang/test/SemaTemplate/instantiate-member-pointers.cpp +++ b/clang/test/SemaTemplate/instantiate-member-pointers.cpp @@ -17,7 +17,7 @@ template<typename T, typename Class> struct X2 { T f(Class &obj, T Class::*pm) { // expected-error{{to a reference}} \ // expected-error{{member pointer to void}} - return obj.*pm; + return obj.*pm; } }; @@ -39,12 +39,12 @@ typedef int Y::*IntMember; template<IntMember Member> struct X4 { X3<int, Y, Member> member; - + int &getMember(Y& y) { return y.*Member; } }; -int &get_X4(X4<&Y::x> x4, Y& y) { - return x4.getMember(y); +int &get_X4(X4<&Y::x> x4, Y& y) { + return x4.getMember(y); } template<IntMember Member> @@ -63,12 +63,12 @@ namespace ValueDepMemberPointer { template <typename T> void S<T>::instantiate() { int a[(int)sizeof(T)-42]; // expected-error{{array with a negative size}} } - S<int> s; + S<int> s; } namespace PR18192 { struct A { struct { int n; }; }; - template<int A::*> struct X {}; + template<int A::*> struct X {}; // expected-note {{template parameter is declared here}} constexpr int A::*p = &A::n; X<p> x; // expected-error{{not a pointer to member constant}} } diff --git a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp index dce30aa2..601049a 100644 --- a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp +++ b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp @@ -20,17 +20,17 @@ apply<add_reference, int>::type ir = i; apply<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}} // Template template parameters -template<int> struct B; +template<int> struct B; // expected-note {{template parameter is declared here}} template<typename T, template<T Value> class X> // expected-error{{cannot have type 'float'}} // expected-error@-1 {{cannot be narrowed from type 'long long' to 'int'}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-2 2{{template parameter is declared here}} struct X0 { }; X0<int, B> x0b1; X0<float, B> x0b2; // expected-note{{while substituting}} -X0<long long, B> x0b3; // expected-note {{has different template parameters}} +X0<long long, B> x0b3; // expected-note {{template template argument is incompatible}} template<template<int V> class TT> struct X1 { }; diff --git a/clang/test/SemaTemplate/instantiation-default-1.cpp b/clang/test/SemaTemplate/instantiation-default-1.cpp index 3e70a21..8ef9f12 100644 --- a/clang/test/SemaTemplate/instantiation-default-1.cpp +++ b/clang/test/SemaTemplate/instantiation-default-1.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s template<typename T, typename U = const T> struct Def1; -template<> struct Def1<int> { +template<> struct Def1<int> { void foo(); }; @@ -22,9 +22,10 @@ void test_Def1(Def1<int, const int> *d1, Def1<const int, const int> *d2, template<typename T, // FIXME: bad error message below, needs better location info typename T2 = const T*> // expected-error{{'T2' declared as a pointer to a reference}} + // expected-note@-1 {{template parameter is declared here}} struct Def2; -template<> struct Def2<int> { +template<> struct Def2<int> { void foo(); }; @@ -40,11 +41,11 @@ template<> struct Def1<const int> { }; // expected-error{{redefinition of 'Def1< template<typename T, typename T2 = T&> struct Def3; -template<> struct Def3<int> { +template<> struct Def3<int> { void foo(); }; -template<> struct Def3<int&> { +template<> struct Def3<int&> { void bar(); }; @@ -83,7 +84,7 @@ template<typename R, typename Arg1, typename Arg2 = Arg1, typename FuncType = R (*)(Arg1, Arg2)> struct Def6; -template<> struct Def6<int, float> { +template<> struct Def6<int, float> { void foo(); }; @@ -91,7 +92,7 @@ template<> struct Def6<bool, int[5], float(double, double)> { void bar(); }; -bool test_Def6(Def6<int, float, float> *d6a, +bool test_Def6(Def6<int, float, float> *d6a, Def6<int, float, float, int (*)(float, float)> *d6b, Def6<bool, int[5], float(double, double), bool(*)(int*, float(*)(double, double))> *d6c) { diff --git a/clang/test/SemaTemplate/instantiation-default-2.cpp b/clang/test/SemaTemplate/instantiation-default-2.cpp index ffa77cf..e5db310 100644 --- a/clang/test/SemaTemplate/instantiation-default-2.cpp +++ b/clang/test/SemaTemplate/instantiation-default-2.cpp @@ -4,8 +4,7 @@ template<typename T, T Value> struct Constant; // FIXME: bad location precxx20-error@-1 {{a non-type template parameter cannot have type 'float'}} -// expected-note@-2 {{template parameter is declared here}} -// cxx20-note@-3 {{template parameter is declared here}} +// expected-note@-2 2{{template parameter is declared here}} Constant<int, 5> *c1; diff --git a/clang/test/SemaTemplate/instantiation-dependence.cpp b/clang/test/SemaTemplate/instantiation-dependence.cpp index 1a97dbf..d98d982 100644 --- a/clang/test/SemaTemplate/instantiation-dependence.cpp +++ b/clang/test/SemaTemplate/instantiation-dependence.cpp @@ -17,7 +17,8 @@ namespace PR24076 { } template<class T, - class = void_t<decltype(declval<T>() + 1)>> // expected-error {{invalid operands to binary expression}} + class = // expected-note {{template parameter is declared here}} + void_t<decltype(declval<T>() + 1)>> // expected-error {{invalid operands to binary expression}} struct bar {}; bar<s> bar; // expected-note {{in instantiation of}} diff --git a/clang/test/SemaTemplate/instantiation-depth-defarg.cpp b/clang/test/SemaTemplate/instantiation-depth-defarg.cpp index 24cd941..82bba72 100644 --- a/clang/test/SemaTemplate/instantiation-depth-defarg.cpp +++ b/clang/test/SemaTemplate/instantiation-depth-defarg.cpp @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth=128 -ftemplate-backtrace-limit=4 %s -template<int N> struct S { +template<int N> struct S { // \ +// expected-error{{recursive template instantiation exceeded maximum depth of 128}} \ +// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}} typedef typename S<N-1>::type type; static int f(int n = S<N-1>::f()); // \ -// expected-error{{recursive template instantiation exceeded maximum depth of 128}} \ // expected-note 3 {{instantiation of default function argument}} \ -// expected-note {{skipping 125 contexts in backtrace}} \ -// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}} +// expected-note {{skipping 125 contexts in backtrace}} }; template<> struct S<0> { diff --git a/clang/test/SemaTemplate/instantiation-depth-exception-spec.cpp b/clang/test/SemaTemplate/instantiation-depth-exception-spec.cpp index 4464fbb..a0d5a14 100644 --- a/clang/test/SemaTemplate/instantiation-depth-exception-spec.cpp +++ b/clang/test/SemaTemplate/instantiation-depth-exception-spec.cpp @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ftemplate-depth=16 -fcxx-exceptions -fexceptions %s -template<int N> struct X { - static int go(int a) noexcept(noexcept(X<N+1>::go(a))); // \ +template<int N> struct X { // \ // expected-error {{recursive template instantiation exceeded maximum depth of 16}} \ -// expected-note 9{{in instantiation of exception specification}} \ -// expected-note {{skipping 7 context}} \ // expected-note {{use -ftemplate-depth}} + static int go(int a) noexcept(noexcept(X<N+1>::go(a))); // \ +// expected-note 9{{in instantiation of exception specification}} \ +// expected-note {{skipping 7 context}} }; void f() { diff --git a/clang/test/SemaTemplate/instantiation-depth.cpp b/clang/test/SemaTemplate/instantiation-depth.cpp index 15e2c2b..35cf42a 100644 --- a/clang/test/SemaTemplate/instantiation-depth.cpp +++ b/clang/test/SemaTemplate/instantiation-depth.cpp @@ -19,11 +19,11 @@ void test() { // RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth=5 -ftemplate-backtrace-limit=4 -std=c++11 -DNOEXCEPT %s template<typename T> struct S { +// expected-error@-1 {{recursive template instantiation exceeded maximum depth of 5}} +// expected-note@-2 {{use -ftemplate-depth=N to increase recursive template instantiation depth}} S() noexcept(noexcept(S<S>())); \ -// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \ // expected-note 3 {{in instantiation of exception spec}} \ -// expected-note {{skipping 2 contexts in backtrace}} \ -// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}} +// expected-note {{skipping 2 contexts in backtrace}} }; S<void> t; // expected-note {{in instantiation of exception spec}} diff --git a/clang/test/SemaTemplate/ms-unqualified-base-class.cpp b/clang/test/SemaTemplate/ms-unqualified-base-class.cpp index 5e926c5..d2b02e5 100644 --- a/clang/test/SemaTemplate/ms-unqualified-base-class.cpp +++ b/clang/test/SemaTemplate/ms-unqualified-base-class.cpp @@ -84,7 +84,7 @@ int main() { return I; } -template <typename Type, int TSize> class Vec {}; // expected-note {{template is declared here}} +template <typename Type, int TSize> class Vec {}; // expected-note {{template parameter is declared here}} template <int TDim> class Index : public Vec<int, TDim> { // after-error@+1 {{member initializer 'Vec' does not name a non-static data member or base class}} @@ -107,7 +107,7 @@ template <typename T> class Wrong : public Vec<T, 4> { template class Wrong<double>; template <typename T> class Wrong2 : public Vec<T, 4> { - Wrong2() : Vec<T>() {} // expected-error {{too few template arguments for class template 'Vec'}} + Wrong2() : Vec<T>() {} // expected-error {{missing template argument for template parameter}} }; template class Wrong2<double>; diff --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp index 7911cf5..395f686 100644 --- a/clang/test/SemaTemplate/nested-template.cpp +++ b/clang/test/SemaTemplate/nested-template.cpp @@ -114,16 +114,16 @@ template<typename T> struct X2 { template<template<class U, T Value> class> // expected-error {{cannot have type 'float'}} // expected-error@-1 {{cannot be narrowed from type 'long long' to 'int'}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-2 {{template parameter is declared here}} struct Inner { }; }; -template<typename T, int Value> +template<typename T, int Value> // expected-note {{template parameter is declared here}} struct X2_arg; X2<int>::Inner<X2_arg> x2i1; X2<float> x2a; // expected-note{{instantiation}} -X2<long long>::Inner<X2_arg> x2i3; // expected-note {{has different template parameters}} +X2<long long>::Inner<X2_arg> x2i3; // expected-note {{template template argument is incompatible}} namespace PR10896 { template<typename TN> diff --git a/clang/test/SemaTemplate/partial-spec-instantiate.cpp b/clang/test/SemaTemplate/partial-spec-instantiate.cpp index 0b84df6..f171bf4 100644 --- a/clang/test/SemaTemplate/partial-spec-instantiate.cpp +++ b/clang/test/SemaTemplate/partial-spec-instantiate.cpp @@ -42,7 +42,7 @@ namespace WonkyAccess { } namespace rdar9169404 { - template<typename T, T N> struct X { }; + template<typename T, T N> struct X { }; // #rdar9169404-X template<bool C> struct X<bool, C> { typedef int type; }; @@ -50,6 +50,7 @@ namespace rdar9169404 { X<bool, -1>::type value; #if __cplusplus >= 201103L // expected-error@-2 {{non-type template argument evaluates to -1, which cannot be narrowed to type 'bool'}} + // expected-note@#rdar9169404-X {{template parameter is declared here}} #endif } diff --git a/clang/test/SemaTemplate/recovery-crash.cpp b/clang/test/SemaTemplate/recovery-crash.cpp index ac8053d..26683b1 100644 --- a/clang/test/SemaTemplate/recovery-crash.cpp +++ b/clang/test/SemaTemplate/recovery-crash.cpp @@ -26,13 +26,14 @@ namespace PR16134 { } namespace PR16225 { - template <typename T> void f(); + template <typename T> void f(); // #PR16225-f template <typename C> void g(C*) { struct LocalStruct : UnknownBase<Mumble, C> { }; // expected-error {{use of undeclared identifier 'Mumble'}} f<LocalStruct>(); #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses local type 'LocalStruct'}} // expected-note@-3 {{while substituting explicitly-specified template arguments}} + // expected-note@#PR16225-f {{template parameter is declared here}} #endif struct LocalStruct2 : UnknownBase<C> { }; // expected-error {{no template named 'UnknownBase'}} } diff --git a/clang/test/SemaTemplate/stack-exhaustion.cpp b/clang/test/SemaTemplate/stack-exhaustion.cpp index c7bfea4..b6e2fc9 100644 --- a/clang/test/SemaTemplate/stack-exhaustion.cpp +++ b/clang/test/SemaTemplate/stack-exhaustion.cpp @@ -33,11 +33,11 @@ int k = f(X<1000>()); namespace template_argument_recursion { struct ostream; - template<typename T> T &&declval(); + template<typename T> T &&declval(); // expected-error {{exceeded maximum depth}} namespace mlir { template<typename T, typename = decltype(declval<ostream&>() << declval<T&>())> - ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}} + ostream &operator<<(ostream& os, const T& obj); struct Value; } @@ -48,12 +48,12 @@ namespace template_argument_recursion { namespace template_parameter_type_recursion { struct ostream; - template<typename T> T &&declval(); + template<typename T> T &&declval(); // expected-error {{exceeded maximum depth}} template<bool B, typename T> struct enable_if { using type = T; }; namespace mlir { template<typename T, typename enable_if<declval<ostream&>() << declval<T&>(), void*>::type = nullptr> - ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}} + ostream &operator<<(ostream& os, const T& obj); struct Value; } diff --git a/clang/test/SemaTemplate/temp_arg.cpp b/clang/test/SemaTemplate/temp_arg.cpp index 538056a..9048744 100644 --- a/clang/test/SemaTemplate/temp_arg.cpp +++ b/clang/test/SemaTemplate/temp_arg.cpp @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx17 %std_cxx98-14 %s // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 %std_cxx17- %s -template<typename T, - int I, - template<typename> class TT> - class A; // precxx17-note 3 {{template is declared here}} \ - cxx17-note 2 {{template is declared here}} \ +template<typename T, + int I, + template<typename> class TT> // expected-note {{template parameter is declared here}} + class A; // precxx17-note 2 {{template is declared here}} \ + cxx17-note {{template is declared here}} \ cxx17-note {{candidate template ignored: couldn't infer template argument 'T'}} \ cxx17-note {{implicit deduction guide declared as 'template <typename T, int I, template <typename> class TT> A(A<T, I, TT>) -> A<T, I, TT>'}} \ cxx17-note {{candidate function template not viable: requires 1 argument, but 0 were provided}} \ @@ -15,7 +15,7 @@ template<typename> class X; A<int, 0, X> * a1; A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}} -A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}} +A<float, 1> *a3; // expected-error{{missing template argument for template parameter}} A a4; // precxx17-error{{use of class template 'A' requires template arguments}} \ cxx17-error{{no viable constructor or deduction guide for deduction of template arguments of 'A'}} diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp index 2a1c059..36d7d9c 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wconversion -verify %s -template<int N> struct A; // expected-note 5{{template parameter is declared here}} +template<int N> struct A; // expected-note 6{{template parameter is declared here}} A<0> *a0; @@ -42,7 +42,7 @@ double g(double); // expected-note 2{{candidate function}} int h(int); float h2(float); -template<int fp(int)> struct A3; // expected-note 1{{template parameter is declared here}} +template<int fp(int)> struct A3; // expected-note 2{{template parameter is declared here}} A3<h> *a14_1; A3<&h> *a14_2; A3<f> *a14_3; @@ -61,7 +61,7 @@ A4<*X_volatile_ptr> *a15_2; // expected-error{{non-type template argument does n A4<y> *15_3; // expected-error{{non-type template parameter of reference type 'const X &' cannot bind to template argument of type 'struct Y'}} \ // FIXME: expected-error{{expected unqualified-id}} -template<int (&fr)(int)> struct A5; // expected-note{{template parameter is declared here}} +template<int (&fr)(int)> struct A5; // expected-note 2{{template parameter is declared here}} A5<h> *a16_1; A5<f> *a16_3; A5<h2> *a16_6; // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'float (float)'}} @@ -86,7 +86,7 @@ A6<&Z::baz> *a17_3; // expected-error-re{{non-type template argument of type 'do template<int Z::*pm> struct A7; // expected-note{{template parameter is declared here}} -template<int Z::*pm> struct A7c; +template<int Z::*pm> struct A7c; // expected-note{{template parameter is declared here}} A7<&Z::int_member> *a18_1; A7c<&Z::int_member> *a18_2; A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float Z::*' cannot be converted to a value of type 'int Z::*'}} @@ -442,7 +442,10 @@ namespace dependent_nested_partial_specialization { A<Y>::B<int, &n> ay; // expected-error {{undefined}} expected-note {{instantiation of}} template<template<typename> class X> struct C { - template<typename T, int N, int M> struct D; // expected-note {{here}} + template<typename T, int N, + int M // expected-note {{template parameter is declared here}} + > struct D; + // expected-note@-1 {{template is declared here}} template<typename T, X<T> N> struct D<T*, N, N + 1> {}; // expected-error {{type of specialized non-type template argument depends on}} }; C<X>::D<int*, 0, 1> cx; @@ -492,7 +495,12 @@ namespace dependent_backreference { Incomplete f(int); // expected-note 2{{here}} int f(short); - template<typename T, T Value, int(*)[sizeof(f(Value))]> struct X {}; // expected-error 2{{incomplete}} + template<typename T, T Value, + int(*)[ // expected-note 2{{template parameter is declared here}} + sizeof(f(Value)) // expected-error 2{{incomplete}} + ] + > struct X {}; + int arr[sizeof(int)]; // When checking this template-id, we must not treat 'Value' as having type // 'int'; its type is the dependent type 'T'. diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp index 5752cba..32bb678 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp @@ -30,7 +30,7 @@ namespace Auto { namespace check_conversion_early { struct X {}; - template<int> struct A {}; + template<int> struct A {}; // expected-note {{template parameter is declared here}} template<X &x> struct A<x> {}; // expected-error {{not implicitly convertible}} struct Y { constexpr operator int() const { return 0; } }; diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp index c35743b..724ac85 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s -template<typename T, T val> struct A {}; // expected-note 3{{template parameter is declared here}} +template<typename T, T val> struct A {}; // expected-note 15{{template parameter is declared here}} template<typename T, typename U> constexpr bool is_same = false; template<typename T> constexpr bool is_same<T, T> = true; @@ -254,8 +254,8 @@ namespace Auto { } namespace DecltypeAuto { - template<auto v> struct A { }; - template<decltype(auto) v> struct DA { }; + template<auto v> struct A { }; // expected-note {{template parameter is declared here}} + template<decltype(auto) v> struct DA { }; // expected-note {{template parameter is declared here}} template<auto&> struct R { }; auto n = 0; // expected-note + {{declared here}} @@ -448,7 +448,7 @@ namespace PR42108 { struct R {}; struct S { constexpr S() {} constexpr S(R) {} }; struct T { constexpr operator S() { return {}; } }; - template <const S &> struct A {}; // expected-note {{template parameter is declared here}} + template <const S &> struct A {}; // expected-note 3{{template parameter is declared here}} void f() { A<R{}>(); // expected-error {{would bind reference to a temporary}} A<S{}>(); // expected-error {{reference to temporary object}} diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp index 56ceb7a..221f859 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp @@ -16,7 +16,7 @@ union U { int a, b; } u; int n; // expected-note 1+{{here}} // pointers to subobjects -template<int *> struct IntPtr {}; +template<int *> struct IntPtr {}; // expected-note 2{{template parameter is declared here}} using IPn = IntPtr<&n + 1>; using IPn = IntPtr<&n + 1>; @@ -30,7 +30,7 @@ using IP3 = IntPtr<s.n + 3>; using IP5 = IntPtr<&s.n[5]>; // expected-error {{not a constant expression}} expected-note {{cannot refer to element 5 of array of 3 elements}} -template<int &> struct IntRef {}; +template<int &> struct IntRef {}; // expected-note 4{{template parameter is declared here}} using IRn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}} using IRn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}} @@ -72,20 +72,20 @@ namespace ClassNTTP { static_assert(&id<A{1,3}> != &id<a>); int k = id<1>; // expected-error {{no viable conversion from 'int' to 'A'}} - // expected-note@#ClassNTTP1 {{passing argument to parameter 'a' here}} + // expected-note@#ClassNTTP1 {{template parameter is declared here}} struct B { constexpr B() {} constexpr B(int) = delete; // expected-note {{here}} }; - template<B> struct Q {}; // expected-note {{passing argument to parameter here}} + template<B> struct Q {}; // expected-note {{template parameter is declared here}} Q<1> q; // expected-error {{conversion function from 'int' to 'B' invokes a deleted function}} struct C { constexpr C() {} C(const C&) = delete; // expected-note {{here}} }; - template<C> struct R {}; // expected-note {{passing argument to parameter here}} + template<C> struct R {}; // expected-note {{template parameter is declared here}} constexpr C c; R<c> r; // expected-error {{call to deleted constructor}} } @@ -228,7 +228,7 @@ namespace UnnamedBitfield { // // FIXME: We shouldn't track a value for unnamed bit-fields, nor number // them when computing field indexes. - template <A> struct X {}; + template <A> struct X {}; // expected-note {{template parameter is declared here}} constexpr A a; using T = X<a>; using T = X<A{}>; @@ -238,7 +238,7 @@ namespace UnnamedBitfield { } namespace Temporary { - template<const int &> struct A {}; // expected-note {{template parameter is declared here}} + template<const int &> struct A {}; // expected-note 6{{template parameter is declared here}} A<0> a0; // expected-error {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}} A<(const int&)1> a1; // expected-error {{reference to temporary object is not allowed in a template argument}} @@ -254,18 +254,18 @@ namespace Temporary { X &&x = X{}; A<x.a[3]> a5; // expected-error {{reference to subobject of temporary object}} - template<const int*> struct B {}; + template<const int*> struct B {}; // expected-note 3{{template parameter is declared here}} B<&(int&)(int&&)0> b0; // expected-error {{pointer to temporary object}} B<&r3> b3; // expected-error {{pointer to temporary object}} B<&x.a[3]> b5; // expected-error {{pointer to subobject of temporary object}} struct C { const int *p[2]; }; - template<C> struct D {}; + template<C> struct D {}; // expected-note {{template parameter is declared here}} D<C{nullptr, &r3}> d; // expected-error {{pointer to temporary object}} } namespace StringLiteral { - template<decltype(auto)> struct Y {}; + template<decltype(auto)> struct Y {}; // expected-note 6{{template parameter is declared here}} Y<&"hello"> y1; // expected-error {{pointer to string literal}} Y<"hello"> y2; // expected-error {{reference to string literal}} Y<+"hello"> y3; // expected-error {{pointer to subobject of string literal}} @@ -278,7 +278,7 @@ namespace StringLiteral { } namespace TypeInfo { - template<decltype(auto)> struct Y {}; + template<decltype(auto)> struct Y {}; // expected-note 4{{template parameter is declared here}} Y<&typeid(int)> y1; // expected-error {{pointer to type_info object}} Y<typeid(int)> y2; // expected-error {{reference to type_info object}} @@ -289,7 +289,7 @@ namespace TypeInfo { } namespace Predefined { - template<decltype(auto)> struct Y {}; + template<decltype(auto)> struct Y {}; // expected-note 7{{template parameter is declared here}} struct A { const char *p; }; struct B { const char &r; }; diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp index e74c031..a87ffcb 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp @@ -5,16 +5,16 @@ struct Test { int b = 42; }; -template <Test t> +template <Test t> // expected-note {{template parameter is declared here}} struct A { static constexpr auto a = t.a; static constexpr auto b = t.b; }; -template <auto N> +template <auto N> // expected-note {{template parameter is declared here}} struct Auto {}; -template <typename T, T elem> +template <typename T, T elem> // expected-note {{template parameter is declared here}} struct Explicit{}; struct L {}; @@ -57,8 +57,8 @@ void test() { DefaultParam3<> d3; } -template<auto n> struct B { /* ... */ }; -template<int i> struct C { /* ... */ }; +template<auto n> struct B { /* ... */ }; // expected-note 2{{template parameter is declared here}} +template<int i> struct C { /* ... */ }; // expected-note {{template parameter is declared here}} C<{ 42 }> c1; // expected-warning {{braces around scalar initializer}} struct J1 { diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp index aa53dba..c10b594 100644 --- a/clang/test/SemaTemplate/temp_arg_template.cpp +++ b/clang/test/SemaTemplate/temp_arg_template.cpp @@ -2,13 +2,13 @@ // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s template<template<typename T> class X> struct A; // #A -// expected-note@-1 2{{previous template template parameter is here}} +// expected-note@-1 3{{template parameter is declared here}} -template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}} +template<template<typename T, int I> class X> struct B; // expected-note{{template parameter is declared here}} template<template<int I> class X> struct C; // expected-error@-1 {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}} -// expected-note@-2 {{previous template template parameter is here}} +// expected-note@-2 {{template parameter is declared here}} template<class> struct X; // expected-note {{template is declared here}} template<int N> struct Y; // expected-note {{template parameter is declared here}} @@ -18,7 +18,10 @@ template<const int &N> struct Yref; // expected-note {{template parameter is dec namespace N { template<class> struct Z; } -template<class, class> struct TooMany; // expected-note{{template is declared here}} +template< + class, + class> // expected-note {{template parameter is declared here}} +struct TooMany; A<X> *a1; @@ -26,14 +29,14 @@ A<N::Z> *a2; A< ::N::Z> *a3; A<Y> *a4; // expected-error@#A {{template argument for non-type template parameter must be an expression}} - // expected-note@-1 {{different template parameters}} -A<TooMany> *a5; // expected-error {{too few template arguments for class template 'TooMany'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} +A<TooMany> *a5; // expected-error@#A {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} B<X> *a6; // expected-error {{too many template arguments for class template 'X'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} C<Y> *a7; C<Ylong> *a8; -C<Yref> *a9; // expected-note {{different template parameters}} +C<Yref> *a9; // expected-note {{template template argument is incompatible}} template<typename T> void f(int); @@ -109,7 +112,7 @@ void foo() { namespace CheckDependentNonTypeParamTypes { template<template<typename T, typename U, T v> class X> struct A { - // expected-note@-1 {{previous template template parameter is here}} + // expected-note@-1 {{template parameter is declared here}} void f() { X<int, void*, 3> x; } @@ -136,7 +139,7 @@ namespace CheckDependentNonTypeParamTypes { }; // FIXME: This should probably be rejected, but the rules are at best unclear. - A<B> ab; // expected-note {{different template parameters}} + A<B> ab; // expected-note {{template template argument is incompatible}} void use() { ab.f(); diff --git a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp index d8a81bb..993930a 100644 --- a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp +++ b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp @@ -1,8 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s -// expected-note@temp_arg_template_p0522.cpp:* 1+{{template is declared here}} // expected-note@temp_arg_template_p0522.cpp:* 1+{{template parameter is declared here}} -// expected-note@temp_arg_template_p0522.cpp:* 1+{{previous template template parameter is here}} template<template<int> typename> struct Ti; // #Ti template<template<int...> typename> struct TPi; // #TPi @@ -34,14 +32,14 @@ namespace IntParam { Ti<iDi>, Ti<Pi>, Ti<iDt>>; - using err1 = Ti<ii>; // expected-error {{too few template arguments for class template 'ii'}} - // expected-note@-1 {{different template parameters}} - using err2 = Ti<iiPi>; // expected-error {{too few template arguments for class template 'iiPi'}} - // expected-note@-1 {{different template parameters}} + using err1 = Ti<ii>; // expected-error@#Ti {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} + using err2 = Ti<iiPi>; // expected-error@#Ti {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} using err3 = Ti<t0>; // expected-error@#Ti {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} - using err4 = Ti<it>; // expected-error {{too few template arguments for class template 'it'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} + using err4 = Ti<it>; // expected-error@#Ti {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} } // These are accepted by the backwards-compatibility "parameter pack in @@ -50,11 +48,11 @@ namespace IntPackParam { using ok = TPi<Pi>; using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>; using err1 = TPi<t0>; // expected-error@#TPi {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using err2 = TPi<iDt>; // expected-error@#TPi {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using err3 = TPi<it>; // expected-error@#TPi {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} } namespace IntAndPackParam { @@ -65,19 +63,19 @@ namespace IntAndPackParam { namespace DependentType { using ok = Pt<tT0<int, i>, tT0<int, iDi>>; - using err1 = tT0<int, ii>; // expected-error {{too few template arguments for class template 'ii'}} - // expected-note@-1 {{different template parameters}} + using err1 = tT0<int, ii>; // expected-error@#tT0 {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} using err2 = tT0<short, i>; using err2a = tT0<long long, i>; // expected-error@#tT0 {{cannot be narrowed from type 'long long' to 'int'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using err2b = tT0<void*, i>; // expected-error@#tT0 {{value of type 'void *' is not implicitly convertible to 'int'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using err3 = tT0<short, t0>; // expected-error@#tT0 {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using ok2 = Tt0<t0>; using err4 = Tt0<it>; // expected-error@#Tt0 {{template argument for non-type template parameter must be an expression}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} } namespace Auto { @@ -94,22 +92,22 @@ namespace Auto { TInt<Auto> ia; TInt<AutoPtr> iap; // expected-error@#TInt {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'int'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} TInt<DecltypeAuto> ida; TInt<Int> ii; TInt<IntPtr> iip; // expected-error@#TInt {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} TIntPtr<Auto> ipa; TIntPtr<AutoPtr> ipap; TIntPtr<DecltypeAuto> ipda; TIntPtr<Int> ipi; // expected-error@#TIntPtr {{value of type 'int *' is not implicitly convertible to 'int'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} TIntPtr<IntPtr> ipip; TAuto<Auto> aa; TAuto<AutoPtr> aap; // expected-error@#AutoPtr {{could not match 'auto *' against 'auto'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} TAuto<Int> ai; // FIXME: ill-formed (?) TAuto<IntPtr> aip; // FIXME: ill-formed (?) @@ -131,7 +129,7 @@ namespace Auto { // parameters. TDecltypeAuto<Auto> daa; TDecltypeAuto<AutoPtr> daap; // expected-error@#AutoPtr {{could not match 'auto *' against 'decltype(auto)'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} int n; template<auto A, decltype(A) B = &n> struct SubstFailure; @@ -160,11 +158,10 @@ namespace GH101394 { } // namespace t1 namespace t2 { template<template<Y> class> struct A {}; // #A - template<X> struct B; // #B + template<X> struct B; template struct A<B>; // expected-error@#A {{no viable conversion from 'const Y' to 'X'}} - // expected-note@-2 {{different template parameters}} + // expected-note@-2 {{template template argument is incompatible}} // expected-note@#X 2{{not viable}} - // expected-note@#B {{passing argument to parameter here}} } // namespace t2 } // namespace GH101394 diff --git a/clang/test/SemaTemplate/temp_arg_type.cpp b/clang/test/SemaTemplate/temp_arg_type.cpp index 392d257..a0d2bc3 100644 --- a/clang/test/SemaTemplate/temp_arg_type.cpp +++ b/clang/test/SemaTemplate/temp_arg_type.cpp @@ -1,9 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify %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 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s -template<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}} +template<typename T> class A; +// expected-note@-1 4{{template parameter is declared here}} +// cxx98-note@-2 2{{template parameter is declared here}} +// expected-note@-3 {{template is declared here}} // [temp.arg.type]p1 A<0> *a1; // expected-error{{template argument for template type parameter must be a type}} |