[clang] 07f3388 - Revert "[clang] Implement instantiation context note for checking template parameters (#126088)"

Nikita Popov via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 10 02:32:17 PDT 2025


Author: Nikita Popov
Date: 2025-03-10T10:32:08+01:00
New Revision: 07f3388fff0c73c1119d06ca1c2353fd012361c0

URL: https://github.com/llvm/llvm-project/commit/07f3388fff0c73c1119d06ca1c2353fd012361c0
DIFF: https://github.com/llvm/llvm-project/commit/07f3388fff0c73c1119d06ca1c2353fd012361c0.diff

LOG: Revert "[clang] Implement instantiation context note for checking template parameters (#126088)"

This reverts commit a24523ac8dc07f3478311a5969184b922b520395.

This is causing significant compile-time regressions for C++ code, see:
https://github.com/llvm/llvm-project/pull/126088#issuecomment-2704874202

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Sema/Sema.h
    clang/lib/Frontend/FrontendActions.cpp
    clang/lib/Sema/SemaInit.cpp
    clang/lib/Sema/SemaLambda.cpp
    clang/lib/Sema/SemaLookup.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/lib/Sema/SemaTemplateInstantiate.cpp
    clang/test/AST/ByteCode/cxx1z.cpp
    clang/test/AST/ByteCode/cxx20.cpp
    clang/test/AST/ByteCode/cxx98.cpp
    clang/test/AST/ByteCode/records.cpp
    clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
    clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
    clang/test/CXX/drs/cwg0xx.cpp
    clang/test/CXX/drs/cwg10xx.cpp
    clang/test/CXX/drs/cwg13xx.cpp
    clang/test/CXX/drs/cwg18xx.cpp
    clang/test/CXX/drs/cwg1xx.cpp
    clang/test/CXX/drs/cwg20xx.cpp
    clang/test/CXX/drs/cwg21xx.cpp
    clang/test/CXX/drs/cwg3xx.cpp
    clang/test/CXX/drs/cwg4xx.cpp
    clang/test/CXX/drs/cwg6xx.cpp
    clang/test/CXX/expr/expr.const/p3-0x.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
    clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
    clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
    clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
    clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
    clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
    clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
    clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
    clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
    clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
    clang/test/CXX/temp/temp.deduct/p9.cpp
    clang/test/CXX/temp/temp.param/p1.cpp
    clang/test/CXX/temp/temp.param/p12.cpp
    clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
    clang/test/CXX/temp/temp.param/p8-cxx20.cpp
    clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp
    clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
    clang/test/CXX/temp/temp.spec/part.spec.cpp
    clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp
    clang/test/Misc/integer-literal-printing.cpp
    clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp
    clang/test/Modules/missing-body-in-import.cpp
    clang/test/Modules/template-default-args.cpp
    clang/test/Parser/MicrosoftExtensions.cpp
    clang/test/Parser/cxx-template-argument.cpp
    clang/test/Parser/cxx-template-template-recovery.cpp
    clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
    clang/test/SemaCXX/access-base-class.cpp
    clang/test/SemaCXX/alias-template.cpp
    clang/test/SemaCXX/anonymous-struct.cpp
    clang/test/SemaCXX/constant-expression-cxx11.cpp
    clang/test/SemaCXX/constant-expression.cpp
    clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
    clang/test/SemaCXX/cxx2a-consteval.cpp
    clang/test/SemaCXX/cxx98-compat-flags.cpp
    clang/test/SemaCXX/cxx98-compat.cpp
    clang/test/SemaCXX/implicit-member-functions.cpp
    clang/test/SemaCXX/lambda-expressions.cpp
    clang/test/SemaCXX/make_integer_seq.cpp
    clang/test/SemaCXX/type-trait-common-type.cpp
    clang/test/SemaCXX/undefined-internal.cpp
    clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp
    clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
    clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl
    clang/test/SemaObjCXX/parameterized_classes_subst.mm
    clang/test/SemaTemplate/alias-templates.cpp
    clang/test/SemaTemplate/cwg2398.cpp
    clang/test/SemaTemplate/default-arguments.cpp
    clang/test/SemaTemplate/instantiate-member-pointers.cpp
    clang/test/SemaTemplate/instantiate-template-template-parm.cpp
    clang/test/SemaTemplate/instantiation-default-1.cpp
    clang/test/SemaTemplate/instantiation-default-2.cpp
    clang/test/SemaTemplate/instantiation-dependence.cpp
    clang/test/SemaTemplate/instantiation-depth-defarg.cpp
    clang/test/SemaTemplate/instantiation-depth-exception-spec.cpp
    clang/test/SemaTemplate/instantiation-depth.cpp
    clang/test/SemaTemplate/ms-unqualified-base-class.cpp
    clang/test/SemaTemplate/nested-template.cpp
    clang/test/SemaTemplate/partial-spec-instantiate.cpp
    clang/test/SemaTemplate/recovery-crash.cpp
    clang/test/SemaTemplate/stack-exhaustion.cpp
    clang/test/SemaTemplate/temp_arg.cpp
    clang/test/SemaTemplate/temp_arg_nontype.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp
    clang/test/SemaTemplate/temp_arg_template.cpp
    clang/test/SemaTemplate/temp_arg_template_p0522.cpp
    clang/test/SemaTemplate/temp_arg_type.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 372a95c80717c..77ddf75be059f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -296,16 +296,6 @@ Bug Fixes to C++ Support
 - Clang now uses the parameter location for abbreviated function templates in ``extern "C"``. (#GH46386)
 - 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 14b0051709625..239f16769ace9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5210,11 +5210,16 @@ def err_template_unnamed_class : Error<
 def err_template_param_list_
diff erent_arity : Error<
   "%select{too few|too many}0 template parameters in template "
   "%select{|template parameter }1redeclaration">;
+def note_template_param_list_
diff erent_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_
diff erent_kind : Error<
   "template parameter has a 
diff erent kind in template "
   "%select{|template parameter }0redeclaration">;
+def note_template_param_
diff erent_kind : Note<
+  "template parameter has a 
diff erent kind in template argument">;
 
 def err_invalid_decl_specifier_in_nontype_parm : Error<
   "invalid declaration specifier in template non-type parameter">;
@@ -5223,6 +5228,8 @@ def err_template_nontype_parm_
diff erent_type : Error<
   "template non-type parameter has a 
diff erent type %0 in template "
   "%select{|template parameter }1redeclaration">;
 
+def note_template_nontype_parm_
diff erent_type : Note<
+  "template non-type parameter has a 
diff erent 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<
@@ -5313,15 +5320,10 @@ 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_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 "
+def err_template_arg_list_
diff erent_arity : Error<
+  "%select{too few|too many}0 template arguments for "
   "%select{class template|function template|variable template|alias template|"
-  "template template parameter|concept|template}0 %1">;
+  "template template parameter|concept|template}1 %2">;
 def note_template_decl_here : Note<"template is declared here">;
 def note_template_decl_external : Note<
   "template declaration from hidden source: %0">;
@@ -5359,8 +5361,11 @@ 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 
diff erent template parameters than its "
+  "corresponding template template parameter">;
 def note_template_arg_template_params_mismatch : Note<
-  "template template argument is incompatible with its "
+  "template template argument has 
diff erent template parameters than its "
   "corresponding template template parameter">;
 def err_non_deduced_mismatch : Error<
   "could not match %
diff {$ against $|types}0,1">;
@@ -5922,6 +5927,10 @@ 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 fdef57e84ee3d..fecc870945ac5 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11833,7 +11833,7 @@ class Sema final : public SemaBase {
                                  bool *ConstraintsNotSatisfied = nullptr);
 
   bool CheckTemplateTypeArgument(
-      TemplateArgumentLoc &Arg,
+      TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg,
       SmallVectorImpl<TemplateArgument> &SugaredConverted,
       SmallVectorImpl<TemplateArgument> &CanonicalConverted);
 
@@ -11869,13 +11869,9 @@ class Sema final : public SemaBase {
                                      bool PartialOrdering,
                                      bool *StrictPackMatch);
 
-  /// Print the given named declaration to a string,
-  /// using the current PrintingPolicy, except that
-  /// TerseOutput will always be set.
-  SmallString<128> toTerseString(const NamedDecl &D) const;
-
   void NoteTemplateLocation(const NamedDecl &Decl,
                             std::optional<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
@@ -11990,13 +11986,15 @@ class Sema final : public SemaBase {
   bool TemplateParameterListsAreEqual(
       const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New,
       const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
-      TemplateParameterListEqualKind Kind);
+      TemplateParameterListEqualKind Kind,
+      SourceLocation TemplateArgLoc = SourceLocation());
 
-  bool TemplateParameterListsAreEqual(TemplateParameterList *New,
-                                      TemplateParameterList *Old, bool Complain,
-                                      TemplateParameterListEqualKind Kind) {
+  bool TemplateParameterListsAreEqual(
+      TemplateParameterList *New, TemplateParameterList *Old, bool Complain,
+      TemplateParameterListEqualKind Kind,
+      SourceLocation TemplateArgLoc = SourceLocation()) {
     return TemplateParameterListsAreEqual(nullptr, New, nullptr, Old, Complain,
-                                          Kind);
+                                          Kind, TemplateArgLoc);
   }
 
   /// Check whether a template can be declared within this scope.
@@ -12876,11 +12874,6 @@ class Sema final : public SemaBase {
 
       /// We are performing partial ordering for template template parameters.
       PartialOrderingTTP,
-
-      /// We are Checking a Template Parameter, so for any diagnostics which
-      /// occur in this scope, we will add a context note which points to this
-      /// template parameter.
-      CheckTemplateParameter,
     } Kind;
 
     /// Was the enclosing context a non-instantiation SFINAE context?
@@ -13108,11 +13101,6 @@ class Sema final : public SemaBase {
                           PartialOrderingTTP, TemplateDecl *PArg,
                           SourceRange InstantiationRange = SourceRange());
 
-    struct CheckTemplateParameter {};
-    /// \brief Note that we are checking a template parameter.
-    InstantiatingTemplate(Sema &SemaRef, CheckTemplateParameter,
-                          NamedDecl *Param);
-
     /// Note that we have finished instantiating this template.
     void Clear();
 
@@ -13146,13 +13134,6 @@ class Sema final : public SemaBase {
     InstantiatingTemplate &operator=(const InstantiatingTemplate &) = delete;
   };
 
-  /// For any diagnostics which occur within its scope, adds a context note
-  /// pointing to the declaration of the template parameter.
-  struct CheckTemplateParameterRAII : InstantiatingTemplate {
-    CheckTemplateParameterRAII(Sema &S, NamedDecl *Param)
-        : InstantiatingTemplate(S, CheckTemplateParameter(), Param) {}
-  };
-
   bool SubstTemplateArgument(const TemplateArgumentLoc &Input,
                              const MultiLevelTemplateArgumentList &TemplateArgs,
                              TemplateArgumentLoc &Output,

diff  --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 60e103e643e27..1ea4a2e9e88cf 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -403,8 +403,7 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
   }
 
 private:
-  static std::optional<std::string>
-  toString(CodeSynthesisContext::SynthesisKind Kind) {
+  static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
     switch (Kind) {
     case CodeSynthesisContext::TemplateInstantiation:
       return "TemplateInstantiation";
@@ -462,10 +461,8 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
       return "TypeAliasTemplateInstantiation";
     case CodeSynthesisContext::PartialOrderingTTP:
       return "PartialOrderingTTP";
-    case CodeSynthesisContext::CheckTemplateParameter:
-      return std::nullopt;
     }
-    return std::nullopt;
+    return "";
   }
 
   template <bool BeginInstantiation>
@@ -473,14 +470,12 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
                                     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";
   }
@@ -560,13 +555,10 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
   }
 
   template <bool BeginInstantiation>
-  static std::optional<TemplightEntry>
-  getTemplightEntry(const Sema &TheSema, const CodeSynthesisContext &Inst) {
+  static TemplightEntry getTemplightEntry(const Sema &TheSema,
+                                          const CodeSynthesisContext &Inst) {
     TemplightEntry Entry;
-    std::optional<std::string> Kind = toString(Inst.Kind);
-    if (!Kind)
-      return std::nullopt;
-    Entry.Kind = *Kind;
+    Entry.Kind = toString(Inst.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 edbd4c071b563..56ec33fe37bf3 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.isParameterKind() && Entity.getDecl()) {
+  if (Entity.isParamOrTemplateParamKind() && Entity.getDecl()) {
     if (Entity.getDecl()->getLocation().isInvalid())
       return;
 
@@ -7280,8 +7280,9 @@ 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 4d278bbc67d28..ceb32ee15dfa3 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1506,13 +1506,14 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
   TemplateParameterList *TemplateParams =
       getGenericLambdaTemplateParameterList(LSI, *this);
   if (TemplateParams) {
-    for (auto *TP : TemplateParams->asArray()) {
+    for (const 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 f3af514596a7e..aecf8ed1b4e4d 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1580,13 +1580,9 @@ llvm::DenseSet<Module*> &Sema::getLookupModules() {
   unsigned N = CodeSynthesisContexts.size();
   for (unsigned I = CodeSynthesisContextLookupModules.size();
        I != N; ++I) {
-    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;
+    Module *M = CodeSynthesisContexts[I].Entity ?
+                getDefiningModule(*this, CodeSynthesisContexts[I].Entity) :
+                nullptr;
     if (M && !LookupModulesCache.insert(M).second)
       M = nullptr;
     CodeSynthesisContextLookupModules.push_back(M);
@@ -3707,8 +3703,7 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
       TemplateParameterList *Params = FD->getTemplateParameters();
       if (Params->size() == 1) {
         IsTemplate = true;
-        NamedDecl *Param = Params->getParam(0);
-        if (!Param->isTemplateParameterPack() && !StringLit) {
+        if (!Params->getParam(0)->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.
@@ -3721,7 +3716,6 @@ 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 0caabc6573361..7ffcef1592a93 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -869,11 +869,9 @@ void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl,
           ? diag::ext_template_param_shadow
           : (SupportedForCompatibility ? diag::ext_compat_template_param_shadow
                                        : diag::err_template_param_shadow);
-  auto *ND = cast<NamedDecl>(PrevDecl);
-  CheckTemplateParameterRAII CTP(*this, ND);
-  // FIXME: Don't put the name in the diagnostic, unless there is no source
-  // location.
+  const auto *ND = cast<NamedDecl>(PrevDecl);
   Diag(Loc, DiagId) << ND->getDeclName();
+  NoteTemplateParameterLocation(*ND);
 }
 
 TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) {
@@ -4826,7 +4824,7 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S,
 }
 
 bool Sema::CheckTemplateTypeArgument(
-    TemplateArgumentLoc &AL,
+    TemplateTypeParmDecl *Param, TemplateArgumentLoc &AL,
     SmallVectorImpl<TemplateArgument> &SugaredConverted,
     SmallVectorImpl<TemplateArgument> &CanonicalConverted) {
   const TemplateArgument &Arg = AL.getArgument();
@@ -4882,6 +4880,7 @@ 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.
@@ -4919,6 +4918,7 @@ bool Sema::CheckTemplateTypeArgument(
     // is not a type.
     SourceRange SR = AL.getSourceRange();
     Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR;
+    NoteTemplateParameterLocation(*Param);
 
     return true;
   }
@@ -5208,8 +5208,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
                                  CheckTemplateArgumentInfo &CTAI,
                                  CheckTemplateArgumentKind CTAK) {
   // Check template type parameters.
-  if (isa<TemplateTypeParmDecl>(Param))
-    return CheckTemplateTypeArgument(ArgLoc, CTAI.SugaredConverted,
+  if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
+    return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI.SugaredConverted,
                                      CTAI.CanonicalConverted);
 
   const TemplateArgument &Arg = ArgLoc.getArgument();
@@ -5354,6 +5354,8 @@ 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: {
@@ -5373,6 +5375,7 @@ 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;
     }
 
@@ -5463,11 +5466,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,
-                                    bool MatchingTTP) {
+                                    TemplateDecl *TD,
+                                    const TemplateParmDecl *D,
+                                    TemplateArgumentListInfo &Args) {
   // 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())
@@ -5485,12 +5488,16 @@ 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.
-  S.Diag(DiagLoc.isValid() ? DiagLoc : Loc,
-         MatchingTTP ? diag::err_template_template_param_missing_param
-                     : diag::err_template_param_missing_arg);
+
+  TemplateParameterList *Params = TD->getTemplateParameters();
+
+  S.Diag(Loc, diag::err_template_arg_list_
diff erent_arity)
+    << /*not enough args*/0
+    << (int)S.getTemplateNameKindForDiagnostics(TemplateName(TD))
+    << TD;
+  S.NoteTemplateLocation(*TD, Params->getSourceRange());
   return true;
 }
 
@@ -5529,8 +5536,6 @@ 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.
@@ -5567,9 +5572,11 @@ bool Sema::CheckTemplateArgumentList(
         continue;
       } else if (ArgIdx == NumArgs && !PartialTemplateArgs) {
         // Not enough arguments for this parameter pack.
-        Diag(RAngleLoc, CTAI.MatchingTTP
-                            ? diag::err_template_template_param_missing_param
-                            : diag::err_template_param_missing_arg);
+        Diag(TemplateLoc, diag::err_template_arg_list_
diff erent_arity)
+          << /*not enough args*/0
+          << (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
+          << Template;
+        NoteTemplateLocation(*Template, Params->getSourceRange());
         return true;
       }
     }
@@ -5582,10 +5589,8 @@ 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() ||
@@ -5626,6 +5631,7 @@ bool Sema::CheckTemplateArgumentList(
                  diag::err_template_expansion_into_fixed_list)
                 << (isa<ConceptDecl>(Template) ? 1 : 0)
                 << ArgLoc.getSourceRange();
+            NoteTemplateParameterLocation(**Param);
             return true;
           }
         }
@@ -5732,14 +5738,14 @@ bool Sema::CheckTemplateArgumentList(
       if (!HasDefaultArg) {
         if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param))
           return diagnoseMissingArgument(*this, TemplateLoc, Template, TTP,
-                                         NewArgs, CTAI.MatchingTTP);
+                                         NewArgs);
         if (NonTypeTemplateParmDecl *NTTP =
                 dyn_cast<NonTypeTemplateParmDecl>(*Param))
           return diagnoseMissingArgument(*this, TemplateLoc, Template, NTTP,
-                                         NewArgs, CTAI.MatchingTTP);
+                                         NewArgs);
         return diagnoseMissingArgument(*this, TemplateLoc, Template,
                                        cast<TemplateTemplateParmDecl>(*Param),
-                                       NewArgs, CTAI.MatchingTTP);
+                                       NewArgs);
       }
       return true;
     }
@@ -5795,7 +5801,8 @@ 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_too_many_args)
+    Diag(TemplateLoc, diag::err_template_arg_list_
diff erent_arity)
+        << /*too many args*/1
         << (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
         << Template
         << SourceRange(NewArgs[ArgIdx].getLocation(), NewArgs.getRAngleLoc());
@@ -6220,6 +6227,8 @@ 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;
   }
 
@@ -6244,7 +6253,8 @@ 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();
+      << Arg->getType() << ParamType << Arg->getSourceRange();
+    S.NoteTemplateParameterLocation(*Param);
     return NPV_NullPointer;
   }
 
@@ -6253,7 +6263,8 @@ 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);
+      << EvalResult.Val.getAsString(S.Context, ParamType);
+    S.NoteTemplateParameterLocation(*Param);
     return NPV_Error;
   }
 
@@ -6265,6 +6276,7 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param,
         << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), Code)
         << FixItHint::CreateInsertion(S.getLocForEndOfToken(Arg->getEndLoc()),
                                       ")");
+    S.NoteTemplateParameterLocation(*Param);
     return NPV_NullPointer;
   }
 
@@ -6305,6 +6317,7 @@ 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;
         }
       }
@@ -6322,6 +6335,7 @@ static bool CheckTemplateArgumentIsCompatibleWithParameter(
       else
         S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_convertible)
             << ArgIn->getType() << ParamType << Arg->getSourceRange();
+      S.NoteTemplateParameterLocation(*Param);
       return true;
     }
   }
@@ -6464,6 +6478,7 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
   if (!Entity) {
     S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref)
         << Arg->getSourceRange();
+    S.NoteTemplateParameterLocation(*Param);
     return true;
   }
 
@@ -6471,6 +6486,7 @@ 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;
   }
 
@@ -6479,6 +6495,7 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
     if (!Method->isStatic()) {
       S.Diag(Arg->getBeginLoc(), diag::err_template_arg_method)
           << Method << Arg->getSourceRange();
+      S.NoteTemplateParameterLocation(*Param);
       return true;
     }
   }
@@ -6518,6 +6535,7 @@ 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;
     }
 
@@ -6537,12 +6555,15 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
     if (!S.Context.hasSameUnqualifiedType(Entity->getType(),
                                           ParamType.getNonReferenceType())) {
       S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
-          << ParamType;
+        << ParamType;
+      S.NoteTemplateParameterLocation(*Param);
       return true;
     }
 
     S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
-        << ParamType << FixItHint::CreateRemoval(AddrOpLoc);
+      << ParamType
+      << FixItHint::CreateRemoval(AddrOpLoc);
+    S.NoteTemplateParameterLocation(*Param);
 
     ArgType = Entity->getType();
   }
@@ -6563,12 +6584,15 @@ 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;
+          << ParamType;
+        S.NoteTemplateParameterLocation(*Param);
         return true;
       }
 
       S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_address_of)
-          << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), "&");
+        << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), "&");
+
+      S.NoteTemplateParameterLocation(*Param);
     }
   }
 
@@ -6684,6 +6708,7 @@ 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;
   }
 
@@ -6789,6 +6814,7 @@ 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();
       }
     }
@@ -6797,8 +6823,10 @@ 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())
+    if (ParamType.isNull()) {
+      NoteTemplateParameterLocation(*Param);
       return ExprError();
+    }
   }
 
   // We should have already dropped all cv-qualifiers by now.
@@ -6830,7 +6858,9 @@ 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();
+      << Arg->getType()
+      << ParamType.getUnqualifiedType();
+    NoteTemplateParameterLocation(*Param);
     return ExprError();
   }
 
@@ -6925,8 +6955,10 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
           Arg, ParamType,
           PartialOrderingTTP ? CCEK_InjectedTTP : CCEK_TemplateArg, Param);
       assert(!ArgResult.isUnset());
-      if (ArgResult.isInvalid())
+      if (ArgResult.isInvalid()) {
+        NoteTemplateParameterLocation(*Param);
         return ExprError();
+      }
     } else {
       ArgResult = Arg;
     }
@@ -7073,6 +7105,7 @@ 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 {
@@ -7110,6 +7143,7 @@ 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();
     }
 
@@ -7155,6 +7189,7 @@ 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.
@@ -7165,10 +7200,12 @@ 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;
@@ -7293,7 +7330,8 @@ 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;
+        << Arg->getType() << ParamType;
+      NoteTemplateParameterLocation(*Param);
       return ExprError();
 
     case NPV_Error:
@@ -7321,7 +7359,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
 
 static void DiagnoseTemplateParameterListArityMismatch(
     Sema &S, TemplateParameterList *New, TemplateParameterList *Old,
-    Sema::TemplateParameterListEqualKind Kind);
+    Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc);
 
 bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
                                          TemplateParameterList *Params,
@@ -7391,6 +7429,7 @@ 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);
@@ -7399,24 +7438,25 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
   return false;
 }
 
-SmallString<128> Sema::toTerseString(const NamedDecl &D) const {
+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> Str;
   llvm::raw_svector_ostream Out(Str);
-  PrintingPolicy PP = getPrintingPolicy();
+  PrintingPolicy PP = S.getPrintingPolicy();
   PP.TerseOutput = 1;
-  D.print(Out, PP);
-  return Str;
+  Decl.print(Out, PP);
+  return S.Diag(Decl.getLocation(), ExternalDiagID) << Out.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 =
-      Diag(Decl.getLocation(), HasLoc ? diag::note_template_decl_here
-                                      : diag::note_template_decl_external);
-  if (!HasLoc)
-    DB << toTerseString(Decl).str();
+      noteLocation(*this, Decl, diag::note_template_decl_here,
+                   diag::note_template_decl_external);
   if (ParamRange && ParamRange->isValid()) {
     assert(Decl.getLocation().isValid() &&
            "Parameter range has location when Decl does not");
@@ -7424,6 +7464,11 @@ 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) {
@@ -7700,17 +7745,21 @@ 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) {
+static bool MatchTemplateParameterKind(
+    Sema &S, NamedDecl *New,
+    const Sema::TemplateCompareNewDeclInfo &NewInstFrom, NamedDecl *Old,
+    const NamedDecl *OldInstFrom, bool Complain,
+    Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) {
   // Check the actual kind (type, non-type, template).
   if (Old->getKind() != New->getKind()) {
     if (Complain) {
-      S.Diag(New->getLocation(), diag::err_template_param_
diff erent_kind)
-          << (Kind != Sema::TPL_TemplateMatch);
+      unsigned NextDiag = diag::err_template_param_
diff erent_kind;
+      if (TemplateArgLoc.isValid()) {
+        S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
+        NextDiag = diag::note_template_param_
diff erent_kind;
+      }
+      S.Diag(New->getLocation(), NextDiag)
+        << (Kind != Sema::TPL_TemplateMatch);
       S.Diag(Old->getLocation(), diag::note_template_prev_declaration)
         << (Kind != Sema::TPL_TemplateMatch);
     }
@@ -7724,11 +7773,18 @@ MatchTemplateParameterKind(Sema &S, NamedDecl *New,
   // 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(), diag::err_template_parameter_pack_non_pack)
-          << ParamKind << New->isParameterPack();
+      S.Diag(New->getLocation(), NextDiag)
+        << ParamKind << New->isParameterPack();
       S.Diag(Old->getLocation(), diag::note_template_parameter_pack_here)
         << ParamKind << Old->isParameterPack();
     }
@@ -7749,8 +7805,13 @@ MatchTemplateParameterKind(Sema &S, NamedDecl *New,
     QualType NewType = S.Context.getUnconstrainedType(NewNTTP->getType());
     if (!S.Context.hasSameType(OldType, NewType)) {
       if (Complain) {
-        S.Diag(NewNTTP->getLocation(),
-               diag::err_template_nontype_parm_
diff erent_type)
+        unsigned NextDiag = diag::err_template_nontype_parm_
diff erent_type;
+        if (TemplateArgLoc.isValid()) {
+          S.Diag(TemplateArgLoc,
+                 diag::err_template_arg_template_params_mismatch);
+          NextDiag = diag::note_template_nontype_parm_
diff erent_type;
+        }
+        S.Diag(NewNTTP->getLocation(), NextDiag)
             << NewNTTP->getType() << (Kind != Sema::TPL_TemplateMatch);
         S.Diag(OldNTTP->getLocation(),
                diag::note_template_nontype_parm_prev_declaration)
@@ -7771,7 +7832,8 @@ MatchTemplateParameterKind(Sema &S, NamedDecl *New,
             OldTTP->getTemplateParameters(), Complain,
             (Kind == Sema::TPL_TemplateMatch
                  ? Sema::TPL_TemplateTemplateParmMatch
-                 : Kind)))
+                 : Kind),
+            TemplateArgLoc))
       return false;
   }
 
@@ -7822,12 +7884,21 @@ MatchTemplateParameterKind(Sema &S, NamedDecl *New,
 
 /// Diagnose a known arity mismatch when comparing template argument
 /// lists.
-static void DiagnoseTemplateParameterListArityMismatch(
-    Sema &S, TemplateParameterList *New, TemplateParameterList *Old,
-    Sema::TemplateParameterListEqualKind Kind) {
-  S.Diag(New->getTemplateLoc(), diag::err_template_param_list_
diff erent_arity)
-      << (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,
+                                                SourceLocation TemplateArgLoc) {
+  unsigned NextDiag = diag::err_template_param_list_
diff erent_arity;
+  if (TemplateArgLoc.isValid()) {
+    S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
+    NextDiag = diag::note_template_param_list_
diff erent_arity;
+  }
+  S.Diag(New->getTemplateLoc(), NextDiag)
+    << (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());
@@ -7836,10 +7907,11 @@ static void DiagnoseTemplateParameterListArityMismatch(
 bool Sema::TemplateParameterListsAreEqual(
     const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New,
     const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
-    TemplateParameterListEqualKind Kind) {
+    TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) {
   if (Old->size() != New->size()) {
     if (Complain)
-      DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind);
+      DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
+                                                 TemplateArgLoc);
 
     return false;
   }
@@ -7857,18 +7929,21 @@ bool Sema::TemplateParameterListsAreEqual(
        OldParm != OldParmEnd; ++OldParm, ++NewParm) {
     if (NewParm == NewParmEnd) {
       if (Complain)
-        DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind);
+        DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
+                                                   TemplateArgLoc);
       return false;
     }
     if (!MatchTemplateParameterKind(*this, *NewParm, NewInstFrom, *OldParm,
-                                    OldInstFrom, Complain, Kind))
+                                    OldInstFrom, Complain, Kind,
+                                    TemplateArgLoc))
       return false;
   }
 
   // Make sure we exhausted all of the arguments.
   if (NewParm != NewParmEnd) {
     if (Complain)
-      DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind);
+      DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
+                                                 TemplateArgLoc);
 
     return false;
   }
@@ -8166,6 +8241,7 @@ 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;
     }
   }
@@ -8189,7 +8265,6 @@ 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 b1a1f86c5cfe1..9769848840d87 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 847057a3f70ea..19c27a76b182c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -575,7 +575,6 @@ 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.
@@ -810,16 +809,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
     Sema &SemaRef, SourceLocation ArgLoc, PartialOrderingTTP,
     TemplateDecl *PArg, SourceRange InstantiationRange)
     : InstantiatingTemplate(SemaRef, CodeSynthesisContext::PartialOrderingTTP,
-                            ArgLoc, SourceRange(), PArg) {}
-
-Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
-                                                   CheckTemplateParameter,
-                                                   NamedDecl *Param)
-    : InstantiatingTemplate(
-          SemaRef, CodeSynthesisContext::CheckTemplateParameter,
-          Param->getLocation(), Param->getSourceRange(), Param) {
-  assert(Param->isTemplateParameter());
-}
+                            ArgLoc, InstantiationRange, PArg) {}
 
 void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
   Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext;
@@ -1261,18 +1251,12 @@ 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;
-    }
     }
   }
 }
@@ -1316,7 +1300,6 @@ 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.
@@ -2365,7 +2348,6 @@ 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 ca5f10f6567b4..57f99235a2b20 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 {}; // both-note 6{{template parameter is declared here}}
+template<typename T, T val> struct A {};
 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 d39c2281ec146..06501de64916a 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 { /* ... */ }; // both-note {{template parameter is declared here}}
+  template<auto n> struct B { /* ... */ };
   struct J1 {
     J1 *self=this;
   };

diff  --git a/clang/test/AST/ByteCode/cxx98.cpp b/clang/test/AST/ByteCode/cxx98.cpp
index 9af668029f8a3..c17049b01c1da 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 {}; // both-note {{template parameter is declared here}}
+  template<int n> struct S {};
   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 d125fb0bcf1b4..42b6d82d7190b 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>// both-note {{template parameter is declared here}}
+  template <typename T, auto Q>
   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 fc4e359666ba9..9632fda296aa1 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,6 +33,5 @@ namespace test1 {
 // specifiers.
 namespace test2 {
   template <class T> struct bar {};
-  // expected-note at -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 57c99212f4c69..2bceb3e267790 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 {}; // expected-note {{template parameter is declared here}}
+template<bool> struct BoolParam {};
 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 c035aa3f4ec61..282e71bbf3bda 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -806,7 +806,6 @@ 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
@@ -1019,9 +1018,9 @@ namespace cwg62 { // cwg62: 2.9
   struct A {
     struct { int n; } b;
   };
-  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
+  template<typename T> struct X {};
+  template<typename T> T get() { return get<T>(); }
+  template<typename T> int take(T) { return 0; }
 
   X<A> x1;
   A a = get<A>();
@@ -1035,27 +1034,22 @@ namespace cwg62 { // cwg62: 2.9
 
   X<NoNameForLinkagePtr> x2;
   // cxx98-error at -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 at -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 at -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 at -4 {{while substituting explicitly-specified template arguments}}
+  //   cxx98-note at -3 {{while substituting explicitly-specified template arguments}}
   NoNameForLinkagePtr p2 = get<const NoNameForLinkagePtr>();
   // cxx98-error at -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 at -4 {{while substituting explicitly-specified template arguments}}
+  //   cxx98-note at -3 {{while substituting explicitly-specified template arguments}}
   int n1 = take(noNameForLinkagePtr);
   // cxx98-error at -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 at -4 {{while substituting deduced template arguments}}
+  //   cxx98-note at -3 {{while substituting deduced template arguments}}
 
   X<Danger> x4;
 
@@ -1063,24 +1057,18 @@ namespace cwg62 { // cwg62: 2.9
     struct NoLinkage {};
     X<NoLinkage> a;
     // cxx98-error at -1 {{template argument uses local type }}
-    //   cxx98-note@#cwg62-X {{template parameter is declared here}}
     X<const NoLinkage> b;
     // cxx98-error at -1 {{template argument uses local type }}
-    //   cxx98-note@#cwg62-X {{template parameter is declared here}}
     get<NoLinkage>();
     // cxx98-error at -1 {{template argument uses local type }}
-    //   cxx98-note@#cwg62-get {{template parameter is declared here}}
-    //   cxx98-note at -3 {{while substituting explicitly-specified template arguments}}
+    //   cxx98-note at -2 {{while substituting explicitly-specified template arguments}}
     get<const NoLinkage>();
     // cxx98-error at -1 {{template argument uses local type }}
-    //   cxx98-note@#cwg62-get {{template parameter is declared here}}
-    //   cxx98-note at -3 {{while substituting explicitly-specified template arguments}}
+    //   cxx98-note at -2 {{while substituting explicitly-specified template arguments}}
     X<void (*)(NoLinkage A::*)> c;
     // cxx98-error at -1 {{template argument uses local type }}
-    //   cxx98-note@#cwg62-X {{template parameter is declared here}}
     X<int NoLinkage::*> d;
     // cxx98-error at -1 {{template argument uses local type }}
-    //   cxx98-note@#cwg62-X {{template parameter is declared here}}
   }
 } // namespace cwg62
 
@@ -1147,11 +1135,10 @@ namespace cwg69 { // cwg69: 9
   extern template void f<char>();
   // cxx98-error at -1 {{extern templates are a C++11 extension}}
   // expected-error at -2 {{explicit instantiation declaration of 'f' with internal linkage}}
-  template<void(*)()> struct Q {}; // #cwg69-Q
+  template<void(*)()> struct Q {};
   Q<&f<int> > q;
   // cxx98-error at -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 10ee50558c7e8..c5b96c4ab8ffc 100644
--- a/clang/test/CXX/drs/cwg10xx.cpp
+++ b/clang/test/CXX/drs/cwg10xx.cpp
@@ -43,7 +43,6 @@ namespace cwg1004 { // cwg1004: 5
   template<class T, template<class> class U = T::template A> struct Third { };
   // expected-error at -1 {{is a constructor name}}
   //   expected-note@#cwg1004-t {{in instantiation of default argument}}
-  //   expected-note at -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 8a9f285673699..9c72fefb5b65c 100644
--- a/clang/test/CXX/drs/cwg13xx.cpp
+++ b/clang/test/CXX/drs/cwg13xx.cpp
@@ -180,7 +180,6 @@ 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 at -1 {{template parameter is declared here}}
   template <typename T> struct C<T, T::value>;
   // expected-error at -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 5f40fe469b01b..626473f11d3ec 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -26,7 +26,6 @@ S<i> V; // #cwg1801-S-i
 // cxx98-14-error at -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
@@ -382,13 +381,13 @@ struct A {
   struct B {
     void e();
   };
-
+  
   void f();
-
+  
   struct D {
     void g();
   };
-
+  
   T h();
 
   template<T U>
@@ -400,13 +399,13 @@ struct A<int> {
   struct B {
     void e();
   };
-
+  
   int f();
-
+  
   struct D {
     void g();
   };
-
+  
   template<int U>
   int i();
 };
@@ -431,11 +430,11 @@ class C {
   template<class T>
   friend void A<T>::D::g();
   // expected-warning at -1 {{dependent nested name specifier 'A<T>::D::' for friend class declaration is not supported; turning off access control for 'C'}}
-
+  
   template<class T>
   friend int *A<T*>::h();
   // expected-warning at -1 {{dependent nested name specifier 'A<T *>::' for friend class declaration is not supported; turning off access control for 'C'}}
-
+  
   template<class T>
   template<T U>
   friend T A<T>::i();
@@ -452,7 +451,7 @@ template<class T>
 void A<T>::f() { (void)c.private_int; }
 int A<int>::f() { (void)c.private_int; return 0; }
 
-// FIXME: both definition of 'D::g' are not friends, so they don't have access to 'private_int'
+// FIXME: both definition of 'D::g' are not friends, so they don't have access to 'private_int' 
 template<class T>
 void A<T>::D::g() { (void)c.private_int; }
 void A<int>::D::g() { (void)c.private_int; }

diff  --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp
index 51f320fc43cfa..15bcc20b7fa2a 100644
--- a/clang/test/CXX/drs/cwg1xx.cpp
+++ b/clang/test/CXX/drs/cwg1xx.cpp
@@ -26,22 +26,18 @@ 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
@@ -156,17 +152,15 @@ namespace cwg112 { // cwg112: 3.1
   volatile T a2[1] = {};
   const Arr a3 = {}; // #cwg112-a3
   volatile Arr a4 = {};
-  template<const volatile T*> struct X {}; // #cwg112-X
+  template<const volatile T*> struct X {};
   // FIXME: Test this somehow in C++11 and on.
   X<a1> x1;
   // cxx98-error at -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 at -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
 
@@ -640,7 +634,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,
@@ -654,7 +648,7 @@ struct Base {
   };
 };
 struct Data {
-  void f() {
+  void f() {  
     int i2 = Base::i;
     // expected-error at -1 {{'i' is a private member of 'cwg138::example3::Base'}}
     //   expected-note@#cwg138-ex3-Base-i {{declared private here}}
@@ -1315,8 +1309,8 @@ namespace cwg184 { // cwg184: 2.7
 
   template<template<typename TT> class T> void A<T>::f() { // #cwg184-T
     T<> t;
-    // expected-error at -1 {{missing template argument for template parameter}}
-    //   expected-note@#cwg184-T {{template parameter is declared here}}
+    // expected-error at -1 {{too few template arguments for template template parameter 'T'}}
+    //   expected-note@#cwg184-T {{template 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 fd31a51f79ec5..141a1012aef93 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 {}; // #cwg2026-X
+  template<int> struct X {};
 
   const int a = a + 1; // #cwg2026-a
   // expected-warning at -1 {{variable 'a' is uninitialized when used within its own initialization}}
@@ -35,11 +35,9 @@ namespace cwg2026 { // cwg2026: 11
   // cxx98-error at -1 {{non-type template argument of type 'int' is not an integral constant expression}}
   //   cxx98-note at -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;
@@ -67,11 +65,9 @@ namespace cwg2026 { // cwg2026: 11
     // cxx98-error at -1 {{non-type template argument of type 'int' is not an integral constant expression}}
     //   cxx98-note at -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;
@@ -153,7 +149,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) {
@@ -433,7 +429,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 97bf320658759..42a7c4d7bbded 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 {}; // #cwg2100-X
+  template<const int *P, bool = true> struct X {};
   template<typename T> struct A {
     static const int n = 1;
     int f() {
@@ -35,7 +35,6 @@ namespace cwg2100 { // cwg2100: 12
       return X<&n>::n; // ok, value-dependent
       // cxx98-14-error at -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 a616120b82063..6c420ecd4c91d 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -317,20 +317,18 @@ namespace cwg319 { // cwg319: no
   typedef int (*pa)[n1];
   pa parr; // ok, type has linkage despite using 'n1'
 
-  template<typename> struct X {}; // #cwg319-X
+  template<typename> struct X {};
 
   void f() {
     struct A { int n; };
     extern A a; // FIXME: ill-formed
     X<A> xa;
     // cxx98-error at -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 at -1 {{template argument uses local type 'A'}}
-    //   cxx98-note@#cwg319-X {{template parameter is declared here}}
 
     const int n = 1;
     typedef int (*C)[n];
@@ -999,7 +997,6 @@ 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 at -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}}
@@ -1505,7 +1502,7 @@ namespace cwg389 { // cwg389: no
     typedef struct {} const C; // #cwg389-C
     typedef enum {} const D; // #cwg389-D
   };
-  template<typename> struct T {}; // #cwg389-T
+  template<typename> struct T {};
 
   struct WithLinkage1 {};
   enum WithLinkage2 {};
@@ -1546,23 +1543,18 @@ namespace cwg389 { // cwg389: no
 
   typedef T<WithoutLinkage1> BadArg1;
   // expected-error at -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 at -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 at -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 at -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 at -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 78b03b3df2323..0debc104ac45b 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -43,15 +43,12 @@ 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
@@ -83,9 +80,8 @@ 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 at -1 {{default template arguments for a function template are a C++11 extension}}
-  //   cxx98-note at -2 {{template parameter is declared here}}
-  // cxx98-error at -3 {{'type' is a protected member of 'cwg401::B'}}
-  //   cxx98-note at -4 {{in instantiation of default argument for 'f<B>' required here}}
+  // cxx98-error at -2 {{'type' is a protected member of 'cwg401::B'}}
+  //   cxx98-note at -3 {{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
@@ -640,17 +636,15 @@ namespace cwg431 { // cwg431: 2.8
 } // namespace cwg431
 
 namespace cwg432 { // cwg432: 3.0
-  template<typename T> struct A {}; // #cwg432-A
+  template<typename T> struct A {};
   template<typename T> struct B : A<B> {};
   // expected-error at -1 {{use of class template 'B' requires template arguments}}
-  //   expected-note@#cwg432-A {{template parameter is declared here}}
-  //   expected-note at -3 {{template is declared here}}
+  //   expected-note at -2 {{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 at -1 {{use of class template 'D' requires template arguments}}
-  //   since-cxx11-note@#cwg432-A {{template parameter is declared here}}
-  //   since-cxx11-note at -3 {{template is declared here}}
+  //   since-cxx11-note at -2 {{template is declared here}}
 #endif
 } // namespace cwg432
 
@@ -1383,7 +1377,6 @@ namespace cwg487 { // cwg487: 2.7
 
 namespace cwg488 { // cwg488: 2.9 c++11
   template <typename T> void f(T);
-  // cxx98-note at -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 11a77575c70c1..fb6acde459d9c 100644
--- a/clang/test/CXX/drs/cwg6xx.cpp
+++ b/clang/test/CXX/drs/cwg6xx.cpp
@@ -79,11 +79,10 @@ namespace cwg602 { // cwg602: 2.7
 } // namespace cwg602
 
 namespace cwg603 { // cwg603: 3.1
-  template<unsigned char> struct S {}; // #cwg603-S
+  template<unsigned char> struct S {};
   typedef S<'\001'> S1;
   typedef S<(1ul << __CHAR_BIT__) + 1> S1;
   // since-cxx11-error at -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
@@ -408,7 +407,7 @@ namespace cwg638 { // cwg638: no
 
   class X {
     typedef int type;
-    template<class T> friend struct A<T>::B;
+    template<class T> friend struct A<T>::B; 
     // expected-warning at -1 {{dependent nested name specifier 'A<T>::' for friend class declaration is not supported; turning off access control for 'X'}}
     template<class T> friend void A<T>::f();
     // expected-warning at -1 {{dependent nested name specifier 'A<T>::' for friend class declaration is not supported; turning off access control for 'X'}}
@@ -1079,7 +1078,7 @@ namespace cwg677 { // cwg677: no
   struct A {
     void *operator new(std::size_t);
     void operator delete(void*) = delete; // #cwg677-A-delete
-    // cxx98-error at -1 {{deleted function definitions are a C++11 extension}}
+    // cxx98-error at -1 {{deleted function definitions are a C++11 extension}} 
   };
   struct B {
     void *operator new(std::size_t);

diff  --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp
index f40e1af14d111..3eedef3cf7712 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}} expected-note {{template parameter is declared here}}
+template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}}
 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; // expected-note 4{{template parameter is declared here}}
+template<unsigned char> using A = int; // cxx17-note 2{{template parameter is declared here}}
 
 using Int = A<E6>;
 using Int = A<EE::EE32>; // expected-error {{not implicitly convertible}}
@@ -79,8 +79,7 @@ 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 at -1 1{{template parameter is declared here}}
-// expected-note at -2 2{{template parameter is declared here}}
+// cxx17-note at -1 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 2572e766cb263..5433cfb21955d 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: missing template argument for template parameter}}
+  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'}}
   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 332f69bacb69e..692958ef565cf 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 {}; // expected-note {{template parameter is declared here}}
+template<int &ip> struct IR {};
 
 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 e979051e23419..629000d88acc3 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}} cxx17-note 2{{here}}
+  template <int* p> struct X0 { }; // expected-note 5{{here}}
 #if __cplusplus >= 201103L
   // precxx17-note at -2 2{{template parameter is declared here}}
 #endif
 
-  template <int (*fp)(int)> struct X1 { }; // cxx17-note {{here}} precxx17-note{{here}}
+  template <int (*fp)(int)> struct X1 { }; // cxx17-note {{here}}
 #if __cplusplus <= 199711L
   // precxx17-note at -2 {{here}}
 #endif
-  template <int &p> struct X2 { }; // expected-note 5{{here}}
+  template <int &p> struct X2 { }; // expected-note 4{{here}}
   template <const int &p> struct X2k { }; // expected-note {{here}}
   template <int (&fp)(int)> struct X3 { }; // expected-note 4{{here}}
 
@@ -180,7 +180,6 @@ namespace addr_of_obj_or_func {
 
 namespace bad_args {
   template <int* N> struct X0 { }; // precxx17-note 4{{template parameter is declared here}}
-                                   // cxx17-note at -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 bb7512a95ed3b..034ad49d0715c 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 1-2{{template parameter is declared here}}
-
+  
+  template<X const *Ptr> struct A2; // expected-note 0-1{{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 2638bef8f20a0..3caed045c6688 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 at -1 {{conversion from 'int' to 'void *' is not allowed in a converted constant expression}}
-  class TT // expected-note 2{{template parameter is declared here}}
+  class TT // expected-note 2{{previous template template parameter is 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; // expected-note {{template parameter is declared here}}
-template<int I, void *J> struct X0e; // expected-note {{template parameter is declared here}}
+template<int I, short J> struct X0d;
+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 {{template template argument is incompatible}}
-X0<X0e> inst_x0e; // expected-note {{template template argument is incompatible}}
+X0<X0d> inst_x0d; // expected-note {{has 
diff erent template parameters}}
+X0<X0e> inst_x0e; // expected-note{{template template argument has 
diff erent template parameters than its corresponding template template parameter}}
 
 template<typename T,
          template <T ...N> // expected-error {{conversion from 'short' to 'void *' is not allowed in a converted constant expression}}
                            // expected-error at -1 {{cannot be narrowed from type 'int' to 'short'}}
-         class TT // expected-note 2{{template parameter is declared here}}
+         class TT // expected-note 2{{previous template template parameter is 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;  // expected-note {{template parameter is declared here}}
-template<short I, void *J> struct X1e; // expected-note {{template parameter is declared here}}
+template<short I, long J> struct X1d;
+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 {{template template argument is incompatible}}
-X1<short, X1e> inst_x1e; // expected-note {{template template argument is incompatible}}
+X1<int, X1d> inst_ix1d;  // expected-note {{has 
diff erent template parameters}}
+X1<short, X1e> inst_x1e; // expected-note {{has 
diff erent template parameters}}
 
 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 5570a7f9d75de..342ffba53dbfa 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 at -1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
-// expected-note@#S1 {{template parameter is declared here}}
+// expected-note@#S1 {{'P' declared here}}
 // expected-note@#Y {{'Y' declared here}}
 S1<Z> s13;
 S1<W> s14;
 // expected-error at -1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
-// expected-note@#S1 {{template parameter is declared here}}
+// expected-note@#S1 {{'P' 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 at -1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
-// expected-note@#S4 {{template parameter is declared here}}
+// expected-note@#S4 {{'P' declared here}}
 // expected-note@#Y {{'Y' declared here}}
 S4<Z> s43;
 S4<W> s44;
 // expected-error at -1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
-// expected-note@#S4 {{template parameter is declared here}}
+// expected-note@#S4 {{'P' 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 65f3e178ac963..650f8585b115a 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=expected,cxx98 -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 
 template<class T> struct A {
@@ -13,8 +13,7 @@ template<typename T> struct B {
 };
 B<function> b; // expected-note{{instantiation of}}
 
-template <typename T> // #f0-temphead
-int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}}
+template <typename T> int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}}
 enum {e};
 // expected-note at -1 {{unnamed type used in template argument was declared here}}
 
@@ -23,7 +22,6 @@ void test_f0(int n) { // #here
 #if __cplusplus <= 199711L
   // expected-warning at -2 {{template argument uses unnamed type}}
   // expected-note at -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}}
@@ -35,9 +33,9 @@ void test_f0(int n) { // #here
 }
 
 namespace N0 {
-  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
+  template <typename R, typename A1> void f0(R (*)(A1));
+  template <typename T> int f1(T);
+  template <typename T, typename U> int f1(T, U);
   enum {e1};
 #if __cplusplus <= 199711L
   // expected-note at -2 2{{unnamed type used in template argument was declared here}}
@@ -53,7 +51,7 @@ namespace N0 {
  // expected-note at -2 {{unnamed type used in template argument was declared here}}
 #endif
 
-  template<typename T> struct X; // cxx98-note {{template parameter is declared here}}
+  template<typename T> struct X;
   template<typename T> struct X<T*> { };
 
   void f() {
@@ -61,28 +59,24 @@ namespace N0 {
 #if __cplusplus <= 199711L
     // expected-warning at -2 {{template argument uses unnamed type}}
     // expected-note at -3 {{while substituting deduced template arguments}}
-    // expected-note@#f0 {{template parameter is declared here}}
 #endif
 
        &f1<__typeof__(e1)>);
 #if __cplusplus <= 199711L
  // expected-warning at -2 {{template argument uses unnamed type}}
  // expected-note at -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 at -2 {{template argument uses unnamed type}}
     // expected-note at -3 {{while substituting deduced template arguments}}
-    // expected-note@#f1-2 {{template parameter is declared here}}
 #endif
 
     f1(e2);
 #if __cplusplus <= 199711L
     // expected-warning at -2 {{template argument uses unnamed type}}
     // expected-note at -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 cf01e406c14ad..388a80ee765c8 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; // expected-note {{template parameter is declared here}}
+  template<typename, int> static int z;
   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 2{{instantiation of}}
+X<int*> xf; // expected-note {{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 cab5c967b0c4f..ab4c663d24c7d 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> // expected-note {{template parameter is declared here}}
-  struct X0; // expected-note {{template is declared here}}
+  template<typename T, typename U, typename V = U>
+  struct X0; // expected-note 2{{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{{missing template argument for template parameter}}
+  X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}
   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 c6e6038fb6ddf..30e7c65dac91c 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 2{{template parameter is declared here}}
-    struct apply { // expected-note {{template is declared here}}
+    // expected-note{{template parameter is declared here}}
+    struct apply { // expected-note 2{{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{{missing template argument for template parameter}}
+  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, 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 5f9ea27234c81..7b661c275211b 100644
--- a/clang/test/CXX/temp/temp.deduct/p9.cpp
+++ b/clang/test/CXX/temp/temp.deduct/p9.cpp
@@ -15,14 +15,13 @@ void test_f() {
 }
 
 template <class T, unsigned = sizeof([]() { T::invalid; })>
-// expected-note at -1 {{template parameter is declared here}}
 void g(T);
 void g(...);
 void test_g() {
-  g(0); // expected-error at -5 {{type 'int' cannot be used prior to '::'}}
+  g(0); // expected-error at -4 {{type 'int' cannot be used prior to '::'}}
         // expected-note at -4 {{in instantiation of default argument}}
         // expected-note at -2 {{while substituting deduced template arguments}}
-        // expected-note at -8 {{while substituting into a lambda expression here}}
+        // expected-note at -7 {{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 e2eecdf0d4554..e9a978961769c 100644
--- a/clang/test/CXX/temp/temp.param/p1.cpp
+++ b/clang/test/CXX/temp/temp.param/p1.cpp
@@ -5,9 +5,8 @@ template<template<> class C> class D; // expected-error{{template template param
 
 
 struct A {};
-template<class M,
-         class T // expected-note {{template parameter is declared here}}
-           = A,  // expected-note{{previous default template argument defined here}}
+template<class M, 
+         class T = A,  // expected-note{{previous default template argument defined here}}
          class C> // expected-error{{template parameter missing a default argument}}
-class X0 {};
-X0<int> x0; // expected-error{{missing template argument for template parameter}}
+class X0 {}; // expected-note{{template is declared here}}
+X0<int> x0; // expected-error{{too few template arguments for class template 'X0'}}

diff  --git a/clang/test/CXX/temp/temp.param/p12.cpp b/clang/test/CXX/temp/temp.param/p12.cpp
index e3dfb65d29461..8317e7f24152c 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 {{template parameter is declared here}}
+template<template<class, int> class =// expected-note {{previous template template parameter is here}}
            Y1> // expected-error{{too many template arguments for class template 'Y1'}}
-               // expected-note at -1 {{template template argument is incompatible}}
+               // expected-note at -1 {{template template argument has 
diff erent template parameters than its corresponding template template parameter}}
   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 402a205f1ea63..83144a494937b 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, // expected-note 2{{template parameter is declared here}}
+  template<template<decltype(X)> class ...Take,
            template<place      > class ...Drop>
-  struct inner {
+  struct inner { // expected-note 2{{declared}}
     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 {{missing template argument}}
+    template inner<wrap<Ts>::template inner...>::take; // expected-error {{too few template arguments}}
 };
 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 {{missing template argument}}
+    template inner<wrap<Ts>::template inner...>::drop; // expected-error {{too few template arguments}}
 };
 
 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 {{missing template argument}}
+    Inner(Classes<>...); // expected-error {{too few}}
   };
 };
 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 aa1666f6306d0..a3478c0669661 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 {}; // expected-note {{template parameter is declared here}}
+  template<D d> struct Z {};
   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 cb048ecdf7001..ecb82372bcb47 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; // cxx98-note {{template parameter is declared here}}
+template<int n> struct S;
 
 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 749b45524f9e6..741ebc5de41fc 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> // expected-note {{template parameter is declared here}}
-T pi = T(3.1415926535897932385);
+template<typename T> 
+T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
 
 template int pi<int>;
 
 #ifndef FIXING
-template float pi<>; // expected-error {{missing template argument for template parameter}}
+template float pi<>; // expected-error {{too few template arguments for variable template 'pi'}}
 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 
diff erent 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 3923d160ef5cf..4b0fdb902633a 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 {}; // expected-note {{template parameter is declared here}}
+template <void (*)()> class PCT5 {};
 template <typename T> class PCT6 {
   // expected-note at +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 {}; // expected-note {{template parameter is declared here}}
+template <typename T, void (*)()> class PCTT5 {};
 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 63fd997add4ec..0283dba63b110 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> // expected-note {{template parameter is declared here}}
-struct A { };
+template<typename T>
+struct A { }; // expected-note{{template is declared here}}
 
 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 at +2{{template specialization declaration cannot be a friend}}
-  // expected-error at +1{{missing template argument for template parameter}}
+  // expected-error at +1{{too few template arguments for class template 'A'}}
   template <> friend class A<>;
 };

diff  --git a/clang/test/Misc/integer-literal-printing.cpp b/clang/test/Misc/integer-literal-printing.cpp
index bc52b3f044679..bd231a368fb70 100644
--- a/clang/test/Misc/integer-literal-printing.cpp
+++ b/clang/test/Misc/integer-literal-printing.cpp
@@ -14,7 +14,6 @@ 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 at -1 {{template parameter is declared here}}
 
 // PR14386
 enum class charTy : char {
@@ -24,7 +23,6 @@ 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 at -1 {{template parameter is declared here}}
 
 enum class scharTy : signed char {
   c = 0,
@@ -33,7 +31,6 @@ 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 at -1 {{template parameter is declared here}}
 
 enum class ucharTy : unsigned char {
   c = 0,
@@ -42,7 +39,6 @@ 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 at -1 {{template parameter is declared here}}
 
 enum class wcharTy : wchar_t {
   c = 0,
@@ -51,7 +47,6 @@ 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 at -1 {{template parameter is declared here}}
 
 enum class char16Ty : char16_t {
   c = 0,
@@ -60,7 +55,6 @@ 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 at -1 {{template parameter is declared here}}
 
 enum class char32Ty : char16_t {
   c = 0,
@@ -69,7 +63,6 @@ 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 at -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 250b54ade0ecb..73dff88e506b4 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> // expected-note 2{{template parameter is declared here}}
+template <typename T, auto Q>
 concept ReferenceOf = Q;
 
 // expected-error at +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 e25f7b5921301..b52ebba15087a 100644
--- a/clang/test/Modules/missing-body-in-import.cpp
+++ b/clang/test/Modules/missing-body-in-import.cpp
@@ -29,7 +29,6 @@ export module mod2;
 import mod1;
 
 struct C: B <A{"a", "b"}> { // expected-error {{non-type template argument is not a constant expression}}
-                            // expected-note at 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 1d8de709fd598..85b2a18d9e506 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 {}; // #G
+template<typename T> struct G {};
 template<typename T> struct J {};
 template<typename T = int> struct J;
 struct K : J<> {};
@@ -39,10 +39,8 @@ 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 at 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 at a.h:8 {{default argument declared here is not reachable}}
-// expected-note at 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 e47b4ef78afdf..9102bca8f6bb2 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 2{{template parameter is declared here}}
+template <class T, const GUID* g = &__uuidof(T)> // expected-note {{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 ffe53e7c6f77e..3c2169f86d6e7 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 parameter is declared here}}
+  template<class T1, typename T2> struct Known { }; // expected-note 3 {{template is declared here}}
   template<class T1, typename T2> struct X;
-  template<class T1, typename T2> struct ABC; // expected-note {{template parameter is declared here}}
+  template<class T1, typename T2> struct ABC; // expected-note {{template 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 {{missing template argument for template parameter}}
+    Known<T1>  // expected-error {{too few template arguments for class template 'Known'}}
   { };
 
   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 {{missing template argument for template parameter}}
-    Known<T1>  // expected-error {{missing template argument for template parameter}}
+    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'}}
   { };
 
   template<class T1, typename T2> struct foo5 :
@@ -92,7 +92,7 @@ namespace pr16225add {
 #if __cplusplus <= 199711L
     // expected-error at -2 {{use '> >'}}
 #endif
-    Known<T1>  // expected-error {{missing template argument for template parameter}}
+    Known<T1>  // expected-error {{too few template arguments for class template 'Known'}}
   { };
 
   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 2ece5a8ccdbea..5700b160cd364 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> // #C1-T
-  concept C1 = true;
+  template <typename T>
+  concept C1 = true; // #C1
 
   template <typename T>
   auto V1 = true; // #V1
 
   namespace b {
-    template <typename T> // #C2-T
-    concept C2 = true;
+    template <typename T>
+    concept C2 = true; // #C2
     template <typename T>
     auto V2 = true; // #V2
   }
 }
 
-template <typename T> // #C3-T
-concept C3 = true;
+template <typename T>
+concept C3 = true; // #C3
 template <typename T>
 auto V3 = true; // #V3
 template <template <typename T> typename C>
 constexpr bool test = true;
 
-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::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::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 eda8cb739f0af..a1594333abae7 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 {}; // expected-note 2{{template parameter is declared here}}
+  template<typename> struct Y {};
 
   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 {}; // expected-note 2{{template parameter is declared here}}
+  template<typename...> struct YP {};
 
   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 {}; // expected-note {{template parameter is declared here}}
+  template<typename T> struct U {};
   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 7d5fe38848f95..47d0f02ec545c 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 2{{here}}
+template <class T, bool Inferred = trait<T>::value> // expected-note {{here}}
 struct a {};
 
 template <class T>

diff  --git a/clang/test/SemaCXX/alias-template.cpp b/clang/test/SemaCXX/alias-template.cpp
index 90095b35a5774..b49d36a6267e6 100644
--- a/clang/test/SemaCXX/alias-template.cpp
+++ b/clang/test/SemaCXX/alias-template.cpp
@@ -167,10 +167,7 @@ namespace SFINAE {
     f<E>();
   }
 
-  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, typename U = EnableIf<is_enum<T>>> struct fail1 {}; // expected-note {{here}}
   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 51066a4516873..75309821998eb 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); // #foo
+template <class T> void foo(T);
 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 at -1 {{unnamed type used in template argument was declared here}}
 
@@ -36,7 +36,6 @@ typedef struct { // expected-error {{anonymous non-C-compatible type given name
 #if __cplusplus <= 199711L
     // expected-warning at -2 {{template argument uses unnamed type}}
     // expected-note at -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 0fb072709b051..c35f3a5632a05 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 {}; // expected-note {{template parameter is declared here}}
+  template<int n> struct IntParam {};
 
   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; }; // expected-note {{template parameter is declared here}}
+  template<int n> struct Id { int k = n; };
   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 d984ced4eae3b..cc041a4acd18c 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 {}; // expected-note {{template parameter is declared here}}
+  template<int n> struct S {};
   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 6b8495e8c9d95..c8204c21523a3 100644
--- a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
+++ b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
@@ -74,7 +74,6 @@ 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 at -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 931acfd86f808..fef4674d17841 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> // expected-note 2{{template parameter is declared here}}
+template<mem_ptr_type ptr>
 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 3986251357aca..6ffb3a5884d17 100644
--- a/clang/test/SemaCXX/cxx98-compat-flags.cpp
+++ b/clang/test/SemaCXX/cxx98-compat-flags.cpp
@@ -1,8 +1,7 @@
 // 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> // expected-note 2{{template parameter is declared here}}
-int TemplateFn(T) { return 0; }
+template<typename T> 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 99ed49481614b..d31d95a9995f1 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -173,8 +173,7 @@ 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> // expected-note 2{{template parameter is declared here}}
-int TemplateFn(T) { return 0; }
+template<typename T> int TemplateFn(T) { return 0; }
 void LocalTemplateArg() {
   struct S {};
   TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}}
@@ -189,7 +188,7 @@ int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{
 #ifndef CXX17COMPAT
 namespace RedundantParensInAddressTemplateParam {
   int n;
-  template<int*p> struct S {}; // expected-note 2{{template parameter is declared here}}
+  template<int*p> struct S {};
   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}}
 }
@@ -312,7 +311,7 @@ namespace LiteralUCNs {
 // template argument evaluation rules.
 #ifndef CXX17COMPAT
 namespace NonTypeTemplateArgs {
-  template<typename T, T v> struct S {}; // expected-note 2{{template parameter is declared here}}
+  template<typename T, T v> struct S {};
   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}}
@@ -321,8 +320,8 @@ namespace NonTypeTemplateArgs {
 
 namespace NullPointerTemplateArg {
   struct A {};
-  template<int*> struct X {}; // expected-note {{template parameter is declared here}}
-  template<int A::*> struct Y {}; // expected-note {{template parameter is declared here}}
+  template<int*> struct X {};
+  template<int A::*> struct Y {};
   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 b48f93778ff81..1554b1af5d59a 100644
--- a/clang/test/SemaCXX/implicit-member-functions.cpp
+++ b/clang/test/SemaCXX/implicit-member-functions.cpp
@@ -63,7 +63,6 @@ namespace Recursion {
     template<typename T,
              typename = typename InvokeCopyConstructor<typename T::type>::type>
     // expected-note at -1 {{in instantiation of template class}}
-    // expected-note at -2 {{template parameter is declared here}}
     A(const T &);
     // expected-note at -1 {{in instantiation of default argument}}
   };

diff  --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index f411ef581f216..2d2dde82a28e6 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -442,7 +442,7 @@ struct A {
   // expected-error at -1 {{field has incomplete type 'void'}}
 };
 
-template <typename F> // cxx03-note {{template parameter is declared here}}
+template <typename F>
 void g(F f) {
   auto a = A<decltype(f())>();
   // expected-note at -1 {{in instantiation of template class 'PR20731::A<void>' requested here}}
@@ -499,14 +499,12 @@ namespace error_in_transform_prototype {
 
 namespace PR21857 {
   template<typename Fn> struct fun : Fn {
-    // cxx03-note at -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 at -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 at -1 2{{while substituting deduced template arguments into function template}}
+                         // cxx03-note at -1 {{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 7fca9ed8ea35d..71b7b8260d4ab 100644
--- a/clang/test/SemaCXX/make_integer_seq.cpp
+++ b/clang/test/SemaCXX/make_integer_seq.cpp
@@ -48,6 +48,5 @@ 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{{template template argument is incompatible}}
+__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{
diff erent template parameters}}
 // expected-error at 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 a59e0320e5306..7190dcad76f1a 100644
--- a/clang/test/SemaCXX/type-trait-common-type.cpp
+++ b/clang/test/SemaCXX/type-trait-common-type.cpp
@@ -5,12 +5,10 @@
 #  error
 #endif
 
-// 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}}
+// expected-note@*:* {{template declaration from hidden source: template <template <class ...> class, template <class> class, class, class ...>}}
 
 void test() {
-  __builtin_common_type<> a; // expected-error {{missing template argument for template parameter}}
+  __builtin_common_type<> a; // expected-error {{too few template arguments for template '__builtin_common_type'}}
   __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 7f466237370e6..9745f097c76b7 100644
--- a/clang/test/SemaCXX/undefined-internal.cpp
+++ b/clang/test/SemaCXX/undefined-internal.cpp
@@ -209,11 +209,9 @@ namespace OverloadUse {
     t<f>(&n, &n); // expected-note {{used here}}
 #if __cplusplus < 201103L
     // expected-warning at -3 {{non-type template argument referring to function 'f' with internal linkage}}
-    // expected-note at -7 {{template parameter is declared here}}
+    // expected-note at -4 {{while substituting explicitly-specified template arguments}}
+    // expected-warning at -4 {{non-type template argument referring to function 'f' with internal linkage}}
     // expected-note at -5 {{while substituting explicitly-specified template arguments}}
-    // expected-warning at -5 {{non-type template argument referring to function 'f' with internal linkage}}
-    // expected-note at -9 {{template parameter is declared here}}
-    // expected-note at -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 1fe0916b3226c..79c9d339b6f20 100644
--- a/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp
+++ b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp
@@ -10,7 +10,6 @@ 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 at -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 e62cc8d24e3a7..941e0a975d5f4 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 at +1 {{class template 'RWBuffer' requires template arguments}}
 RWBuffer BufferErr1;
 
-// expected-error at +1 {{missing template argument for template parameter}}
+// expected-error at +1 {{too few template arguments for class template 'RWBuffer'}}
 RWBuffer<> BufferErr2;
 
 // test implicit RWBuffer concept
@@ -39,7 +39,7 @@ template<typename T> struct TemplatedVector {
 
 // structs not allowed
 // expected-error at +4 {{constraints not satisfied for class template 'RWBuffer'}}
-// expected-note@*:* {{template parameter from hidden source: typename element_type}}
+// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}
 // 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 d5e2142cc55d2..fb14429025d5a 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 at +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 at +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 at +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 at +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 at +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 at +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 e113bea22f8a8..8aacf21faf091 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> // expected-note {{template parameter is declared here}}
+template<template<typename T, typename U> class TT>
 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 c27b193361654..ab5cad72faf1b 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 {{missing template argument for template parameter}}
+  Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}}
   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 {{missing template argument for template parameter}}
+    Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}}
     int z = Bar(); // expected-error {{use of template template parameter 'Bar' requires template arguments}}
   }
 }
@@ -304,12 +304,11 @@ namespace resolved_nttp {
   using TB = int (*)(int (*)[1], int (*)[2], int (*)[3]);
 
   template <typename T, int ...M> struct C {
-    template <T... N> // expected-note 3{{template parameter is declared here}}
-      using Fn = T(int(*...A)[N]);
+    template <T... N> 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 3{{instantiation of}}
+  using TC2 = decltype(C<bool, 2, 3>::p); // expected-note {{instantiation of}}
 }

diff  --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp
index 3fb5eb6d1c3ac..51d98d4b3b202 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 at -1 2{{no template parameter}}
+    // expected-note at -1 2{{substitution failure: too few template arguments}}
 
     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 at -1 {{no template parameter}}
+      // expected-note at -1 {{substitution failure: too few template arguments}}
       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 at -1 {{no template parameter}}
+      // expected-note at -1 {{too few template arguments for class template 'A'}}
       return f(TT2<int, 2>());
     }
 
@@ -347,11 +347,11 @@ namespace packs {
   namespace t1 {
     template<template<int, int...> class> struct A {};
     // expected-error at -1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}}
-    // expected-note at -2 {{template parameter is declared here}}
+    // expected-note at -2 {{previous template template parameter is here}}
 
-    template<char> struct B; // expected-note {{template parameter is declared here}}
+    template<char> struct B;
     template struct A<B>;
-    // expected-note at -1 {{template template argument is incompatible}}
+    // expected-note at -1 {{has 
diff erent template parameters}}
   } // 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 at -1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}}
-    // expected-note at -2 {{template parameter is declared here}}
+    // expected-note at -2 {{previous template template parameter is here}}
 
-    template<char> struct B; // expected-note {{template parameter is declared here}}
+    template<char> struct B;
     template struct A<B>;
-    // expected-note at -1 {{template template argument is incompatible}}
+    // expected-note at -1 {{has 
diff erent template parameters}}
   } // namespace t3
   namespace t4 {
     template<template<char...> class> struct A {};
@@ -501,7 +501,7 @@ namespace constraints {
   // expected-note at -1 {{similar constraint expressions not considered equivalent}}
 
   namespace t1 {
-    template<template<C1, class... T1s> class TT1> // expected-note {{template parameter is declared here}}
+    template<template<C1, class... T1s> class TT1> // expected-note {{TT1' 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 {{template parameter is declared here}}
+    template<template<C1, class... T1s> class TT1> // expected-note {{'TT1' 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 {{template parameter is declared here}}
+    template<template<C1... T1s> class TT1> // expected-note {{'TT1' 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 {{template parameter is declared here}}
+    template<template<C2... T1s> class TT1> // expected-note {{'TT1' declared here}}
     struct A {};
     template<C1 T2> struct B {}; // expected-note {{'B' declared here}}
     template struct A<B>;
     // expected-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
   } // namespace t5
   namespace t6 {
-    template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}}
+    template<template<C1... T1s> class TT1> // expected-note {{'TT1' 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 {{template parameter is declared here}}
+    template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}}
     struct A {};
     template<D1 T2> struct B {}; // expected-note {{'B' declared here}}
     template struct A<B>;
     // expected-error at -1 {{'B' is more constrained than template template parameter 'TT1'}}
   } // namespace t9
   namespace t10 {
-    template<template<class...> requires C1<int> class TT1> // expected-note {{template parameter is declared here}}
+    template<template<class...> requires C1<int> class TT1> // expected-note {{'TT1' declared here}}
     struct A {};
 
     template<class> requires C2<int> struct B {}; // expected-note {{'B' declared here}}
@@ -613,21 +613,21 @@ namespace nttp_auto {
     // FIXME: Shouldn't accept parameters after a parameter pack.
     template<template<auto... Va1, auto Va2> class> struct A {};
     // expected-error at -1 {{deduced non-type template argument does not have the same type as the corresponding template parameter ('auto' vs 'int')}}
-    // expected-note at -2 {{template parameter is declared here}}
+    // expected-note at -2 {{previous template template parameter is here}}
     template<int... Vi> struct B;
     // expected-note at -1 {{template parameter is declared here}}
     template struct A<B>;
-    // expected-note at -1 {{template template argument is incompatible}}
+    // expected-note at -1 {{
diff erent template parameters}}
   } // namespace t2
   namespace t3 {
     // FIXME: Shouldn't accept parameters after a parameter pack.
     template<template<auto... Va1, auto... Va2> class> struct A {};
     // expected-error at -1 {{deduced non-type template argument does not have the same type as the corresponding template parameter ('auto' vs 'int')}}
-    // expected-note at -2 {{template parameter is declared here}}
+    // expected-note at -2 {{previous template template parameter is here}}
     template<int... Vi> struct B;
     // expected-note at -1 {{template parameter is declared here}}
     template struct A<B>;
-    // expected-note at -1 {{template template argument is incompatible}}
+    // expected-note at -1 {{
diff erent template parameters}}
   } // namespace t3
 } // namespace nttp_auto
 

diff  --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp
index fdf666baf01bb..5ea34c0254ec1 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 parameter is declared here}}
+template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
 
 X<int, 1> *x1;
 X<int> *x2;
 
-X<> *x3; // expected-error{{missing template argument for template parameter}}
+X<> *x3; // expected-error{{too few template arguments for class template 'X'}}
 
 template<typename U = float, int M> struct X;
 
@@ -20,7 +20,6 @@ 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 at -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>;
@@ -51,14 +50,12 @@ 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>'}} \
-                                              // expected-note {{template parameter is declared here}}
-  struct Inner1 { };
+                                              // expected-error{{no type named 'type' in 'X1<char>'}}
+  struct Inner1 { }; // expected-note{{template is declared here}}
 
   template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \
-                                   // expected-error{{no member named 'value' in 'X1<char>'}} \
-                                   // expected-note {{template parameter is declared here}}
-  struct NonType1 { };
+                                   // expected-error{{no member named 'value' in 'X1<char>'}}
+  struct NonType1 { }; // expected-note{{template is declared here}}
 
   template<T Value>
   struct Inner2 { };
@@ -77,10 +74,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{{missing template argument for template parameter}}
+X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}}
 
 X2<int>::NonType1<'a'> x2_nontype1;
-X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{missing template argument for template parameter}}
+X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}}
 
 // Check multi-level substitution into template type arguments
 X2<int>::Inner3<float>::VeryInner<> vi;
@@ -115,12 +112,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 {}; // expected-note {{template parameter is declared here}}
+template<int> struct X5 {};
 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 at -1 {{template template argument is incompatible}}
-                                   // expected-note at -2 {{template parameter is declared here}}
+                                   // expected-note at -1 {{has 
diff erent template parameters}}
+                                   // expected-note at -2 {{previous template template parameter is 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 4eeaa3db6e77c..4757870d13b70 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 {}; // expected-note {{template parameter is declared here}}
+  template<int A::*> struct X {};
   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 601049ae93c22..dce30aa2af4ee 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; // expected-note {{template parameter is declared here}}
+template<int> struct B;
 
 template<typename T,
          template<T Value> class X> // expected-error{{cannot have type 'float'}}
                                     // expected-error at -1 {{cannot be narrowed from type 'long long' to 'int'}}
-                                    // expected-note at -2 2{{template parameter is declared here}}
+                                    // expected-note at -2 {{previous template template parameter is here}}
 struct X0 { };
 
 X0<int, B> x0b1;
 X0<float, B> x0b2; // expected-note{{while substituting}}
-X0<long long, B> x0b3; // expected-note {{template template argument is incompatible}}
+X0<long long, B> x0b3; // expected-note {{has 
diff erent template parameters}}
 
 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 8ef9f123e9c1c..3e70a2148ca1a 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,10 +22,9 @@ 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 at -1 {{template parameter is declared here}}
   struct Def2;
 
-template<> struct Def2<int> {
+template<> struct Def2<int> { 
   void foo();
 };
 
@@ -41,11 +40,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();
 };
 
@@ -84,7 +83,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();
 };
 
@@ -92,7 +91,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 e5db31000a419..ffa77cf1ee567 100644
--- a/clang/test/SemaTemplate/instantiation-default-2.cpp
+++ b/clang/test/SemaTemplate/instantiation-default-2.cpp
@@ -4,7 +4,8 @@
 
 template<typename T, T Value> struct Constant;
 // FIXME: bad location precxx20-error at -1 {{a non-type template parameter cannot have type 'float'}}
-// expected-note at -2 2{{template parameter is declared here}}
+// expected-note at -2 {{template parameter is declared here}}
+// cxx20-note at -3 {{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 d98d98240db7c..1a97dbf769ec6 100644
--- a/clang/test/SemaTemplate/instantiation-dependence.cpp
+++ b/clang/test/SemaTemplate/instantiation-dependence.cpp
@@ -17,8 +17,7 @@ namespace PR24076 {
   }
 
   template<class T,
-           class = // expected-note {{template parameter is declared here}}
-             void_t<decltype(declval<T>() + 1)>> // expected-error {{invalid operands to binary expression}}
+           class = 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 82bba72929553..24cd941042917 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 { // \
-// expected-error{{recursive template instantiation exceeded maximum depth of 128}} \
-// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
+template<int N> struct S {
   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 {{skipping 125 contexts in backtrace}} \
+// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
 
 };
 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 a0d5a1458ce5d..4464fbb31b383 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 { // \
-// expected-error {{recursive template instantiation exceeded maximum depth of 16}} \
-// expected-note {{use -ftemplate-depth}}
+template<int N> struct X {
   static int go(int a) noexcept(noexcept(X<N+1>::go(a))); // \
+// 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 {{skipping 7 context}} \
+// expected-note {{use -ftemplate-depth}}
 };
 
 void f() {

diff  --git a/clang/test/SemaTemplate/instantiation-depth.cpp b/clang/test/SemaTemplate/instantiation-depth.cpp
index 35cf42a2724bc..15e2c2ba7c8bd 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 at -1 {{recursive template instantiation exceeded maximum depth of 5}}
-// expected-note at -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 {{skipping 2 contexts in backtrace}} \
+// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
 };
 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 d2b02e511e2ed..5e926c5087f93 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 parameter is declared here}}
+template <typename Type, int TSize> class Vec {}; // expected-note {{template is declared here}}
 
 template <int TDim> class Index : public Vec<int, TDim> {
   // after-error at +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 {{missing template argument for template parameter}}
+  Wrong2() : Vec<T>() {} // expected-error {{too few template arguments for class template 'Vec'}}
 };
 
 template class Wrong2<double>;

diff  --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp
index 4e82371ef13f7..4d7f2d9c5c946 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 at -1 {{cannot be narrowed from type 'long long' to 'int'}}
-                                              // expected-note at -2 {{template parameter is declared here}}
+                                              // expected-note at -2 {{previous template template parameter is here}}
     struct Inner { };
 };
 
-template<typename T, int Value> // expected-note {{template parameter is declared here}}
+template<typename T, int Value>
   struct X2_arg;
 
 X2<int>::Inner<X2_arg> x2i1;
 X2<float> x2a; // expected-note{{instantiation}}
-X2<long long>::Inner<X2_arg> x2i3; // expected-note {{template template argument is incompatible}}
+X2<long long>::Inner<X2_arg> x2i3; // expected-note {{has 
diff erent template parameters}}
 
 namespace PR10896 {
   template<typename TN>

diff  --git a/clang/test/SemaTemplate/partial-spec-instantiate.cpp b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
index f171bf4c712b8..0b84df69562e2 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 { }; // #rdar9169404-X
+  template<typename T, T N> struct X { };
   template<bool C> struct X<bool, C> {
     typedef int type;
   };
@@ -50,7 +50,6 @@ namespace rdar9169404 {
   X<bool, -1>::type value;
 #if __cplusplus >= 201103L
   // expected-error at -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 26683b11a1256..ac8053da101ab 100644
--- a/clang/test/SemaTemplate/recovery-crash.cpp
+++ b/clang/test/SemaTemplate/recovery-crash.cpp
@@ -26,14 +26,13 @@ namespace PR16134 {
 }
 
 namespace PR16225 {
-  template <typename T> void f(); // #PR16225-f
+  template <typename T> void 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 at -2 {{template argument uses local type 'LocalStruct'}}
     // expected-note at -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 b6e2fc9d35999..c7bfea4132d5e 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(); // expected-error {{exceeded maximum depth}}
+  template<typename T> T &&declval();
 
   namespace mlir {
     template<typename T, typename = decltype(declval<ostream&>() << declval<T&>())>
-    ostream &operator<<(ostream& os, const T& obj);
+    ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}}
     struct Value;
   }
 
@@ -48,12 +48,12 @@ namespace template_argument_recursion {
 
 namespace template_parameter_type_recursion {
   struct ostream;
-  template<typename T> T &&declval(); // expected-error {{exceeded maximum depth}}
+  template<typename T> T &&declval();
   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);
+    ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}}
     struct Value;
   }
 

diff  --git a/clang/test/SemaTemplate/temp_arg.cpp b/clang/test/SemaTemplate/temp_arg.cpp
index 9048744f3095a..538056a4e44c7 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> // expected-note {{template parameter is declared here}}
-  class A; // precxx17-note 2 {{template is declared here}} \
-              cxx17-note {{template is declared here}} \
+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}} \
               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{{missing template argument for template parameter}}
+A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}}
 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 36d7d9cb6f519..2a1c059df002e 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 6{{template parameter is declared here}}
+template<int N> struct A; // expected-note 5{{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 2{{template parameter is declared here}}
+template<int fp(int)> struct A3; // expected-note 1{{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 2{{template parameter is declared here}}
+template<int (&fr)(int)> struct A5; // expected-note{{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; // expected-note{{template parameter is declared here}}
+template<int Z::*pm> struct A7c;
 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,10 +442,7 @@ 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 // expected-note {{template parameter is declared here}}
-    > struct D;
-    // expected-note at -1 {{template is declared here}}
+    template<typename T, int N, int M> struct D; // expected-note {{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;
@@ -495,12 +492,7 @@ namespace dependent_backreference {
   Incomplete f(int); // expected-note 2{{here}}
   int f(short);
 
-  template<typename T, T Value,
-    int(*)[ // expected-note 2{{template parameter is declared here}}
-      sizeof(f(Value)) // expected-error 2{{incomplete}}
-    ]
-  > struct X {};
-
+  template<typename T, T Value, int(*)[sizeof(f(Value))]> struct X {}; // expected-error 2{{incomplete}}
   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 32bb678c4bf4e..5752cbac0291d 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 {}; // expected-note {{template parameter is declared here}}
+  template<int> struct A {};
   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 724ac85b5f73d..c35743b87adbc 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 15{{template parameter is declared here}}
+template<typename T, T val> struct A {}; // expected-note 3{{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 { }; // expected-note {{template parameter is declared here}}
-    template<decltype(auto) v> struct DA { }; // expected-note {{template parameter is declared here}}
+    template<auto v> struct A { };
+    template<decltype(auto) v> struct DA { };
     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 3{{template parameter is declared here}}
+  template <const S &> struct A {}; // expected-note {{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 221f8595f43d5..56ceb7af4ccd9 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 {}; // expected-note 2{{template parameter is declared here}}
+template<int *> struct IntPtr {};
 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 {}; // expected-note 4{{template parameter is declared here}}
+template<int &> struct IntRef {};
 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 {{template parameter is declared here}}
+                 // expected-note@#ClassNTTP1 {{passing argument to parameter 'a' here}}
 
   struct B {
     constexpr B() {}
     constexpr B(int) = delete; // expected-note {{here}}
   };
-  template<B> struct Q {}; // expected-note {{template parameter is declared here}}
+  template<B> struct Q {}; // expected-note {{passing argument to parameter 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 {{template parameter is declared here}}
+  template<C> struct R {}; // expected-note {{passing argument to parameter 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 {}; // expected-note {{template parameter is declared here}}
+  template <A> struct X {};
   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 6{{template parameter is declared here}}
+  template<const int &> struct A {}; // expected-note {{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 {}; // expected-note 3{{template parameter is declared here}}
+  template<const int*> struct B {};
   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 {}; // expected-note {{template parameter is declared here}}
+  template<C> struct D {};
   D<C{nullptr, &r3}> d; // expected-error {{pointer to temporary object}}
 }
 
 namespace StringLiteral {
-  template<decltype(auto)> struct Y {}; // expected-note 6{{template parameter is declared here}}
+  template<decltype(auto)> struct Y {};
   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 {}; // expected-note 4{{template parameter is declared here}}
+  template<decltype(auto)> struct Y {};
   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 {}; // expected-note 7{{template parameter is declared here}}
+  template<decltype(auto)> struct Y {};
 
   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 a87ffcbc66659..e74c031eba4c1 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> // expected-note {{template parameter is declared here}}
+template <Test t>
 struct A {
     static constexpr auto a = t.a;
     static constexpr auto b = t.b;
 };
 
-template <auto N> // expected-note {{template parameter is declared here}}
+template <auto N>
 struct Auto {};
 
-template <typename T, T elem> // expected-note {{template parameter is declared here}}
+template <typename T, T elem>
 struct Explicit{};
 
 struct L {};
@@ -57,8 +57,8 @@ void test() {
     DefaultParam3<> d3;
 }
 
-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}}
+template<auto n> struct B { /* ... */ };
+template<int i> struct C { /* ... */ };
 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 c10b594c7c2b4..aa53dba652050 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 at -1 3{{template parameter is declared here}}
+// expected-note at -1 2{{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<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}}
 
 template<template<int I> class X> struct C;
 // expected-error at -1 {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}}
-// expected-note at -2 {{template parameter is declared here}}
+// expected-note at -2 {{previous template template parameter is here}}
 
 template<class> struct X; // expected-note {{template is declared here}}
 template<int N> struct Y; // expected-note {{template parameter is declared here}}
@@ -18,10 +18,7 @@ template<const int &N> struct Yref; // expected-note {{template parameter is dec
 namespace N {
   template<class> struct Z;
 }
-template<
-  class,
-  class> // expected-note {{template parameter is declared here}}
-struct TooMany;
+template<class, class> struct TooMany; // expected-note{{template is declared here}}
 
 
 A<X> *a1;
@@ -29,14 +26,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 at -1 {{template template argument is incompatible}}
-A<TooMany> *a5; // expected-error@#A {{no template parameter in this template template parameter}}
-                // expected-note at -1 {{template template argument is incompatible}}
+          // expected-note at -1 {{
diff erent template parameters}}
+A<TooMany> *a5; // expected-error {{too few template arguments for class template 'TooMany'}}
+                // expected-note at -1 {{
diff erent template parameters}}
 B<X> *a6; // expected-error {{too many template arguments for class template 'X'}}
-          // expected-note at -1 {{template template argument is incompatible}}
+          // expected-note at -1 {{
diff erent template parameters}}
 C<Y> *a7;
 C<Ylong> *a8;
-C<Yref> *a9; // expected-note {{template template argument is incompatible}}
+C<Yref> *a9; // expected-note {{
diff erent template parameters}}
 
 template<typename T> void f(int);
 
@@ -112,7 +109,7 @@ void foo() {
 
 namespace CheckDependentNonTypeParamTypes {
   template<template<typename T, typename U, T v> class X> struct A {
-    // expected-note at -1 {{template parameter is declared here}}
+    // expected-note at -1 {{previous template template parameter is here}}
     void f() {
       X<int, void*, 3> x;
     }
@@ -139,7 +136,7 @@ namespace CheckDependentNonTypeParamTypes {
   };
 
   // FIXME: This should probably be rejected, but the rules are at best unclear.
-  A<B> ab; // expected-note {{template template argument is incompatible}}
+  A<B> ab; // expected-note {{
diff erent template parameters}}
 
   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 e9084d1c27413..2e5a36ae6ed08 100644
--- a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
+++ b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
 
+// expected-note at temp_arg_template_p0522.cpp:* 1+{{template is declared here}}
 // expected-note at temp_arg_template_p0522.cpp:* 1+{{template parameter is declared here}}
+// expected-note at 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
@@ -31,14 +33,14 @@ namespace IntParam {
         Ti<iDi>,
         Ti<Pi>,
         Ti<iDt>>;
-  using err1 = Ti<ii>; // expected-error@#Ti {{no template parameter in this template template parameter}}
-                       // expected-note at -1 {{template template argument is incompatible}}
-  using err2 = Ti<iiPi>; // expected-error@#Ti {{no template parameter in this template template parameter}}
-                         // expected-note at -1 {{template template argument is incompatible}}
+  using err1 = Ti<ii>; // expected-error {{too few template arguments for class template 'ii'}}
+                       // expected-note at -1 {{
diff erent template parameters}}
+  using err2 = Ti<iiPi>; // expected-error {{too few template arguments for class template 'iiPi'}}
+                         // expected-note at -1 {{
diff erent template parameters}}
   using err3 = Ti<t0>; // expected-error@#Ti {{template argument for template type parameter must be a type}}
-                       // expected-note at -1 {{template template argument is incompatible}}
-  using err4 = Ti<it>; // expected-error@#Ti {{no template parameter in this template template parameter}}
-                       // expected-note at -1 {{template template argument is incompatible}}
+                       // expected-note at -1 {{
diff erent template parameters}}
+  using err4 = Ti<it>; // expected-error {{too few template arguments for class template 'it'}}
+                       // expected-note at -1 {{
diff erent template parameters}}
 }
 
 // These are accepted by the backwards-compatibility "parameter pack in
@@ -47,11 +49,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 at -1 {{template template argument is incompatible}}
+                        // expected-note at -1 {{
diff erent template parameters}}
   using err2 = TPi<iDt>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
-                         // expected-note at -1 {{template template argument is incompatible}}
+                         // expected-note at -1 {{
diff erent template parameters}}
   using err3 = TPi<it>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
-                        // expected-note at -1 {{template template argument is incompatible}}
+                        // expected-note at -1 {{
diff erent template parameters}}
 }
 
 namespace IntAndPackParam {
@@ -62,19 +64,19 @@ namespace IntAndPackParam {
 
 namespace DependentType {
   using ok = Pt<tT0<int, i>, tT0<int, iDi>>;
-  using err1 = tT0<int, ii>; // expected-error@#tT0 {{no template parameter in this template template parameter}}
-                             // expected-note at -1 {{template template argument is incompatible}}
+  using err1 = tT0<int, ii>; // expected-error {{too few template arguments for class template 'ii'}}
+                             // expected-note at -1 {{
diff erent template parameters}}
   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 at -1 {{template template argument is incompatible}}
+                                   // expected-note at -1 {{
diff erent template parameters}}
   using err2b = tT0<void*, i>; // expected-error@#tT0 {{value of type 'void *' is not implicitly convertible to 'int'}}
-                               // expected-note at -1 {{template template argument is incompatible}}
+                               // expected-note at -1 {{
diff erent template parameters}}
   using err3 = tT0<short, t0>; // expected-error@#tT0 {{template argument for template type parameter must be a type}}
-                               // expected-note at -1 {{template template argument is incompatible}}
+                               // expected-note at -1 {{
diff erent template parameters}}
 
   using ok2 = Tt0<t0>;
   using err4 = Tt0<it>; // expected-error@#Tt0 {{template argument for non-type template parameter must be an expression}}
-                        // expected-note at -1 {{template template argument is incompatible}}
+                        // expected-note at -1 {{
diff erent template parameters}}
 }
 
 namespace Auto {
@@ -91,22 +93,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 at -1 {{template template argument is incompatible}}
+                     // expected-note at -1 {{
diff erent template parameters}}
   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 at -1 {{template template argument is incompatible}}
+                    // expected-note at -1 {{
diff erent template parameters}}
 
   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 at -1 {{template template argument is incompatible}}
+                    // expected-note at -1 {{
diff erent template parameters}}
   TIntPtr<IntPtr> ipip;
 
   TAuto<Auto> aa;
   TAuto<AutoPtr> aap; // expected-error@#AutoPtr {{could not match 'auto *' against 'auto'}}
-                      // expected-note at -1 {{template template argument is incompatible}}
+                      // expected-note at -1 {{
diff erent template parameters}}
   TAuto<Int> ai; // FIXME: ill-formed (?)
   TAuto<IntPtr> aip; // FIXME: ill-formed (?)
 
@@ -128,7 +130,7 @@ namespace Auto {
   // parameters.
   TDecltypeAuto<Auto> daa;
   TDecltypeAuto<AutoPtr> daap; // expected-error@#AutoPtr {{could not match 'auto *' against 'decltype(auto)'}}
-                               // expected-note at -1 {{template template argument is incompatible}}
+                               // expected-note at -1 {{
diff erent template parameters}}
 
   int n;
   template<auto A, decltype(A) B = &n> struct SubstFailure;
@@ -157,10 +159,11 @@ namespace GH101394 {
   } // namespace t1
   namespace t2 {
     template<template<Y> class> struct A {}; // #A
-    template<X> struct B;
+    template<X> struct B; // #B
     template struct A<B>;
     // expected-error@#A {{no viable conversion from 'const Y' to 'X'}}
-    // expected-note at -2  {{template template argument is incompatible}}
+    // expected-note at -2  {{
diff erent template parameters}}
     // 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 a0d2bc383d917..392d2573d3d0e 100644
--- a/clang/test/SemaTemplate/temp_arg_type.cpp
+++ b/clang/test/SemaTemplate/temp_arg_type.cpp
@@ -1,12 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -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 at -1 4{{template parameter is declared here}}
-// cxx98-note at -2    2{{template parameter is declared here}}
-// expected-note at -3  {{template is declared here}}
+template<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}}
 
 // [temp.arg.type]p1
 A<0> *a1; // expected-error{{template argument for template type parameter must be a type}}


        


More information about the cfe-commits mailing list