https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/125453

>From adde9f1f8eabe4d98ba09fd978f8d152a9865347 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizve...@gmail.com>
Date: Sun, 2 Feb 2025 23:47:15 -0300
Subject: [PATCH] [clang] print correct context for diagnostics suppressed by
 deduction

This patch makes it so the correct instantiation context is printed
for diagnostics suppessed by template argument deduction.

The context is saved along with the suppressed diagnostic, and
when the declaration they were attached to becomes used, we print
the correct context, instead of whatever context was at this point.
---
 clang/docs/ReleaseNotes.rst                   |   2 +
 clang/include/clang/Sema/Sema.h               |  26 +-
 clang/lib/Sema/Sema.cpp                       |  13 +-
 clang/lib/Sema/SemaAttr.cpp                   |   6 +-
 clang/lib/Sema/SemaExpr.cpp                   |   7 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp    | 271 +++++++++---------
 clang/test/CXX/drs/cwg0xx.cpp                 |   5 +
 clang/test/CXX/drs/cwg4xx.cpp                 |   3 +-
 .../CXX/temp/temp.arg/temp.arg.type/p2.cpp    |   9 +-
 clang/test/SemaCXX/anonymous-struct.cpp       |   5 +-
 clang/test/SemaCXX/bool-increment-SFINAE.cpp  |   4 +-
 clang/test/SemaCXX/cxx98-compat-flags.cpp     |   2 +
 clang/test/SemaCXX/cxx98-compat.cpp           |   2 +
 clang/test/SemaCXX/deprecated.cpp             |   4 +-
 clang/test/SemaCXX/lambda-expressions.cpp     |   2 +
 clang/test/SemaCXX/undefined-internal.cpp     |   6 +-
 clang/test/SemaTemplate/recovery-crash.cpp    |   1 +
 clang/test/SemaTemplate/temp_arg_nontype.cpp  |   1 +
 18 files changed, 208 insertions(+), 161 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 21c1ff25d2862ba..dfce173d414ebb2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -146,6 +146,8 @@ Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Clang is now better at keeping track of friend function template instance 
contexts. (#GH55509)
+- Clang now prints the correct instantiation context for diagnostics suppressed
+  by template argument deduction.
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1870d1271c556cb..c0e01c817cf100b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1909,7 +1909,19 @@ class Sema final : public SemaBase {
   /// '\#pragma clang attribute push' directives to the given declaration.
   void AddPragmaAttributes(Scope *S, Decl *D);
 
-  void PrintPragmaAttributeInstantiationPoint();
+  using DiagFuncRef =
+      llvm::function_ref<void(SourceLocation, PartialDiagnostic)>;
+  auto getDefaultDiagFunc() {
+    return [this](SourceLocation Loc, PartialDiagnostic PD) {
+      DiagnosticBuilder Builder(Diags.Report(Loc, PD.getDiagID()));
+      PD.Emit(Builder);
+    };
+  }
+
+  void PrintPragmaAttributeInstantiationPoint(DiagFuncRef DiagFunc);
+  void PrintPragmaAttributeInstantiationPoint() {
+    PrintPragmaAttributeInstantiationPoint(getDefaultDiagFunc());
+  }
 
   void DiagnoseUnterminatedPragmaAttribute();
 
@@ -13263,18 +13275,22 @@ class Sema final : public SemaBase {
   void pushCodeSynthesisContext(CodeSynthesisContext Ctx);
   void popCodeSynthesisContext();
 
-  void PrintContextStack() {
+  void PrintContextStack(DiagFuncRef DiagFunc) {
     if (!CodeSynthesisContexts.empty() &&
         CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) {
-      PrintInstantiationStack();
+      PrintInstantiationStack(DiagFunc);
       LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size();
     }
     if (PragmaAttributeCurrentTargetDecl)
-      PrintPragmaAttributeInstantiationPoint();
+      PrintPragmaAttributeInstantiationPoint(DiagFunc);
   }
+  void PrintContextStack() { PrintContextStack(getDefaultDiagFunc()); }
   /// Prints the current instantiation stack through a series of
   /// notes.
-  void PrintInstantiationStack();
+  void PrintInstantiationStack(DiagFuncRef DiagFunc);
+  void PrintInstantiationStack() {
+    PrintInstantiationStack(getDefaultDiagFunc());
+  }
 
   /// Determines whether we are currently in a context where
   /// template argument substitution failures are not considered
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 15c18f9a4525b22..f3f7111a3a200f3 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1654,11 +1654,20 @@ void Sema::EmitDiagnostic(unsigned DiagID, const 
DiagnosticBuilder &DB) {
     }
 
     case DiagnosticIDs::SFINAE_Suppress:
+      if (DiagnosticsEngine::Level Level = getDiagnostics().getDiagnosticLevel(
+              DiagInfo.getID(), DiagInfo.getLocation());
+          Level == DiagnosticsEngine::Ignored)
+        return;
       // Make a copy of this suppressed diagnostic and store it with the
       // template-deduction information;
       if (*Info) {
-        (*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(),
-                       PartialDiagnostic(DiagInfo, 
Context.getDiagAllocator()));
+        (*Info)->addSuppressedDiagnostic(
+            DiagInfo.getLocation(),
+            PartialDiagnostic(DiagInfo, Context.getDiagAllocator()));
+        if (!Diags.getDiagnosticIDs()->isNote(DiagID))
+          PrintContextStack([Info](SourceLocation Loc, PartialDiagnostic PD) {
+            (*Info)->addSuppressedDiagnostic(Loc, std::move(PD));
+          });
       }
 
       // Suppress this diagnostic.
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index defdda17c32dedb..e9a6c6b52b9bae8 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1216,10 +1216,10 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
   }
 }
 
-void Sema::PrintPragmaAttributeInstantiationPoint() {
+void Sema::PrintPragmaAttributeInstantiationPoint(DiagFuncRef DiagFunc) {
   assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
-  Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
-               diag::note_pragma_attribute_applied_decl_here);
+  DiagFunc(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
+           PDiag(diag::note_pragma_attribute_applied_decl_here));
 }
 
 void Sema::DiagnosePrecisionLossInComplexDivision() {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3cd4010740d1944..46e2ebfcf54e605 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -225,9 +225,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, 
ArrayRef<SourceLocation> Locs,
     // emit them now.
     auto Pos = SuppressedDiagnostics.find(D->getCanonicalDecl());
     if (Pos != SuppressedDiagnostics.end()) {
-      for (const PartialDiagnosticAt &Suppressed : Pos->second)
-        Diag(Suppressed.first, Suppressed.second);
-
+      for (const auto &[DiagLoc, PD] : Pos->second) {
+        DiagnosticBuilder Builder(Diags.Report(DiagLoc, PD.getDiagID()));
+        PD.Emit(Builder);
+      }
       // Clear out the list of suppressed diagnostics, so that we don't emit
       // them again for this specialization. However, we don't obsolete this
       // entry from the table, because we want to avoid ever emitting these
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index d9a47ca3daa20c5..cccf2095816db14 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -903,7 +903,7 @@ bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
   return true;
 }
 
-void Sema::PrintInstantiationStack() {
+void Sema::PrintInstantiationStack(DiagFuncRef DiagFunc) {
   // Determine which template instantiations to skip, if any.
   unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart;
   unsigned Limit = Diags.getTemplateBacktraceLimit();
@@ -923,9 +923,9 @@ void Sema::PrintInstantiationStack() {
     if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
       if (InstantiationIdx == SkipStart) {
         // Note that we're skipping instantiations.
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_instantiation_contexts_suppressed)
-          << unsigned(CodeSynthesisContexts.size() - Limit);
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(diag::note_instantiation_contexts_suppressed)
+                     << unsigned(CodeSynthesisContexts.size() - Limit));
       }
       continue;
     }
@@ -937,37 +937,34 @@ void Sema::PrintInstantiationStack() {
         unsigned DiagID = diag::note_template_member_class_here;
         if (isa<ClassTemplateSpecializationDecl>(Record))
           DiagID = diag::note_template_class_instantiation_here;
-        Diags.Report(Active->PointOfInstantiation, DiagID)
-          << Record << Active->InstantiationRange;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(DiagID) << Record << Active->InstantiationRange);
       } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
         unsigned DiagID;
         if (Function->getPrimaryTemplate())
           DiagID = diag::note_function_template_spec_here;
         else
           DiagID = diag::note_template_member_function_here;
-        Diags.Report(Active->PointOfInstantiation, DiagID)
-          << Function
-          << Active->InstantiationRange;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(DiagID) << Function << Active->InstantiationRange);
       } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-        Diags.Report(Active->PointOfInstantiation,
-                     VD->isStaticDataMember()?
-                       diag::note_template_static_data_member_def_here
-                     : diag::note_template_variable_def_here)
-          << VD
-          << Active->InstantiationRange;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(VD->isStaticDataMember()
+                           ? diag::note_template_static_data_member_def_here
+                           : diag::note_template_variable_def_here)
+                     << VD << Active->InstantiationRange);
       } else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_template_enum_def_here)
-          << ED
-          << Active->InstantiationRange;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(diag::note_template_enum_def_here)
+                     << ED << Active->InstantiationRange);
       } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_template_nsdmi_here)
-            << FD << Active->InstantiationRange;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(diag::note_template_nsdmi_here)
+                     << FD << Active->InstantiationRange);
       } else if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(D)) {
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_template_class_instantiation_here)
-            << CTD << Active->InstantiationRange;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(diag::note_template_class_instantiation_here)
+                     << CTD << Active->InstantiationRange);
       }
       break;
     }
@@ -979,35 +976,35 @@ void Sema::PrintInstantiationStack() {
       Template->printName(OS, getPrintingPolicy());
       printTemplateArgumentList(OS, Active->template_arguments(),
                                 getPrintingPolicy());
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_default_arg_instantiation_here)
-        << OS.str()
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_default_arg_instantiation_here)
+                   << OS.str() << Active->InstantiationRange);
       break;
     }
 
     case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: {
       FunctionTemplateDecl *FnTmpl = 
cast<FunctionTemplateDecl>(Active->Entity);
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_explicit_template_arg_substitution_here)
-        << FnTmpl
-        << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
-                                           Active->TemplateArgs,
-                                           Active->NumTemplateArgs)
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_explicit_template_arg_substitution_here)
+                   << FnTmpl
+                   << getTemplateArgumentBindingsText(
+                          FnTmpl->getTemplateParameters(), 
Active->TemplateArgs,
+                          Active->NumTemplateArgs)
+                   << Active->InstantiationRange);
       break;
     }
 
     case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: {
       if (FunctionTemplateDecl *FnTmpl =
               dyn_cast<FunctionTemplateDecl>(Active->Entity)) {
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_function_template_deduction_instantiation_here)
-          << FnTmpl
-          << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
-                                             Active->TemplateArgs,
-                                             Active->NumTemplateArgs)
-          << Active->InstantiationRange;
+        DiagFunc(
+            Active->PointOfInstantiation,
+            PDiag(diag::note_function_template_deduction_instantiation_here)
+                << FnTmpl
+                << getTemplateArgumentBindingsText(
+                       FnTmpl->getTemplateParameters(), Active->TemplateArgs,
+                       Active->NumTemplateArgs)
+                << Active->InstantiationRange);
       } else {
         bool IsVar = isa<VarTemplateDecl>(Active->Entity) ||
                      isa<VarTemplateSpecializationDecl>(Active->Entity);
@@ -1026,12 +1023,13 @@ void Sema::PrintInstantiationStack() {
           llvm_unreachable("unexpected template kind");
         }
 
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_deduced_template_arg_substitution_here)
-          << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
-          << getTemplateArgumentBindingsText(Params, Active->TemplateArgs,
-                                             Active->NumTemplateArgs)
-          << Active->InstantiationRange;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(diag::note_deduced_template_arg_substitution_here)
+                     << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
+                     << getTemplateArgumentBindingsText(Params,
+                                                        Active->TemplateArgs,
+                                                        
Active->NumTemplateArgs)
+                     << Active->InstantiationRange);
       }
       break;
     }
@@ -1045,10 +1043,9 @@ void Sema::PrintInstantiationStack() {
       FD->printName(OS, getPrintingPolicy());
       printTemplateArgumentList(OS, Active->template_arguments(),
                                 getPrintingPolicy());
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_default_function_arg_instantiation_here)
-        << OS.str()
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_default_function_arg_instantiation_here)
+                   << OS.str() << Active->InstantiationRange);
       break;
     }
 
@@ -1065,14 +1062,13 @@ void Sema::PrintInstantiationStack() {
         TemplateParams =
           cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
                                                       
->getTemplateParameters();
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_prior_template_arg_substitution)
-        << isa<TemplateTemplateParmDecl>(Parm)
-        << Name
-        << getTemplateArgumentBindingsText(TemplateParams,
-                                           Active->TemplateArgs,
-                                           Active->NumTemplateArgs)
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_prior_template_arg_substitution)
+                   << isa<TemplateTemplateParmDecl>(Parm) << Name
+                   << getTemplateArgumentBindingsText(TemplateParams,
+                                                      Active->TemplateArgs,
+                                                      Active->NumTemplateArgs)
+                   << Active->InstantiationRange);
       break;
     }
 
@@ -1085,55 +1081,56 @@ void Sema::PrintInstantiationStack() {
           cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
                                                       
->getTemplateParameters();
 
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_template_default_arg_checking)
-        << getTemplateArgumentBindingsText(TemplateParams,
-                                           Active->TemplateArgs,
-                                           Active->NumTemplateArgs)
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_template_default_arg_checking)
+                   << getTemplateArgumentBindingsText(TemplateParams,
+                                                      Active->TemplateArgs,
+                                                      Active->NumTemplateArgs)
+                   << Active->InstantiationRange);
       break;
     }
 
     case CodeSynthesisContext::ExceptionSpecEvaluation:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_evaluating_exception_spec_here)
-          << cast<FunctionDecl>(Active->Entity);
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_evaluating_exception_spec_here)
+                   << cast<FunctionDecl>(Active->Entity));
       break;
 
     case CodeSynthesisContext::ExceptionSpecInstantiation:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_template_exception_spec_instantiation_here)
-        << cast<FunctionDecl>(Active->Entity)
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_template_exception_spec_instantiation_here)
+                   << cast<FunctionDecl>(Active->Entity)
+                   << Active->InstantiationRange);
       break;
 
     case CodeSynthesisContext::RequirementInstantiation:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_template_requirement_instantiation_here)
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_template_requirement_instantiation_here)
+                   << Active->InstantiationRange);
       break;
     case CodeSynthesisContext::RequirementParameterInstantiation:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_template_requirement_params_instantiation_here)
-          << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_template_requirement_params_instantiation_here)
+                   << Active->InstantiationRange);
       break;
 
     case CodeSynthesisContext::NestedRequirementConstraintsCheck:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_nested_requirement_here)
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_nested_requirement_here)
+                   << Active->InstantiationRange);
       break;
 
     case CodeSynthesisContext::DeclaringSpecialMember:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_in_declaration_of_implicit_special_member)
-          << cast<CXXRecordDecl>(Active->Entity)
-          << llvm::to_underlying(Active->SpecialMember);
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_in_declaration_of_implicit_special_member)
+                   << cast<CXXRecordDecl>(Active->Entity)
+                   << llvm::to_underlying(Active->SpecialMember));
       break;
 
     case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
-      Diags.Report(Active->Entity->getLocation(),
-                   diag::note_in_declaration_of_implicit_equality_comparison);
+      DiagFunc(
+          Active->Entity->getLocation(),
+          PDiag(diag::note_in_declaration_of_implicit_equality_comparison));
       break;
 
     case CodeSynthesisContext::DefiningSynthesizedFunction: {
@@ -1144,60 +1141,62 @@ void Sema::PrintInstantiationStack() {
           FD ? getDefaultedFunctionKind(FD) : DefaultedFunctionKind();
       if (DFK.isSpecialMember()) {
         auto *MD = cast<CXXMethodDecl>(FD);
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_member_synthesized_at)
-            << MD->isExplicitlyDefaulted()
-            << llvm::to_underlying(DFK.asSpecialMember())
-            << Context.getTagDeclType(MD->getParent());
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(diag::note_member_synthesized_at)
+                     << MD->isExplicitlyDefaulted()
+                     << llvm::to_underlying(DFK.asSpecialMember())
+                     << Context.getTagDeclType(MD->getParent()));
       } else if (DFK.isComparison()) {
         QualType RecordType = FD->getParamDecl(0)
                                   ->getType()
                                   .getNonReferenceType()
                                   .getUnqualifiedType();
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_comparison_synthesized_at)
-            << (int)DFK.asComparison() << RecordType;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(diag::note_comparison_synthesized_at)
+                     << (int)DFK.asComparison() << RecordType);
       }
       break;
     }
 
     case CodeSynthesisContext::RewritingOperatorAsSpaceship:
-      Diags.Report(Active->Entity->getLocation(),
-                   diag::note_rewriting_operator_as_spaceship);
+      DiagFunc(Active->Entity->getLocation(),
+               PDiag(diag::note_rewriting_operator_as_spaceship));
       break;
 
     case CodeSynthesisContext::InitializingStructuredBinding:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_in_binding_decl_init)
-          << cast<BindingDecl>(Active->Entity);
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_in_binding_decl_init)
+                   << cast<BindingDecl>(Active->Entity));
       break;
 
     case CodeSynthesisContext::MarkingClassDllexported:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_due_to_dllexported_class)
-          << cast<CXXRecordDecl>(Active->Entity) << !getLangOpts().CPlusPlus11;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_due_to_dllexported_class)
+                   << cast<CXXRecordDecl>(Active->Entity)
+                   << !getLangOpts().CPlusPlus11);
       break;
 
     case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_building_builtin_dump_struct_call)
-          << convertCallArgsToString(
-                 *this, llvm::ArrayRef(Active->CallArgs, Active->NumCallArgs));
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_building_builtin_dump_struct_call)
+                   << convertCallArgsToString(
+                          *this, llvm::ArrayRef(Active->CallArgs,
+                                                Active->NumCallArgs)));
       break;
 
     case CodeSynthesisContext::Memoization:
       break;
 
     case CodeSynthesisContext::LambdaExpressionSubstitution:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_lambda_substitution_here);
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_lambda_substitution_here));
       break;
     case CodeSynthesisContext::ConstraintsCheck: {
       unsigned DiagID = 0;
       if (!Active->Entity) {
-        Diags.Report(Active->PointOfInstantiation,
-                     diag::note_nested_requirement_here)
-          << Active->InstantiationRange;
+        DiagFunc(Active->PointOfInstantiation,
+                 PDiag(diag::note_nested_requirement_here)
+                     << Active->InstantiationRange);
         break;
       }
       if (isa<ConceptDecl>(Active->Entity))
@@ -1219,42 +1218,44 @@ void Sema::PrintInstantiationStack() {
         printTemplateArgumentList(OS, Active->template_arguments(),
                                   getPrintingPolicy());
       }
-      Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str()
-        << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(DiagID) << OS.str() << Active->InstantiationRange);
       break;
     }
     case CodeSynthesisContext::ConstraintSubstitution:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_constraint_substitution_here)
-          << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_constraint_substitution_here)
+                   << Active->InstantiationRange);
       break;
     case CodeSynthesisContext::ConstraintNormalization:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_constraint_normalization_here)
-          << cast<NamedDecl>(Active->Entity) << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_constraint_normalization_here)
+                   << cast<NamedDecl>(Active->Entity)
+                   << Active->InstantiationRange);
       break;
     case CodeSynthesisContext::ParameterMappingSubstitution:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_parameter_mapping_substitution_here)
-          << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_parameter_mapping_substitution_here)
+                   << Active->InstantiationRange);
       break;
     case CodeSynthesisContext::BuildingDeductionGuides:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_building_deduction_guide_here);
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_building_deduction_guide_here));
       break;
     case CodeSynthesisContext::TypeAliasTemplateInstantiation:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_template_type_alias_instantiation_here)
-          << cast<TypeAliasTemplateDecl>(Active->Entity)
-          << Active->InstantiationRange;
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_template_type_alias_instantiation_here)
+                   << cast<TypeAliasTemplateDecl>(Active->Entity)
+                   << Active->InstantiationRange);
       break;
     case CodeSynthesisContext::PartialOrderingTTP:
-      Diags.Report(Active->PointOfInstantiation,
-                   diag::note_template_arg_template_params_mismatch);
+      DiagFunc(Active->PointOfInstantiation,
+               PDiag(diag::note_template_arg_template_params_mismatch));
       if (SourceLocation ParamLoc = Active->Entity->getLocation();
           ParamLoc.isValid())
-        Diags.Report(ParamLoc, diag::note_template_prev_declaration)
-            << /*isTemplateTemplateParam=*/true << Active->InstantiationRange;
+        DiagFunc(ParamLoc, PDiag(diag::note_template_prev_declaration)
+                               << /*isTemplateTemplateParam=*/true
+                               << Active->InstantiationRange);
       break;
     }
   }
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 44a0eb520af2216..282e71bbf3bdaab 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -1041,12 +1041,15 @@ namespace cwg62 { // cwg62: 2.9
   NoNameForLinkagePtr p1 = get<NoNameForLinkagePtr>();
   // cxx98-error@-1 {{template argument uses unnamed type}}
   //   cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was 
declared here}}
+  //   cxx98-note@-3 {{while substituting explicitly-specified template 
arguments}}
   NoNameForLinkagePtr p2 = get<const NoNameForLinkagePtr>();
   // cxx98-error@-1 {{template argument uses unnamed type}}
   //   cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was 
declared here}}
+  //   cxx98-note@-3 {{while substituting explicitly-specified template 
arguments}}
   int n1 = take(noNameForLinkagePtr);
   // cxx98-error@-1 {{template argument uses unnamed type}}
   //   cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was 
declared here}}
+  //   cxx98-note@-3 {{while substituting deduced template arguments}}
 
   X<Danger> x4;
 
@@ -1058,8 +1061,10 @@ namespace cwg62 { // cwg62: 2.9
     // cxx98-error@-1 {{template argument uses local type }}
     get<NoLinkage>();
     // cxx98-error@-1 {{template argument uses local type }}
+    //   cxx98-note@-2 {{while substituting explicitly-specified template 
arguments}}
     get<const NoLinkage>();
     // cxx98-error@-1 {{template argument uses local type }}
+    //   cxx98-note@-2 {{while substituting explicitly-specified template 
arguments}}
     X<void (*)(NoLinkage A::*)> c;
     // cxx98-error@-1 {{template argument uses local type }}
     X<int NoLinkage::*> d;
diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp
index bcaf7db04ad3b5d..0debc104ac45b82 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -20,7 +20,7 @@ namespace cwg400 { // cwg400: 2.7
   struct A { int a; struct a {}; }; // #cwg400-A
   struct B { int a; struct a {}; }; // #cwg400-B
   struct C : A, B { using A::a; struct a b; };
-  struct D : A, B { 
+  struct D : A, B {
     using A::a;
     // FIXME: we should issue a single diagnostic
     using B::a; // #cwg400-using-B-a
@@ -1386,6 +1386,7 @@ namespace cwg488 { // cwg488: 2.9 c++11
     enum E { e };
     f(e);
     // cxx98-error@-1 {{template argument uses local type 'E'}}
+    //   cxx98-note@-2 {{while substituting deduced template arguments}}
   }
 } // namespace cwg488
 
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 1e314da3139903e..650f8585b115a87 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
@@ -15,14 +15,13 @@ B<function> b; // expected-note{{instantiation of}}
 
 template <typename T> int f0(void *, const T&); // expected-note{{candidate 
template ignored: substitution failure}}
 enum {e};
-#if __cplusplus <= 199711L
-// expected-note@-2 {{unnamed type used in template argument was declared 
here}}
-#endif
+// expected-note@-1 {{unnamed type used in template argument was declared 
here}}
 
 void test_f0(int n) { // #here
   int i = f0(0, e);
 #if __cplusplus <= 199711L
   // expected-warning@-2 {{template argument uses unnamed type}}
+  // expected-note@-3 {{while substituting deduced template arguments}}
 #endif
 
   int vla[n]; // expected-warning {{variable length arrays in C++ are a Clang 
extension}}
@@ -59,21 +58,25 @@ namespace N0 {
     f0(
 #if __cplusplus <= 199711L
     // expected-warning@-2 {{template argument uses unnamed type}}
+    // expected-note@-3 {{while substituting deduced template arguments}}
 #endif
 
        &f1<__typeof__(e1)>);
 #if __cplusplus <= 199711L
  // expected-warning@-2 {{template argument uses unnamed type}}
+ // expected-note@-3 {{while substituting explicitly-specified template 
arguments}}
 #endif
 
     int (*fp1)(int, __typeof__(e2)) = f1;
 #if __cplusplus <= 199711L
     // expected-warning@-2 {{template argument uses unnamed type}}
+    // expected-note@-3 {{while substituting deduced template arguments}}
 #endif
 
     f1(e2);
 #if __cplusplus <= 199711L
     // expected-warning@-2 {{template argument uses unnamed type}}
+    // expected-note@-3 {{while substituting deduced template arguments}}
 #endif
 
     f1(e2);
diff --git a/clang/test/SemaCXX/anonymous-struct.cpp 
b/clang/test/SemaCXX/anonymous-struct.cpp
index e1db98d2b2f5079..75309821998eba1 100644
--- a/clang/test/SemaCXX/anonymous-struct.cpp
+++ b/clang/test/SemaCXX/anonymous-struct.cpp
@@ -29,14 +29,13 @@ struct E {
 
 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}}
-#if __cplusplus <= 199711L
-// expected-note@-2 {{declared here}}
-#endif
+// expected-note@-1 {{unnamed type used in template argument was declared 
here}}
 
   void test() { // expected-note {{type is not C-compatible due to this member 
declaration}}
     foo(this);
 #if __cplusplus <= 199711L
     // expected-warning@-2 {{template argument uses unnamed type}}
+    // expected-note@-3 {{while substituting deduced template arguments}}
 #endif
   }
 } A; // expected-note {{type is given name 'A' for linkage purposes by this 
typedef declaration}}
diff --git a/clang/test/SemaCXX/bool-increment-SFINAE.cpp 
b/clang/test/SemaCXX/bool-increment-SFINAE.cpp
index d3889293fc0b642..3a465fa5a3d5a22 100644
--- a/clang/test/SemaCXX/bool-increment-SFINAE.cpp
+++ b/clang/test/SemaCXX/bool-increment-SFINAE.cpp
@@ -7,7 +7,7 @@
 template<class T> auto f(T t) -> decltype(++t); // precxx17-warning 
{{incrementing expression of type bool is deprecated}}
 
 auto f(...) -> void;
-void g() { f(true); }
+void g() { f(true); } // precxx17-note {{while substituting deduced template 
arguments}}
 
 #ifdef FAILED_CXX17
 
@@ -30,7 +30,7 @@ void f() {
 
 int main() {
   f<bool>(); // cxx20-note {{in instantiation of function template 
specialization 'f<bool>' requested here}}
-  static_assert(!can_increment<bool>); 
+  static_assert(!can_increment<bool>);
 
   return 0;
 }
diff --git a/clang/test/SemaCXX/cxx98-compat-flags.cpp 
b/clang/test/SemaCXX/cxx98-compat-flags.cpp
index 1fdb50c7fb2878f..6ffb3a5884d17cc 100644
--- a/clang/test/SemaCXX/cxx98-compat-flags.cpp
+++ b/clang/test/SemaCXX/cxx98-compat-flags.cpp
@@ -5,9 +5,11 @@ 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}}
+                   // expected-note@-1 {{while substituting deduced template 
arguments}}
 }
 struct {} obj_of_unnamed_type; // expected-note {{here}}
 int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning 
{{unnamed type as template argument is incompatible with C++98}}
+                                                          // expected-note@-1 
{{while substituting deduced template arguments}}
 
 namespace CopyCtorIssues {
   struct Private {
diff --git a/clang/test/SemaCXX/cxx98-compat.cpp 
b/clang/test/SemaCXX/cxx98-compat.cpp
index 28547d42c64902d..d31d95a9995f19f 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -177,9 +177,11 @@ 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}}
+                   // expected-note@-1 {{while substituting deduced template 
arguments}}
 }
 struct {} obj_of_unnamed_type; // expected-note {{here}}
 int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning 
{{unnamed type as template argument is incompatible with C++98}}
+                                                          // expected-note@-1 
{{while substituting deduced template arguments}}
 
 // FIXME: We do not implement C++98 compatibility warnings for the C++17
 // template argument evaluation rules.
diff --git a/clang/test/SemaCXX/deprecated.cpp 
b/clang/test/SemaCXX/deprecated.cpp
index 4282239af81b4c9..a24b40d8e622a8b 100644
--- a/clang/test/SemaCXX/deprecated.cpp
+++ b/clang/test/SemaCXX/deprecated.cpp
@@ -216,7 +216,7 @@ namespace DeprecatedVolatile {
 #endif
 
   template<typename T> T f(T v); // cxx20-warning 2{{deprecated}}
-  int use_f = f<volatile int>(0); // FIXME: Missing "in instantiation of" note.
+  int use_f = f<volatile int>(0); // cxx20-note {{while substituting deduced 
template arguments}}
 
   // OK, only the built-in operators are deprecated.
   struct UDT {
@@ -247,7 +247,7 @@ namespace ArithConv {
 namespace ArrayComp {
   int arr1[3], arr2[4];
   bool b1 = arr1 == arr2; // not-cxx20-warning {{comparison between two arrays 
compare their addresses}} cxx20-warning {{comparison between two arrays is 
deprecated}}
-                          // expected-warning@-1 {{array comparison always 
evaluates to false}} 
+                          // expected-warning@-1 {{array comparison always 
evaluates to false}}
   bool b2 = arr1 < arr2; // not-cxx20-warning {{comparison between two arrays 
compare their addresses}} cxx20-warning {{comparison between two arrays is 
deprecated}}
                          // expected-warning@-1 {{array comparison always 
evaluates to a constant}}
   __attribute__((weak)) int arr3[3];
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp 
b/clang/test/SemaCXX/lambda-expressions.cpp
index f3deb6ee3f4244f..2d2dde82a28e6b6 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -452,6 +452,7 @@ void g(F f) {
 void f() {
   g([] {}); // cxx03-warning {{template argument uses local type}}
   // expected-note-re@-1 {{in instantiation of function template 
specialization 'PR20731::g<(lambda at {{.*}}>' requested here}}
+  // cxx03-note@-2 {{while substituting deduced template arguments}}
 }
 
 template <class _Rp> struct function {
@@ -503,6 +504,7 @@ namespace PR21857 {
   };
   template<typename Fn> fun<Fn> wrap(Fn fn); // cxx03-warning {{template 
argument uses unnamed type}}
   auto x = wrap([](){}); // cxx03-warning {{template argument uses unnamed 
type}} cxx03-note 2 {{unnamed type used in template argument was declared here}}
+                         // cxx03-note@-1 {{while substituting deduced 
template arguments into function template}}
 }
 
 namespace PR13987 {
diff --git a/clang/test/SemaCXX/undefined-internal.cpp 
b/clang/test/SemaCXX/undefined-internal.cpp
index 054e71b92f93d2f..9745f097c76b78c 100644
--- a/clang/test/SemaCXX/undefined-internal.cpp
+++ b/clang/test/SemaCXX/undefined-internal.cpp
@@ -133,7 +133,7 @@ namespace PR9323 {
   }
   void f(const Uncopyable&) {}
   void test() {
-    f(Uncopyable()); 
+    f(Uncopyable());
 #if __cplusplus <= 199711L // C++03 or earlier modes
     // expected-warning@-2 {{C++98 requires an accessible copy constructor}}
 #else
@@ -209,7 +209,9 @@ namespace OverloadUse {
     t<f>(&n, &n); // expected-note {{used here}}
 #if __cplusplus < 201103L
     // expected-warning@-3 {{non-type template argument referring to function 
'f' with internal linkage}}
-    // expected-warning@-3 {{non-type template argument referring to function 
'f' with internal linkage}}
+    // expected-note@-4 {{while substituting explicitly-specified template 
arguments}}
+    // expected-warning@-4 {{non-type template argument referring to function 
'f' with internal linkage}}
+    // expected-note@-5 {{while substituting explicitly-specified template 
arguments}}
 #endif
   }
 }
diff --git a/clang/test/SemaTemplate/recovery-crash.cpp 
b/clang/test/SemaTemplate/recovery-crash.cpp
index 88e989aeb406493..ac8053da101ab34 100644
--- a/clang/test/SemaTemplate/recovery-crash.cpp
+++ b/clang/test/SemaTemplate/recovery-crash.cpp
@@ -32,6 +32,7 @@ namespace PR16225 {
     f<LocalStruct>();
 #if __cplusplus <= 199711L
     // expected-warning@-2 {{template argument uses local type 'LocalStruct'}}
+    // expected-note@-3 {{while substituting explicitly-specified template 
arguments}}
 #endif
     struct LocalStruct2 : UnknownBase<C> { };  // expected-error {{no template 
named 'UnknownBase'}}
   }
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp 
b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 8b270b22a12b461..2a1c059df002ea3 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -255,6 +255,7 @@ namespace test8 {
 namespace PR8372 {
   template <int I> void foo() { } // expected-note{{template parameter is 
declared here}}
   void bar() { foo <0x80000000> (); } // expected-warning{{non-type template 
argument value '2147483648' truncated to '-2147483648' for template parameter 
of type 'int'}}
+  // expected-note@-1 {{while substituting explicitly-specified template 
arguments}}
 }
 
 namespace PR9227 {

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to