https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/132129

>From ce40f50211739b0c3f18f96767b0ca1fa144c469 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Thu, 20 Mar 2025 01:43:39 +0100
Subject: [PATCH 1/7] [Clang] [NFC] Introduce helpers for defining compatibilty
 warnings

---
 clang/include/clang/Basic/Diagnostic.td | 43 +++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/clang/include/clang/Basic/Diagnostic.td 
b/clang/include/clang/Basic/Diagnostic.td
index 0b8b3af939ba0..85b7276695613 100644
--- a/clang/include/clang/Basic/Diagnostic.td
+++ b/clang/include/clang/Basic/Diagnostic.td
@@ -155,6 +155,49 @@ class DefaultWarnNoWerror {
 }
 class DefaultRemark { Severity DefaultSeverity = SEV_Remark; }
 
+// C++ compatibility warnings
+multiclass CXXCompatWarn<
+    string message,
+    bit default_ignore,
+    int std_ver,
+    string std_ver_override = ""#std_ver> {
+    // 'X is a C++YZ extension'.
+    def compat_pre_cxx#std_ver#_#NAME :
+        Diagnostic<!strconcat(message, " a C++", std_ver_override,  " 
extension"),
+                   CLASS_EXTENSION,
+                   !if(default_ignore, SEV_Ignored, SEV_Warning)>,
+        InGroup<!cast<DiagGroup>("CXX"#std_ver)>;
+
+    // 'X is incompatible with C++98' (if std_ver == 11).
+    // 'X is incompatible with C++ standards before C++YZ' (otherwise).
+    def compat_cxx#std_ver#_#NAME :
+        Warning<!if(!eq(std_ver, 11),
+                    !strconcat(message, " incompatible with C++98"),
+                    !strconcat(message, " incompatible with C++ standards 
before C++", std_ver_override))>,
+        InGroup<!cast<DiagGroup>(!if(!eq(std_ver, 11),
+                                     "CXX98Compat",
+                                     "CXXPre"#std_ver#"Compat"))>,
+        DefaultIgnore;
+}
+
+multiclass CXX11CompatWarn<string message, bit default_ignore = false>
+    : CXXCompatWarn<message, default_ignore, 11>;
+
+multiclass CXX14CompatWarn<string message, bit default_ignore = false>
+    : CXXCompatWarn<message, default_ignore, 14>;
+
+multiclass CXX17CompatWarn<string message, bit default_ignore = false>
+    : CXXCompatWarn<message, default_ignore, 17>;
+
+multiclass CXX20CompatWarn<string message, bit default_ignore = false>
+    : CXXCompatWarn<message, default_ignore, 20>;
+
+multiclass CXX23CompatWarn<string message, bit default_ignore = false>
+    : CXXCompatWarn<message, default_ignore, 23>;
+
+multiclass CXX26CompatWarn<string message, bit default_ignore = false>
+    : CXXCompatWarn<message, default_ignore, 26, "2c">;
+
 // Definitions for Diagnostics.
 include "DiagnosticASTKinds.td"
 include "DiagnosticCommentKinds.td"

>From ac894bf305da482781ff7ada87704a4f2eb3b5a7 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Thu, 20 Mar 2025 01:47:13 +0100
Subject: [PATCH 2/7] Refactor compatibility warnings in Sema

---
 .../clang/Basic/DiagnosticSemaKinds.td        | 202 +++++-------------
 clang/lib/Sema/SemaDecl.cpp                   |  12 +-
 clang/lib/Sema/SemaDeclCXX.cpp                |  65 +++---
 clang/lib/Sema/SemaExpr.cpp                   |   4 +-
 clang/lib/Sema/SemaTemplate.cpp               |  25 +--
 clang/test/AST/ByteCode/if.cpp                |   2 +-
 clang/test/CXX/drs/cwg13xx.cpp                |  12 +-
 clang/test/CXX/drs/cwg1xx.cpp                 |   2 +-
 clang/test/CXX/drs/cwg3xx.cpp                 |   4 +-
 .../CXX/temp/temp.arg/temp.arg.nontype/p5.cpp |   2 +-
 clang/test/Misc/warning-flags.c               |   3 +-
 clang/test/Parser/cxx1z-decomposition.cpp     |  12 +-
 clang/test/Parser/decomposed-condition.cpp    |  24 +--
 clang/test/SemaCXX/cxx98-compat.cpp           |   6 +-
 clang/test/SemaObjCXX/message.mm              |   6 +-
 clang/test/SemaTemplate/temp_arg_nontype.cpp  |   2 +-
 .../SemaTemplate/typename-specifier-4.cpp     |   2 +-
 .../test/SemaTemplate/typename-specifier.cpp  |  12 +-
 18 files changed, 154 insertions(+), 243 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1536a3b8c920a..4ef1ab0ca4470 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12,6 +12,61 @@
 
 let Component = "Sema" in {
 let CategoryName = "Semantic Issue" in {
+// C++11 compatibility with C++98.
+defm nonclass_type_friend : CXX11CompatWarn<"non-class friend type %0 is">;
+defm static_data_member_in_union : CXX11CompatWarn<"static data member %0 in 
union is">;
+defm templ_default_in_function_templ : CXX11CompatWarn<
+  "default template arguments for a function template are">;
+defm template_arg_extra_parens : CXX11CompatWarn<
+  "parentheses around address non-type template argument are">;
+defm typename_outside_of_template : CXX11CompatWarn<"'typename' outside of a 
template is">;
+
+// C++14 compatibility with C++11 and earlier.
+defm constexpr_type_definition : CXX14CompatWarn<
+  "type definition in a constexpr %select{function|constructor}0 is">;
+defm constexpr_local_var : CXX14CompatWarn<
+  "variable declaration in a constexpr %select{function|constructor}0 is">;
+defm constexpr_body_multiple_return : CXX14CompatWarn<
+  "multiple return statements in constexpr function is">;
+defm variable_template : CXX14CompatWarn<"variable templates are">;
+
+// C++17 compatibility with C++14 and earlier.
+defm decomp_decl : CXX17CompatWarn<"decomposition declarations are">;
+defm inline_variable : CXX17CompatWarn<"inline variables are">;
+
+// C++20 compatibility with C++17 and earlier.
+defm decomp_decl_spec : CXX20CompatWarn<
+  "decomposition declaration declared "
+  "%plural{1:'%1'|:with '%1' specifiers}0 is">;
+defm constexpr_local_var_no_init : CXX20CompatWarn<
+  "uninitialized variable in a constexpr %select{function|constructor}0 is">;
+defm constexpr_function_try_block : CXX20CompatWarn<
+  "function try block in constexpr %select{function|constructor}0 is">;
+defm constexpr_union_ctor_no_init : CXX20CompatWarn<
+  "constexpr union constructor that does not initialize any member is">;
+defm constexpr_ctor_missing_init : CXX20CompatWarn<
+  "constexpr constructor that does not initialize all members is">;
+defm adl_only_template_id : CXX20CompatWarn<
+  "use of function template name with no prior declaration in function call "
+  "with explicit template arguments is">;
+
+// C++23 compatibility with C++20 and earlier.
+defm constexpr_static_var : CXX23CompatWarn<
+  "definition of a %select{static|thread_local}1 variable "
+  "in a constexpr %select{function|constructor}0 "
+  "is">;
+
+// C++26 compatibility with C++23 and earlier.
+defm decomp_decl_cond : CXX26CompatWarn<"structured binding declaration in a 
condition is">;
+
+// Compatibility warnings duplicated across multiple language versions.
+foreach std = [14, 20, 23] in {
+  defm constexpr_body_invalid_stmt : CXXCompatWarn<
+    "use of this statement in a constexpr %select{function|constructor}0 is",
+    /*default_ignore=*/false,
+    std>;
+}
+
 def note_previous_decl : Note<"%0 declared here">;
 def note_entity_declared_at : Note<"%0 declared here">;
 def note_callee_decl : Note<"%0 declared here">;
@@ -523,30 +578,9 @@ def warn_modifying_shadowing_decl :
 // C++ decomposition declarations
 def err_decomp_decl_context : Error<
   "decomposition declaration not permitted in this context">;
-def warn_cxx14_compat_decomp_decl : Warning<
-  "decomposition declarations are incompatible with "
-  "C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>;
-def ext_decomp_decl : ExtWarn<
-  "decomposition declarations are a C++17 extension">, InGroup<CXX17>;
-def ext_decomp_decl_cond : ExtWarn<
-  "structured binding declaration in a condition is a C++2c extenstion">,
-  InGroup<CXX26>;
-def warn_cxx26_decomp_decl_cond : Warning<
-  "structured binding declaration in a condition is incompatible with "
-  "C++ standards before C++2c">,
-  InGroup<CXXPre26Compat>, DefaultIgnore;
 def err_decomp_decl_spec : Error<
   "decomposition declaration cannot be declared "
   "%plural{1:'%1'|:with '%1' specifiers}0">;
-def ext_decomp_decl_spec : ExtWarn<
-  "decomposition declaration declared "
-  "%plural{1:'%1'|:with '%1' specifiers}0 is a C++20 extension">,
-  InGroup<CXX20>;
-def warn_cxx17_compat_decomp_decl_spec : Warning<
-  "decomposition declaration declared "
-  "%plural{1:'%1'|:with '%1' specifiers}0 "
-  "is incompatible with C++ standards before C++20">,
-  InGroup<CXXPre20Compat>, DefaultIgnore;
 def err_decomp_decl_type : Error<
   "decomposition declaration cannot be declared with type %0; "
   "declared type must be 'auto' or reference to 'auto'">;
@@ -1695,12 +1729,6 @@ def warn_consteval_if_always_true : Warning<
   "consteval if is always true in an %select{unevaluated|immediate}0 context">,
   InGroup<DiagGroup<"redundant-consteval-if">>;
 
-def ext_inline_variable : ExtWarn<
-  "inline variables are a C++17 extension">, InGroup<CXX17>;
-def warn_cxx14_compat_inline_variable : Warning<
-  "inline variables are incompatible with C++ standards before C++17">,
-  DefaultIgnore, InGroup<CXXPre17Compat>;
-
 def warn_inline_namespace_reopened_noninline : Warning<
   "inline namespace reopened as a non-inline namespace">,
   InGroup<InlineNamespaceReopenedNoninline>;
@@ -1716,11 +1744,6 @@ def ext_enum_friend : ExtWarn<
   InGroup<DiagGroup<"friend-enum">>;
 def note_enum_friend : Note<
   "remove 'enum%select{| struct| class}0' to befriend an enum">;
-def ext_nonclass_type_friend : ExtWarn<
-  "non-class friend type %0 is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_nonclass_type_friend : Warning<
-  "non-class friend type %0 is incompatible with C++98">,
-  InGroup<CXX98Compat>, DefaultIgnore;
 def err_friend_is_member : Error<
   "friends cannot be members of the declaring class">;
 def warn_cxx98_compat_friend_is_member : Warning<
@@ -2152,11 +2175,6 @@ def select_tag_type_kind : TextSubstitution<
 def err_static_data_member_not_allowed_in_anon_struct : Error<
   "static data member %0 not allowed in anonymous "
   "%sub{select_tag_type_kind}1">;
-def ext_static_data_member_in_union : ExtWarn<
-  "static data member %0 in union is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_static_data_member_in_union : Warning<
-  "static data member %0 in union is incompatible with C++98">,
-  InGroup<CXX98Compat>, DefaultIgnore;
 def ext_union_member_of_reference_type : ExtWarn<
   "union member %0 has reference type %1, which is a Microsoft extension">,
   InGroup<MicrosoftUnionMemberReference>;
@@ -2904,63 +2922,17 @@ def err_constexpr_non_literal_param : Error<
   "not a literal type">;
 def err_constexpr_body_invalid_stmt : Error<
   "statement not allowed in %select{constexpr|consteval}1 
%select{function|constructor}0">;
-def ext_constexpr_body_invalid_stmt : ExtWarn<
-  "use of this statement in a constexpr %select{function|constructor}0 "
-  "is a C++14 extension">, InGroup<CXX14>;
-def warn_cxx11_compat_constexpr_body_invalid_stmt : Warning<
-  "use of this statement in a constexpr %select{function|constructor}0 "
-  "is incompatible with C++ standards before C++14">,
-  InGroup<CXXPre14Compat>, DefaultIgnore;
-def ext_constexpr_body_invalid_stmt_cxx20 : ExtWarn<
-  "use of this statement in a constexpr %select{function|constructor}0 "
-  "is a C++20 extension">, InGroup<CXX20>;
-def warn_cxx17_compat_constexpr_body_invalid_stmt : Warning<
-  "use of this statement in a constexpr %select{function|constructor}0 "
-  "is incompatible with C++ standards before C++20">,
-  InGroup<CXXPre20Compat>, DefaultIgnore;
-def ext_constexpr_body_invalid_stmt_cxx23 : ExtWarn<
-  "use of this statement in a constexpr %select{function|constructor}0 "
-  "is a C++23 extension">, InGroup<CXX23>;
-def warn_cxx20_compat_constexpr_body_invalid_stmt : Warning<
-  "use of this statement in a constexpr %select{function|constructor}0 "
-  "is incompatible with C++ standards before C++23">,
-  InGroup<CXXPre23Compat>, DefaultIgnore;
-def ext_constexpr_type_definition : ExtWarn<
-  "type definition in a constexpr %select{function|constructor}0 "
-  "is a C++14 extension">, InGroup<CXX14>;
-def warn_cxx11_compat_constexpr_type_definition : Warning<
-  "type definition in a constexpr %select{function|constructor}0 "
-  "is incompatible with C++ standards before C++14">,
-  InGroup<CXXPre14Compat>, DefaultIgnore;
 def err_constexpr_vla : Error<
   "variably-modified type %0 cannot be used in a constexpr "
   "%select{function|constructor}1">;
-def ext_constexpr_local_var : ExtWarn<
-  "variable declaration in a constexpr %select{function|constructor}0 "
-  "is a C++14 extension">, InGroup<CXX14>;
-def warn_cxx11_compat_constexpr_local_var : Warning<
-  "variable declaration in a constexpr %select{function|constructor}0 "
-  "is incompatible with C++ standards before C++14">,
-  InGroup<CXXPre14Compat>, DefaultIgnore;
-def ext_constexpr_static_var : ExtWarn<
-  "definition of a %select{static|thread_local}1 variable "
-  "in a constexpr %select{function|constructor}0 "
-  "is a C++23 extension">, InGroup<CXX23>;
 def warn_cxx20_compat_constexpr_var : Warning<
-  "definition of a %select{static variable|thread_local variable|variable "
-  "of non-literal type}1 in a constexpr %select{function|constructor}0 "
+  "definition of a variable of non-literal type in a constexpr "
+  "%select{function|constructor}0 "
   "is incompatible with C++ standards before C++23">,
   InGroup<CXXPre23Compat>, DefaultIgnore;
 def err_constexpr_local_var_non_literal_type : Error<
   "variable of non-literal type %1 cannot be defined in a constexpr "
   "%select{function|constructor}0 before C++23">;
-def ext_constexpr_local_var_no_init : ExtWarn<
-  "uninitialized variable in a constexpr %select{function|constructor}0 "
-  "is a C++20 extension">, InGroup<CXX20>;
-def warn_cxx17_compat_constexpr_local_var_no_init : Warning<
-  "uninitialized variable in a constexpr %select{function|constructor}0 "
-  "is incompatible with C++ standards before C++20">,
-  InGroup<CXXPre20Compat>, DefaultIgnore;
 def ext_constexpr_function_never_constant_expr : ExtWarn<
   "%select{constexpr|consteval}1 %select{function|constructor}0 never produces 
a "
   "constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, 
DefaultError;
@@ -2982,41 +2954,11 @@ def err_constexpr_return_missing_expr : Error<
 def warn_cxx11_compat_constexpr_body_no_return : Warning<
   "constexpr function with no return statements is incompatible with C++ "
   "standards before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
-def ext_constexpr_body_multiple_return : ExtWarn<
-  "multiple return statements in constexpr function is a C++14 extension">,
-  InGroup<CXX14>;
-def warn_cxx11_compat_constexpr_body_multiple_return : Warning<
-  "multiple return statements in constexpr function "
-  "is incompatible with C++ standards before C++14">,
-  InGroup<CXXPre14Compat>, DefaultIgnore;
 def note_constexpr_body_previous_return : Note<
   "previous return statement is here">;
 def err_ms_constexpr_cannot_be_applied : Error<
   "attribute 'msvc::constexpr' cannot be applied to the 
%select{constexpr|consteval|virtual}0 function %1">;
 
-// C++20 function try blocks in constexpr
-def ext_constexpr_function_try_block_cxx20 : ExtWarn<
-  "function try block in constexpr %select{function|constructor}0 is "
-  "a C++20 extension">, InGroup<CXX20>;
-def warn_cxx17_compat_constexpr_function_try_block : Warning<
-  "function try block in constexpr %select{function|constructor}0 is "
-  "incompatible with C++ standards before C++20">,
-  InGroup<CXXPre20Compat>, DefaultIgnore;
-
-def ext_constexpr_union_ctor_no_init : ExtWarn<
-  "constexpr union constructor that does not initialize any member "
-  "is a C++20 extension">, InGroup<CXX20>;
-def warn_cxx17_compat_constexpr_union_ctor_no_init : Warning<
-  "constexpr union constructor that does not initialize any member "
-  "is incompatible with C++ standards before C++20">,
-  InGroup<CXXPre20Compat>, DefaultIgnore;
-def ext_constexpr_ctor_missing_init : ExtWarn<
-  "constexpr constructor that does not initialize all members "
-  "is a C++20 extension">, InGroup<CXX20>;
-def warn_cxx17_compat_constexpr_ctor_missing_init : Warning<
-  "constexpr constructor that does not initialize all members "
-  "is incompatible with C++ standards before C++20">,
-  InGroup<CXXPre20Compat>, DefaultIgnore;
 def note_constexpr_ctor_missing_init : Note<
   "member not initialized by constructor">;
 def note_non_literal_no_constexpr_ctors : Note<
@@ -5293,12 +5235,6 @@ def note_template_param_prev_default_arg_in_other_module 
: Note<
   "previous default template argument defined in module %0">;
 def err_template_param_default_arg_missing : Error<
   "template parameter missing a default argument">;
-def ext_template_parameter_default_in_function_template : ExtWarn<
-  "default template arguments for a function template are a C++11 extension">,
-  InGroup<CXX11>;
-def warn_cxx98_compat_template_parameter_default_in_function_template : 
Warning<
-  "default template arguments for a function template are incompatible with 
C++98">,
-  InGroup<CXX98Compat>, DefaultIgnore;
 def err_template_parameter_default_template_member : Error<
   "cannot add a default template argument to the definition of a member of a "
   "class template">;
@@ -5307,11 +5243,6 @@ def err_template_parameter_default_friend_template : 
Error<
 def err_template_template_parm_no_parms : Error<
   "template template parameter must have its own template parameters">;
 
-def ext_variable_template : ExtWarn<"variable templates are a C++14 
extension">,
-  InGroup<CXX14>;
-def warn_cxx11_compat_variable_template : Warning<
-  "variable templates are incompatible with C++ standards before C++14">,
-  InGroup<CXXPre14Compat>, DefaultIgnore;
 def err_template_variable_noparams : Error<
   "extraneous 'template<>' in declaration of variable %0">;
 def err_template_member : Error<"non-static data member %0 cannot be declared 
as a template">;
@@ -5321,15 +5252,6 @@ def err_template_member_noparams : Error<
 def err_template_tag_noparams : Error<
   "extraneous 'template<>' in declaration of %0 %1">;
 
-def warn_cxx17_compat_adl_only_template_id : Warning<
-  "use of function template name with no prior function template "
-  "declaration in function call with explicit template arguments "
-  "is incompatible with C++ standards before C++20">,
-  InGroup<CXXPre20Compat>, DefaultIgnore;
-def ext_adl_only_template_id : ExtWarn<
-  "use of function template name with no prior declaration in function call "
-  "with explicit template arguments is a C++20 extension">, InGroup<CXX20>;
-
 def warn_unqualified_call_to_std_cast_function : Warning<
   "unqualified call to '%0'">, InGroup<DiagGroup<"unqualified-std-cast-call">>;
 
@@ -5468,11 +5390,6 @@ def err_template_arg_not_pointer_to_member_form : Error<
   "non-type template argument is not a pointer to member constant">;
 def err_template_arg_invalid : Error<
   "non-type template argument '%0' is invalid">;
-def ext_template_arg_extra_parens : ExtWarn<
-  "address non-type template argument cannot be surrounded by parentheses">;
-def warn_cxx98_compat_template_arg_extra_parens : Warning<
-  "redundant parentheses surrounding address non-type template argument are "
-  "incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
 def err_pointer_to_member_type : Error<
   "invalid use of pointer to member type after %select{.*|->*}0">;
 def err_pointer_to_member_call_drops_quals : Error<
@@ -5887,11 +5804,6 @@ def err_typename_missing_template
 def ext_typename_missing
     : ExtWarn<"missing 'typename' prior to dependent type name %0">,
       InGroup<DiagGroup<"typename-missing">>;
-def ext_typename_outside_of_template : ExtWarn<
-  "'typename' occurs outside of a template">, InGroup<CXX11>;
-def warn_cxx98_compat_typename_outside_of_template : Warning<
-  "use of 'typename' outside of a template is incompatible with C++98">,
-  InGroup<CXX98Compat>, DefaultIgnore;
 def err_typename_refers_to_using_value_decl : Error<
   "typename specifier refers to a dependent using declaration for a value "
   "%0 in %1">;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 61e3cd4066a8d..67d734c8cf8a2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7648,8 +7648,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(
           // Only C++1y supports variable templates (N3651).
           Diag(D.getIdentifierLoc(),
                getLangOpts().CPlusPlus14
-                   ? diag::warn_cxx11_compat_variable_template
-                   : diag::ext_variable_template);
+                   ? diag::compat_cxx14_variable_template
+                   : diag::compat_pre_cxx14_variable_template);
         }
       }
     } else {
@@ -7717,8 +7717,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(
             // the program is ill-formed. C++11 drops this restriction.
             Diag(D.getIdentifierLoc(),
                  getLangOpts().CPlusPlus11
-                     ? diag::warn_cxx98_compat_static_data_member_in_union
-                     : diag::ext_static_data_member_in_union)
+                     ? diag::compat_cxx11_static_data_member_in_union
+                     : diag::compat_pre_cxx11_static_data_member_in_union)
                 << Name;
           }
         }
@@ -7821,8 +7821,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(
         << FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc());
     } else {
       Diag(D.getDeclSpec().getInlineSpecLoc(),
-           getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_inline_variable
-                                     : diag::ext_inline_variable);
+           getLangOpts().CPlusPlus17 ? diag::compat_cxx17_inline_variable
+                                     : diag::compat_pre_cxx17_inline_variable);
       NewVD->setInlineSpecified();
     }
   }
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index bd6321c46a78f..753beeb3c5349 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -745,12 +745,12 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator 
&D,
 
   unsigned DiagID;
   if (!getLangOpts().CPlusPlus17)
-    DiagID = diag::ext_decomp_decl;
+    DiagID = diag::compat_pre_cxx17_decomp_decl;
   else if (D.getContext() == DeclaratorContext::Condition)
-    DiagID = getLangOpts().CPlusPlus26 ? diag::warn_cxx26_decomp_decl_cond
-                                       : diag::ext_decomp_decl_cond;
+    DiagID = getLangOpts().CPlusPlus26 ? diag::compat_cxx26_decomp_decl_cond
+                                       : 
diag::compat_pre_cxx26_decomp_decl_cond;
   else
-    DiagID = diag::warn_cxx14_compat_decomp_decl;
+    DiagID = diag::compat_cxx17_decomp_decl;
 
   Diag(Decomp.getLSquareLoc(), DiagID) << Decomp.getSourceRange();
 
@@ -808,8 +808,8 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
     } else if (!CPlusPlus20Specifiers.empty()) {
       auto &&Warn = Diag(CPlusPlus20SpecifierLocs.front(),
                          getLangOpts().CPlusPlus20
-                             ? diag::warn_cxx17_compat_decomp_decl_spec
-                             : diag::ext_decomp_decl_spec);
+                             ? diag::compat_cxx20_decomp_decl_spec
+                             : diag::compat_pre_cxx20_decomp_decl_spec);
       Warn << (int)CPlusPlus20Specifiers.size()
            << llvm::join(CPlusPlus20Specifiers.begin(),
                          CPlusPlus20Specifiers.end(), " ");
@@ -2041,8 +2041,8 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
         if (Kind == Sema::CheckConstexprKind::Diagnose) {
           SemaRef.Diag(DS->getBeginLoc(),
                        SemaRef.getLangOpts().CPlusPlus14
-                           ? diag::warn_cxx11_compat_constexpr_type_definition
-                           : diag::ext_constexpr_type_definition)
+                           ? diag::compat_cxx14_constexpr_type_definition
+                           : diag::compat_pre_cxx14_constexpr_type_definition)
               << isa<CXXConstructorDecl>(Dcl);
         } else if (!SemaRef.getLangOpts().CPlusPlus14) {
           return false;
@@ -2069,8 +2069,8 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
           if (Kind == Sema::CheckConstexprKind::Diagnose) {
             SemaRef.Diag(VD->getLocation(),
                          SemaRef.getLangOpts().CPlusPlus23
-                             ? diag::warn_cxx20_compat_constexpr_var
-                             : diag::ext_constexpr_static_var)
+                             ? diag::compat_cxx23_constexpr_static_var
+                             : diag::compat_pre_cxx23_constexpr_static_var)
                 << isa<CXXConstructorDecl>(Dcl)
                 << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
           } else if (!SemaRef.getLangOpts().CPlusPlus23) {
@@ -2080,8 +2080,7 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
         if (SemaRef.LangOpts.CPlusPlus23) {
           CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
                            diag::warn_cxx20_compat_constexpr_var,
-                           isa<CXXConstructorDecl>(Dcl),
-                           /*variable of non-literal type*/ 2);
+                           isa<CXXConstructorDecl>(Dcl));
         } else if (CheckLiteralType(
                        SemaRef, Kind, VD->getLocation(), VD->getType(),
                        diag::err_constexpr_local_var_non_literal_type,
@@ -2094,8 +2093,8 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
             SemaRef.Diag(
                 VD->getLocation(),
                 SemaRef.getLangOpts().CPlusPlus20
-                    ? diag::warn_cxx17_compat_constexpr_local_var_no_init
-                    : diag::ext_constexpr_local_var_no_init)
+                    ? diag::compat_cxx20_constexpr_local_var_no_init
+                    : diag::compat_pre_cxx20_constexpr_local_var_no_init)
                 << isa<CXXConstructorDecl>(Dcl);
           } else if (!SemaRef.getLangOpts().CPlusPlus20) {
             return false;
@@ -2106,8 +2105,8 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
       if (Kind == Sema::CheckConstexprKind::Diagnose) {
         SemaRef.Diag(VD->getLocation(),
                      SemaRef.getLangOpts().CPlusPlus14
-                      ? diag::warn_cxx11_compat_constexpr_local_var
-                      : diag::ext_constexpr_local_var)
+                      ? diag::compat_cxx14_constexpr_local_var
+                      : diag::compat_pre_cxx14_constexpr_local_var)
           << isa<CXXConstructorDecl>(Dcl);
       } else if (!SemaRef.getLangOpts().CPlusPlus14) {
         return false;
@@ -2179,8 +2178,8 @@ static bool CheckConstexprCtorInitializer(Sema &SemaRef,
       if (!Diagnosed) {
         SemaRef.Diag(Dcl->getLocation(),
                      SemaRef.getLangOpts().CPlusPlus20
-                         ? diag::warn_cxx17_compat_constexpr_ctor_missing_init
-                         : diag::ext_constexpr_ctor_missing_init);
+                         ? diag::compat_cxx20_constexpr_ctor_missing_init
+                         : diag::compat_pre_cxx20_constexpr_ctor_missing_init);
         Diagnosed = true;
       }
       SemaRef.Diag(Field->getLocation(),
@@ -2392,9 +2391,9 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, 
const FunctionDecl *Dcl,
 
     case Sema::CheckConstexprKind::Diagnose:
       SemaRef.Diag(Body->getBeginLoc(),
-           !SemaRef.getLangOpts().CPlusPlus20
-               ? diag::ext_constexpr_function_try_block_cxx20
-               : diag::warn_cxx17_compat_constexpr_function_try_block)
+                   SemaRef.getLangOpts().CPlusPlus20
+                       ? diag::compat_cxx20_constexpr_function_try_block
+                       : diag::compat_pre_cxx20_constexpr_function_try_block)
           << isa<CXXConstructorDecl>(Dcl);
       break;
     }
@@ -2423,20 +2422,20 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, 
const FunctionDecl *Dcl,
   } else if (Cxx2bLoc.isValid()) {
     SemaRef.Diag(Cxx2bLoc,
                  SemaRef.getLangOpts().CPlusPlus23
-                     ? diag::warn_cxx20_compat_constexpr_body_invalid_stmt
-                     : diag::ext_constexpr_body_invalid_stmt_cxx23)
+                     ? diag::compat_cxx23_constexpr_body_invalid_stmt
+                     : diag::compat_pre_cxx23_constexpr_body_invalid_stmt)
         << isa<CXXConstructorDecl>(Dcl);
   } else if (Cxx2aLoc.isValid()) {
     SemaRef.Diag(Cxx2aLoc,
          SemaRef.getLangOpts().CPlusPlus20
-           ? diag::warn_cxx17_compat_constexpr_body_invalid_stmt
-           : diag::ext_constexpr_body_invalid_stmt_cxx20)
+           ? diag::compat_cxx20_constexpr_body_invalid_stmt
+           : diag::compat_pre_cxx20_constexpr_body_invalid_stmt)
       << isa<CXXConstructorDecl>(Dcl);
   } else if (Cxx1yLoc.isValid()) {
     SemaRef.Diag(Cxx1yLoc,
          SemaRef.getLangOpts().CPlusPlus14
-           ? diag::warn_cxx11_compat_constexpr_body_invalid_stmt
-           : diag::ext_constexpr_body_invalid_stmt)
+           ? diag::compat_cxx14_constexpr_body_invalid_stmt
+           : diag::compat_pre_cxx14_constexpr_body_invalid_stmt)
       << isa<CXXConstructorDecl>(Dcl);
   }
 
@@ -2456,8 +2455,8 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, 
const FunctionDecl *Dcl,
           SemaRef.Diag(
               Dcl->getLocation(),
               SemaRef.getLangOpts().CPlusPlus20
-                  ? diag::warn_cxx17_compat_constexpr_union_ctor_no_init
-                  : diag::ext_constexpr_union_ctor_no_init);
+                  ? diag::compat_cxx20_constexpr_union_ctor_no_init
+                  : diag::compat_pre_cxx20_constexpr_union_ctor_no_init);
         } else if (!SemaRef.getLangOpts().CPlusPlus20) {
           return false;
         }
@@ -2523,8 +2522,8 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, 
const FunctionDecl *Dcl,
         SemaRef.Diag(
             ReturnStmts.back(),
             SemaRef.getLangOpts().CPlusPlus14
-                ? diag::warn_cxx11_compat_constexpr_body_multiple_return
-                : diag::ext_constexpr_body_multiple_return);
+                ? diag::compat_cxx14_constexpr_body_multiple_return
+                : diag::compat_pre_cxx14_constexpr_body_multiple_return);
         for (unsigned I = 0; I < ReturnStmts.size() - 1; ++I)
           SemaRef.Diag(ReturnStmts[I],
                        diag::note_constexpr_body_previous_return);
@@ -17825,8 +17824,8 @@ Decl *Sema::ActOnFriendTypeDecl(Scope *S, const 
DeclSpec &DS,
                                         InsertionText);
     } else {
       Diag(FriendLoc, getLangOpts().CPlusPlus11
-                          ? diag::warn_cxx98_compat_nonclass_type_friend
-                          : diag::ext_nonclass_type_friend)
+                          ? diag::compat_cxx11_nonclass_type_friend
+                          : diag::compat_pre_cxx11_nonclass_type_friend)
           << T << DS.getSourceRange();
     }
   }
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a03acb5fbd273..7c666fb94bd53 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6484,8 +6484,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, 
SourceLocation LParenLoc,
       ULE && ULE->hasExplicitTemplateArgs() &&
       ULE->decls_begin() == ULE->decls_end()) {
     Diag(Fn->getExprLoc(), getLangOpts().CPlusPlus20
-                               ? diag::warn_cxx17_compat_adl_only_template_id
-                               : diag::ext_adl_only_template_id)
+                               ? diag::compat_cxx20_adl_only_template_id
+                               : diag::compat_pre_cxx20_adl_only_template_id)
         << ULE->getName();
   }
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index c3c993d51b79d..b56572c7cae42 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2235,10 +2235,11 @@ static bool DiagnoseDefaultTemplateArgument(Sema &S,
     //   template-argument, that declaration shall be a definition and shall be
     //   the only declaration of the function template in the translation unit.
     // (C++98/03 doesn't have this wording; see DR226).
-    S.Diag(ParamLoc, S.getLangOpts().CPlusPlus11 ?
-         
diag::warn_cxx98_compat_template_parameter_default_in_function_template
-           : diag::ext_template_parameter_default_in_function_template)
-      << DefArgRange;
+    S.Diag(ParamLoc,
+           S.getLangOpts().CPlusPlus11
+               ? diag::compat_cxx11_templ_default_in_function_templ
+               : diag::compat_pre_cxx11_templ_default_in_function_templ)
+        << DefArgRange;
     return false;
 
   case Sema::TPC_ClassTemplateMember:
@@ -6428,8 +6429,8 @@ static bool 
CheckTemplateArgumentAddressOfObjectOrFunction(
       if (!Invalid && !ExtraParens) {
         S.Diag(Arg->getBeginLoc(),
                S.getLangOpts().CPlusPlus11
-                   ? diag::warn_cxx98_compat_template_arg_extra_parens
-                   : diag::ext_template_arg_extra_parens)
+                   ? diag::compat_cxx11_template_arg_extra_parens
+                   : diag::compat_pre_cxx11_template_arg_extra_parens)
             << Arg->getSourceRange();
         ExtraParens = true;
       }
@@ -6651,8 +6652,8 @@ CheckTemplateArgumentPointerToMember(Sema &S, 
NonTypeTemplateParmDecl *Param,
     if (!Invalid && !ExtraParens) {
       S.Diag(Arg->getBeginLoc(),
              S.getLangOpts().CPlusPlus11
-                 ? diag::warn_cxx98_compat_template_arg_extra_parens
-                 : diag::ext_template_arg_extra_parens)
+                 ? diag::compat_cxx11_template_arg_extra_parens
+                 : diag::compat_pre_cxx11_template_arg_extra_parens)
           << Arg->getSourceRange();
       ExtraParens = true;
     }
@@ -10636,8 +10637,8 @@ TypeResult Sema::ActOnTypenameType(Scope *S, 
SourceLocation TypenameLoc,
   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
     Diag(TypenameLoc,
          getLangOpts().CPlusPlus11 ?
-           diag::warn_cxx98_compat_typename_outside_of_template :
-           diag::ext_typename_outside_of_template)
+           diag::compat_cxx11_typename_outside_of_template :
+           diag::compat_pre_cxx11_typename_outside_of_template)
       << FixItHint::CreateRemoval(TypenameLoc);
 
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
@@ -10664,8 +10665,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation 
TypenameLoc,
   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
     Diag(TypenameLoc,
          getLangOpts().CPlusPlus11 ?
-           diag::warn_cxx98_compat_typename_outside_of_template :
-           diag::ext_typename_outside_of_template)
+           diag::compat_cxx11_typename_outside_of_template :
+           diag::compat_pre_cxx11_typename_outside_of_template)
       << FixItHint::CreateRemoval(TypenameLoc);
 
   // Strangely, non-type results are not ignored by this lookup, so the
diff --git a/clang/test/AST/ByteCode/if.cpp b/clang/test/AST/ByteCode/if.cpp
index 909e08a22a283..ad87b64fec468 100644
--- a/clang/test/AST/ByteCode/if.cpp
+++ b/clang/test/AST/ByteCode/if.cpp
@@ -54,7 +54,7 @@ namespace InitDecl {
 constexpr char g(char const (&x)[2]) {
     return 'x';
   if (auto [a, b] = x) // both-error {{an array type is not allowed here}} \
-                       // both-warning {{structured binding declaration in a 
condition is a C++2c extenstion}}
+                       // both-warning {{structured binding declaration in a 
condition is a C++2c extension}}
     ;
 }
 static_assert(g("x") == 'x');
diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp
index 9c72fefb5b65c..2501a10846129 100644
--- a/clang/test/CXX/drs/cwg13xx.cpp
+++ b/clang/test/CXX/drs/cwg13xx.cpp
@@ -81,14 +81,14 @@ namespace cwg1310 { // cwg1310: 5
     W<int>::W<int>::X w1bx;
     typename W<int>::W w2a;
     // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' 
is a constructor name rather than a type in this context, despite preceding 
'typename' keyword}}
-    // cxx98-error@-2 {{'typename' occurs outside of a template}}
+    // cxx98-error@-2 {{'typename' outside of a template is a C++11 extension}}
     typename W<int>::W::X w2ax;
-    // cxx98-error@-1 {{'typename' occurs outside of a template}}
+    // cxx98-error@-1 {{'typename' outside of a template is a C++11 extension}}
     typename W<int>::W<int> w2b;
     // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' 
is a constructor name rather than a template name in this context, despite 
preceding 'typename' keyword}}
-    // cxx98-error@-2 {{'typename' occurs outside of a template}}
+    // cxx98-error@-2 {{'typename' outside of a template is a C++11 extension}}
     typename W<int>::W<int>::X w2bx;
-    // cxx98-error@-1 {{'typename' occurs outside of a template}}
+    // cxx98-error@-1 {{'typename' outside of a template is a C++11 extension}}
     W<int>::template W<int> w3;
     // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' 
is a constructor name rather than a template name in this context, despite 
preceding 'template' keyword}}
     // cxx98-error@-2 {{'template' keyword outside of a template}}
@@ -97,10 +97,10 @@ namespace cwg1310 { // cwg1310: 5
     typename W<int>::template W<int> w4;
     // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' 
is a constructor name rather than a template name in this context, despite 
preceding 'template' keyword}}
     // cxx98-error@-2 {{'template' keyword outside of a template}}
-    // cxx98-error@-3 {{'typename' occurs outside of a template}}
+    // cxx98-error@-3 {{'typename' outside of a template is a C++11 extension}}
     typename W<int>::template W<int>::X w4x;
     // cxx98-error@-1 {{'template' keyword outside of a template}}
-    // cxx98-error@-2 {{'typename' occurs outside of a template}}
+    // cxx98-error@-2 {{'typename' outside of a template is a C++11 extension}}
 
     TT<W<int>::W> tt1;
     // expected-error@-1 {{qualified reference to 'W' is a constructor name 
rather than a type in this context}}
diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp
index 4a5394be146bc..6b9ad31bffbcd 100644
--- a/clang/test/CXX/drs/cwg1xx.cpp
+++ b/clang/test/CXX/drs/cwg1xx.cpp
@@ -1295,7 +1295,7 @@ namespace cwg183 { // cwg183: sup 382
   };
   template<> struct A<int> {
     typename B<int>::X x;
-    // cxx98-error@-1 {{'typename' occurs outside of a template}}
+    // cxx98-error@-1 {{'typename' outside of a template is a C++11 extension}}
   };
 } // namespace cwg183
 
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index 164cc26ae585a..8b035cf6f2370 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -1333,9 +1333,9 @@ namespace cwg382 { // cwg382: 2.7 c++11
   // FIXME: Should we allow this in C++98 mode?
   struct A { typedef int T; };
   typename A::T t;
-  // cxx98-error@-1 {{'typename' occurs outside of a template}}
+  // cxx98-error@-1 {{'typename' outside of a template is a C++11 extension}}
   typename cwg382::A a;
-  // cxx98-error@-1 {{'typename' occurs outside of a template}}
+  // cxx98-error@-1 {{'typename' outside of a template is a C++11 extension}}
   typename A b;
   // expected-error@-1 {{expected a qualified name after 'typename'}}
 } // namespace cwg382
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp 
b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
index 034ad49d0715c..15b7a40654cd7 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
@@ -64,7 +64,7 @@ namespace pointer_to_object_parameters {
   A2<&an_X> *a13_2;
   A2<(&an_X)> *a13_3;
 #if __cplusplus < 201103L
-  // expected-warning@-2 {{address non-type template argument cannot be 
surrounded by parentheses}}
+  // expected-warning@-2 {{parentheses around address non-type template 
argument are a C++11 extension}}
 #endif
 
   // PR6244
diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c
index 46b4e5a064c36..a978835a41014 100644
--- a/clang/test/Misc/warning-flags.c
+++ b/clang/test/Misc/warning-flags.c
@@ -18,13 +18,12 @@ This test serves two purposes:
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (59):
+CHECK: Warnings without flags (58):
 
 CHECK-NEXT:   ext_expected_semi_decl_list
 CHECK-NEXT:   ext_missing_whitespace_after_macro_name
 CHECK-NEXT:   ext_new_paren_array_nonconst
 CHECK-NEXT:   ext_plain_complex
-CHECK-NEXT:   ext_template_arg_extra_parens
 CHECK-NEXT:   ext_typecheck_cond_incompatible_operands
 CHECK-NEXT:   ext_typecheck_ordered_comparison_of_pointer_integer
 CHECK-NEXT:   ext_using_undefined_std
diff --git a/clang/test/Parser/cxx1z-decomposition.cpp 
b/clang/test/Parser/cxx1z-decomposition.cpp
index a6ca642269eee..3e2526979be8b 100644
--- a/clang/test/Parser/cxx1z-decomposition.cpp
+++ b/clang/test/Parser/cxx1z-decomposition.cpp
@@ -37,12 +37,12 @@ namespace OtherDecl {
   void g() {
     // A condition is allowed as a Clang extension.
     // See commentary in test/Parser/decomposed-condition.cpp
-    for (; auto [a, b, c] = S(); ) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extenstion}} expected-error {{value of 
type 'S' is not contextually convertible to 'bool'}}
-    if (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extenstion}} expected-error {{value of 
type 'S' is not contextually convertible to 'bool'}}
-    if (int n; auto [a, b, c] = S()) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extenstion}} expected-error {{value of 
type 'S' is not contextually convertible to 'bool'}}
-    switch (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extenstion}} expected-error {{statement 
requires expression of integer type ('S' invalid)}}
-    switch (int n; auto [a, b, c] = S()) {} // pre2c-warning {{structured 
binding declaration in a condition is a C++2c extenstion}} expected-error 
{{statement requires expression of integer type ('S' invalid)}}
-    while (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extenstion}} expected-error {{value of 
type 'S' is not contextually convertible to 'bool'}}
+    for (; auto [a, b, c] = S(); ) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extension}} expected-error {{value of 
type 'S' is not contextually convertible to 'bool'}}
+    if (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extension}} expected-error {{value of 
type 'S' is not contextually convertible to 'bool'}}
+    if (int n; auto [a, b, c] = S()) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extension}} expected-error {{value of 
type 'S' is not contextually convertible to 'bool'}}
+    switch (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extension}} expected-error {{statement 
requires expression of integer type ('S' invalid)}}
+    switch (int n; auto [a, b, c] = S()) {} // pre2c-warning {{structured 
binding declaration in a condition is a C++2c extension}} expected-error 
{{statement requires expression of integer type ('S' invalid)}}
+    while (auto [a, b, c] = S()) {} // pre2c-warning {{structured binding 
declaration in a condition is a C++2c extension}} expected-error {{value of 
type 'S' is not contextually convertible to 'bool'}}
 
     // An exception-declaration is not a simple-declaration.
     try {}
diff --git a/clang/test/Parser/decomposed-condition.cpp 
b/clang/test/Parser/decomposed-condition.cpp
index 37a24f8f95093..15a9da7d32004 100644
--- a/clang/test/Parser/decomposed-condition.cpp
+++ b/clang/test/Parser/decomposed-condition.cpp
@@ -33,33 +33,33 @@ Na g();
 
 namespace CondInIf {
 int h() {
-  if (auto [ok, d] = f()) // expected-warning {{structured binding declaration 
in a condition is a C++2c extenstion}}
+  if (auto [ok, d] = f()) // expected-warning {{structured binding declaration 
in a condition is a C++2c extension}}
     ;
-  if (auto [ok, d] = g()) // expected-warning {{structured binding declaration 
in a condition is a C++2c extenstion}} expected-error {{value of type 'Na' is 
not contextually convertible to 'bool'}}
+  if (auto [ok, d] = g()) // expected-warning {{structured binding declaration 
in a condition is a C++2c extension}} expected-error {{value of type 'Na' is 
not contextually convertible to 'bool'}}
     ;
-  if (auto [value] = Get()) // expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}}
+  if (auto [value] = Get()) // expected-warning {{structured binding 
declaration in a condition is a C++2c extension}}
     return value;
 }
 } // namespace CondInIf
 
 namespace CondInWhile {
 int h() {
-  while (auto [ok, d] = f()) // expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}}
+  while (auto [ok, d] = f()) // expected-warning {{structured binding 
declaration in a condition is a C++2c extension}}
     ;
-  while (auto [ok, d] = g()) // expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}} expected-error {{value of 
type 'Na' is not contextually convertible to 'bool'}}
+  while (auto [ok, d] = g()) // expected-warning {{structured binding 
declaration in a condition is a C++2c extension}} expected-error {{value of 
type 'Na' is not contextually convertible to 'bool'}}
     ;
-  while (auto [value] = Get()) // expected-warning{{structured binding 
declaration in a condition is a C++2c extenstion}}
+  while (auto [value] = Get()) // expected-warning{{structured binding 
declaration in a condition is a C++2c extension}}
     return value;
 }
 } // namespace CondInWhile
 
 namespace CondInFor {
 int h() {
-  for (; auto [ok, d] = f();) // expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}}
+  for (; auto [ok, d] = f();) // expected-warning {{structured binding 
declaration in a condition is a C++2c extension}}
     ;
-  for (; auto [ok, d] = g();) // expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}} expected-error {{value of 
type 'Na' is not contextually convertible to 'bool'}}
+  for (; auto [ok, d] = g();) // expected-warning {{structured binding 
declaration in a condition is a C++2c extension}} expected-error {{value of 
type 'Na' is not contextually convertible to 'bool'}}
     ;
-  for (; auto [value] = Get();) // expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}}
+  for (; auto [value] = Get();) // expected-warning {{structured binding 
declaration in a condition is a C++2c extension}}
     return value;
 }
 } // namespace CondInFor
@@ -74,11 +74,11 @@ struct IntegerLike {
 
 namespace CondInSwitch {
 int h(IntegerLike x) {
-  switch (auto [ok, d] = x) // expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}}
+  switch (auto [ok, d] = x) // expected-warning {{structured binding 
declaration in a condition is a C++2c extension}}
     ;
-  switch (auto [ok, d] = g()) // expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}} expected-error {{statement 
requires expression of integer type ('Na' invalid)}}
+  switch (auto [ok, d] = g()) // expected-warning {{structured binding 
declaration in a condition is a C++2c extension}} expected-error {{statement 
requires expression of integer type ('Na' invalid)}}
     ;
-  switch (auto [value] = Get()) {// expected-warning {{structured binding 
declaration in a condition is a C++2c extenstion}}
+  switch (auto [value] = Get()) {// expected-warning {{structured binding 
declaration in a condition is a C++2c extension}}
   // expected-warning@-1{{switch condition has boolean value}}
   case 1:
     return value;
diff --git a/clang/test/SemaCXX/cxx98-compat.cpp 
b/clang/test/SemaCXX/cxx98-compat.cpp
index d31d95a9995f1..43ba208d375cd 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -189,8 +189,8 @@ int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); 
// expected-warning {{
 namespace RedundantParensInAddressTemplateParam {
   int n;
   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}}
+  S<(&n)> s; // expected-warning {{parentheses around address non-type 
template argument are incompatible with C++98}}
+  S<(((&n)))> t; // expected-warning {{parentheses around address non-type 
template argument are incompatible with C++98}}
 }
 #endif
 
@@ -202,7 +202,7 @@ template<> struct TemplateSpecOutOfScopeNs::S<char> {};
 struct Typename {
   template<typename T> struct Inner {};
 };
-typename ::Typename TypenameOutsideTemplate(); // expected-warning {{use of 
'typename' outside of a template is incompatible with C++98}}
+typename ::Typename TypenameOutsideTemplate(); // expected-warning 
{{'typename' outside of a template is incompatible with C++98}}
 Typename::template Inner<int> TemplateOutsideTemplate(); // expected-warning 
{{use of 'template' keyword outside of a template is incompatible with C++98}}
 
 struct TrivialButNonPOD {
diff --git a/clang/test/SemaObjCXX/message.mm b/clang/test/SemaObjCXX/message.mm
index ec82d63ea908b..5c37135f1a59c 100644
--- a/clang/test/SemaObjCXX/message.mm
+++ b/clang/test/SemaObjCXX/message.mm
@@ -67,7 +67,7 @@ + (int *)otherMethod {
     if (true)
       return [typename identity<I3>::type method];
 #if __cplusplus <= 199711L
-      // expected-warning@-2 {{'typename' occurs outside of a template}}
+      // expected-warning@-2 {{'typename' outside of a template is a C++11 
extension}}
 #endif
 
     return [::I3 method];
@@ -77,12 +77,12 @@ + (int *)otherMethod {
   int* ip2 = {[::I3 method]};
   int* ip3 = {[typename identity<I3>::type method]};
 #if __cplusplus <= 199711L
-  // expected-warning@-2 {{'typename' occurs outside of a template}}
+  // expected-warning@-2 {{'typename' outside of a template is a C++11 
extension}}
 #endif
 
   int* ip4 = {[typename identity<I2_holder>::type().get() method]};
 #if __cplusplus <= 199711L
-  // expected-warning@-2 {{'typename' occurs outside of a template}}
+  // expected-warning@-2 {{'typename' outside of a template is a C++11 
extension}}
 #endif
   int array[5] = {[3] = 2}; // expected-warning {{C99 extension}}
   return [super method];
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp 
b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 2a1c059df002e..e989e45efb687 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -90,7 +90,7 @@ 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::*'}}
-A7c<(&Z::int_member)> *a18_4; // expected-warning{{address non-type template 
argument cannot be surrounded by parentheses}}
+A7c<(&Z::int_member)> *a18_4; // expected-warning{{parentheses around address 
non-type template argument are a C++11 extension}}
 A7c<&Z::union_member> *a18_5;
 
 template<unsigned char C> struct Overflow; // expected-note{{template 
parameter is declared here}}
diff --git a/clang/test/SemaTemplate/typename-specifier-4.cpp 
b/clang/test/SemaTemplate/typename-specifier-4.cpp
index 7aa2b8da51081..4853e610e2ba6 100644
--- a/clang/test/SemaTemplate/typename-specifier-4.cpp
+++ b/clang/test/SemaTemplate/typename-specifier-4.cpp
@@ -32,7 +32,7 @@ int a1[is_same<
          typename make_pair::template apply<int, float>, 
 #if __cplusplus <= 199711L // C++03 and earlier modes
          // expected-warning@-2 {{'template' keyword outside of a template}}
-         // expected-warning@-3 {{'typename' occurs outside of a template}}
+         // expected-warning@-3 {{'typename' outside of a template is a C++11 
extension}}
 #endif
          make_pair::apply<int, float>
        >::value? 1 : -1];
diff --git a/clang/test/SemaTemplate/typename-specifier.cpp 
b/clang/test/SemaTemplate/typename-specifier.cpp
index 99326f6a400ad..01acc34f3bb37 100644
--- a/clang/test/SemaTemplate/typename-specifier.cpp
+++ b/clang/test/SemaTemplate/typename-specifier.cpp
@@ -22,35 +22,35 @@ int i;
 
 typename N::A::type *ip1 = &i;
 #if __cplusplus <= 199711L // C++03 or earlier modes
-// expected-warning@-2 {{'typename' occurs outside of a template}}
+// expected-warning@-2 {{'typename' outside of a template is a C++11 
extension}}
 #endif
 typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 
'N::B'}}
 #if __cplusplus <= 199711L
-// expected-warning@-2 {{'typename' occurs outside of a template}}
+// expected-warning@-2 {{'typename' outside of a template is a C++11 
extension}}
 #endif
 typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to 
non-type member 'type'}}
 #if __cplusplus <= 199711L
-// expected-warning@-2 {{'typename' occurs outside of a template}}
+// expected-warning@-2 {{'typename' outside of a template is a C++11 
extension}}
 #endif
 
 void test(double d) {
   typename N::A::type f(typename N::A::type(a)); // 
expected-warning{{disambiguated as a function declaration}}
   // expected-note@-1 {{add a pair of parentheses}}
 #if __cplusplus <= 199711L
-  // expected-warning@-3 2{{'typename' occurs outside of a template}}
+  // expected-warning@-3 2{{'typename' outside of a template is a C++11 
extension}}
 #endif
   int five = f(5);
   
   using namespace N;
   for (typename A::type i = 0; i < 10; ++i)
 #if __cplusplus <= 199711L
-// expected-warning@-2 {{'typename' occurs outside of a template}}
+// expected-warning@-2 {{'typename' outside of a template is a C++11 
extension}}
 #endif
     five += 1;
 
   const typename N::A::type f2(d);
 #if __cplusplus <= 199711L
-// expected-warning@-2 {{'typename' occurs outside of a template}}
+// expected-warning@-2 {{'typename' outside of a template is a C++11 
extension}}
 #endif
 }
 

>From 1237a15001e81b12c22a19855462781109dd06b5 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Thu, 20 Mar 2025 02:13:24 +0100
Subject: [PATCH 3/7] clang-format

---
 clang/lib/Sema/SemaDeclCXX.cpp  | 27 ++++++++++++++-------------
 clang/lib/Sema/SemaTemplate.cpp | 18 ++++++++----------
 2 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 753beeb3c5349..15b49ff2aee99 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -747,8 +747,9 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
   if (!getLangOpts().CPlusPlus17)
     DiagID = diag::compat_pre_cxx17_decomp_decl;
   else if (D.getContext() == DeclaratorContext::Condition)
-    DiagID = getLangOpts().CPlusPlus26 ? diag::compat_cxx26_decomp_decl_cond
-                                       : 
diag::compat_pre_cxx26_decomp_decl_cond;
+    DiagID = getLangOpts().CPlusPlus26
+                 ? diag::compat_cxx26_decomp_decl_cond
+                 : diag::compat_pre_cxx26_decomp_decl_cond;
   else
     DiagID = diag::compat_cxx17_decomp_decl;
 
@@ -2105,9 +2106,9 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const 
FunctionDecl *Dcl,
       if (Kind == Sema::CheckConstexprKind::Diagnose) {
         SemaRef.Diag(VD->getLocation(),
                      SemaRef.getLangOpts().CPlusPlus14
-                      ? diag::compat_cxx14_constexpr_local_var
-                      : diag::compat_pre_cxx14_constexpr_local_var)
-          << isa<CXXConstructorDecl>(Dcl);
+                         ? diag::compat_cxx14_constexpr_local_var
+                         : diag::compat_pre_cxx14_constexpr_local_var)
+            << isa<CXXConstructorDecl>(Dcl);
       } else if (!SemaRef.getLangOpts().CPlusPlus14) {
         return false;
       }
@@ -2427,16 +2428,16 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, 
const FunctionDecl *Dcl,
         << isa<CXXConstructorDecl>(Dcl);
   } else if (Cxx2aLoc.isValid()) {
     SemaRef.Diag(Cxx2aLoc,
-         SemaRef.getLangOpts().CPlusPlus20
-           ? diag::compat_cxx20_constexpr_body_invalid_stmt
-           : diag::compat_pre_cxx20_constexpr_body_invalid_stmt)
-      << isa<CXXConstructorDecl>(Dcl);
+                 SemaRef.getLangOpts().CPlusPlus20
+                     ? diag::compat_cxx20_constexpr_body_invalid_stmt
+                     : diag::compat_pre_cxx20_constexpr_body_invalid_stmt)
+        << isa<CXXConstructorDecl>(Dcl);
   } else if (Cxx1yLoc.isValid()) {
     SemaRef.Diag(Cxx1yLoc,
-         SemaRef.getLangOpts().CPlusPlus14
-           ? diag::compat_cxx14_constexpr_body_invalid_stmt
-           : diag::compat_pre_cxx14_constexpr_body_invalid_stmt)
-      << isa<CXXConstructorDecl>(Dcl);
+                 SemaRef.getLangOpts().CPlusPlus14
+                     ? diag::compat_cxx14_constexpr_body_invalid_stmt
+                     : diag::compat_pre_cxx14_constexpr_body_invalid_stmt)
+        << isa<CXXConstructorDecl>(Dcl);
   }
 
   if (const CXXConstructorDecl *Constructor
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index b56572c7cae42..97da433b8ddbc 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10635,11 +10635,10 @@ TypeResult Sema::ActOnTypenameType(Scope *S, 
SourceLocation TypenameLoc,
     return true;
 
   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
-    Diag(TypenameLoc,
-         getLangOpts().CPlusPlus11 ?
-           diag::compat_cxx11_typename_outside_of_template :
-           diag::compat_pre_cxx11_typename_outside_of_template)
-      << FixItHint::CreateRemoval(TypenameLoc);
+    Diag(TypenameLoc, getLangOpts().CPlusPlus11
+                          ? diag::compat_cxx11_typename_outside_of_template
+                          : 
diag::compat_pre_cxx11_typename_outside_of_template)
+        << FixItHint::CreateRemoval(TypenameLoc);
 
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
   TypeSourceInfo *TSI = nullptr;
@@ -10663,11 +10662,10 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation 
TypenameLoc,
                         ASTTemplateArgsPtr TemplateArgsIn,
                         SourceLocation RAngleLoc) {
   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
-    Diag(TypenameLoc,
-         getLangOpts().CPlusPlus11 ?
-           diag::compat_cxx11_typename_outside_of_template :
-           diag::compat_pre_cxx11_typename_outside_of_template)
-      << FixItHint::CreateRemoval(TypenameLoc);
+    Diag(TypenameLoc, getLangOpts().CPlusPlus11
+                          ? diag::compat_cxx11_typename_outside_of_template
+                          : 
diag::compat_pre_cxx11_typename_outside_of_template)
+        << FixItHint::CreateRemoval(TypenameLoc);
 
   // Strangely, non-type results are not ignored by this lookup, so the
   // program is ill-formed if it finds an injected-class-name.

>From 230528403f934619e3b97f37c58cc0006fd391a0 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Thu, 20 Mar 2025 02:18:36 +0100
Subject: [PATCH 4/7] Shorten 'CompatWarn' to just 'Compat'

---
 clang/include/clang/Basic/Diagnostic.td       | 26 ++++++------
 .../clang/Basic/DiagnosticSemaKinds.td        | 40 +++++++++----------
 2 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/clang/include/clang/Basic/Diagnostic.td 
b/clang/include/clang/Basic/Diagnostic.td
index 85b7276695613..26ac50f391d78 100644
--- a/clang/include/clang/Basic/Diagnostic.td
+++ b/clang/include/clang/Basic/Diagnostic.td
@@ -156,7 +156,7 @@ class DefaultWarnNoWerror {
 class DefaultRemark { Severity DefaultSeverity = SEV_Remark; }
 
 // C++ compatibility warnings
-multiclass CXXCompatWarn<
+multiclass CXXCompat<
     string message,
     bit default_ignore,
     int std_ver,
@@ -180,23 +180,23 @@ multiclass CXXCompatWarn<
         DefaultIgnore;
 }
 
-multiclass CXX11CompatWarn<string message, bit default_ignore = false>
-    : CXXCompatWarn<message, default_ignore, 11>;
+multiclass CXX11Compat<string message, bit default_ignore = false>
+    : CXXCompat<message, default_ignore, 11>;
 
-multiclass CXX14CompatWarn<string message, bit default_ignore = false>
-    : CXXCompatWarn<message, default_ignore, 14>;
+multiclass CXX14Compat<string message, bit default_ignore = false>
+    : CXXCompat<message, default_ignore, 14>;
 
-multiclass CXX17CompatWarn<string message, bit default_ignore = false>
-    : CXXCompatWarn<message, default_ignore, 17>;
+multiclass CXX17Compat<string message, bit default_ignore = false>
+    : CXXCompat<message, default_ignore, 17>;
 
-multiclass CXX20CompatWarn<string message, bit default_ignore = false>
-    : CXXCompatWarn<message, default_ignore, 20>;
+multiclass CXX20Compat<string message, bit default_ignore = false>
+    : CXXCompat<message, default_ignore, 20>;
 
-multiclass CXX23CompatWarn<string message, bit default_ignore = false>
-    : CXXCompatWarn<message, default_ignore, 23>;
+multiclass CXX23Compat<string message, bit default_ignore = false>
+    : CXXCompat<message, default_ignore, 23>;
 
-multiclass CXX26CompatWarn<string message, bit default_ignore = false>
-    : CXXCompatWarn<message, default_ignore, 26, "2c">;
+multiclass CXX26Compat<string message, bit default_ignore = false>
+    : CXXCompat<message, default_ignore, 26, "2c">;
 
 // Definitions for Diagnostics.
 include "DiagnosticASTKinds.td"
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4ef1ab0ca4470..f5dfd0cfa419d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13,55 +13,55 @@
 let Component = "Sema" in {
 let CategoryName = "Semantic Issue" in {
 // C++11 compatibility with C++98.
-defm nonclass_type_friend : CXX11CompatWarn<"non-class friend type %0 is">;
-defm static_data_member_in_union : CXX11CompatWarn<"static data member %0 in 
union is">;
-defm templ_default_in_function_templ : CXX11CompatWarn<
+defm nonclass_type_friend : CXX11Compat<"non-class friend type %0 is">;
+defm static_data_member_in_union : CXX11Compat<"static data member %0 in union 
is">;
+defm templ_default_in_function_templ : CXX11Compat<
   "default template arguments for a function template are">;
-defm template_arg_extra_parens : CXX11CompatWarn<
+defm template_arg_extra_parens : CXX11Compat<
   "parentheses around address non-type template argument are">;
-defm typename_outside_of_template : CXX11CompatWarn<"'typename' outside of a 
template is">;
+defm typename_outside_of_template : CXX11Compat<"'typename' outside of a 
template is">;
 
 // C++14 compatibility with C++11 and earlier.
-defm constexpr_type_definition : CXX14CompatWarn<
+defm constexpr_type_definition : CXX14Compat<
   "type definition in a constexpr %select{function|constructor}0 is">;
-defm constexpr_local_var : CXX14CompatWarn<
+defm constexpr_local_var : CXX14Compat<
   "variable declaration in a constexpr %select{function|constructor}0 is">;
-defm constexpr_body_multiple_return : CXX14CompatWarn<
+defm constexpr_body_multiple_return : CXX14Compat<
   "multiple return statements in constexpr function is">;
-defm variable_template : CXX14CompatWarn<"variable templates are">;
+defm variable_template : CXX14Compat<"variable templates are">;
 
 // C++17 compatibility with C++14 and earlier.
-defm decomp_decl : CXX17CompatWarn<"decomposition declarations are">;
-defm inline_variable : CXX17CompatWarn<"inline variables are">;
+defm decomp_decl : CXX17Compat<"decomposition declarations are">;
+defm inline_variable : CXX17Compat<"inline variables are">;
 
 // C++20 compatibility with C++17 and earlier.
-defm decomp_decl_spec : CXX20CompatWarn<
+defm decomp_decl_spec : CXX20Compat<
   "decomposition declaration declared "
   "%plural{1:'%1'|:with '%1' specifiers}0 is">;
-defm constexpr_local_var_no_init : CXX20CompatWarn<
+defm constexpr_local_var_no_init : CXX20Compat<
   "uninitialized variable in a constexpr %select{function|constructor}0 is">;
-defm constexpr_function_try_block : CXX20CompatWarn<
+defm constexpr_function_try_block : CXX20Compat<
   "function try block in constexpr %select{function|constructor}0 is">;
-defm constexpr_union_ctor_no_init : CXX20CompatWarn<
+defm constexpr_union_ctor_no_init : CXX20Compat<
   "constexpr union constructor that does not initialize any member is">;
-defm constexpr_ctor_missing_init : CXX20CompatWarn<
+defm constexpr_ctor_missing_init : CXX20Compat<
   "constexpr constructor that does not initialize all members is">;
-defm adl_only_template_id : CXX20CompatWarn<
+defm adl_only_template_id : CXX20Compat<
   "use of function template name with no prior declaration in function call "
   "with explicit template arguments is">;
 
 // C++23 compatibility with C++20 and earlier.
-defm constexpr_static_var : CXX23CompatWarn<
+defm constexpr_static_var : CXX23Compat<
   "definition of a %select{static|thread_local}1 variable "
   "in a constexpr %select{function|constructor}0 "
   "is">;
 
 // C++26 compatibility with C++23 and earlier.
-defm decomp_decl_cond : CXX26CompatWarn<"structured binding declaration in a 
condition is">;
+defm decomp_decl_cond : CXX26Compat<"structured binding declaration in a 
condition is">;
 
 // Compatibility warnings duplicated across multiple language versions.
 foreach std = [14, 20, 23] in {
-  defm constexpr_body_invalid_stmt : CXXCompatWarn<
+  defm constexpr_body_invalid_stmt : CXXCompat<
     "use of this statement in a constexpr %select{function|constructor}0 is",
     /*default_ignore=*/false,
     std>;

>From ff090e2d64aa8e0a6f91ce264cdefe7ac9746199 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Thu, 20 Mar 2025 02:25:00 +0100
Subject: [PATCH 5/7] Rename and reorder parameters

---
 clang/include/clang/Basic/Diagnostic.td       | 30 +++++++++----------
 .../clang/Basic/DiagnosticSemaKinds.td        |  4 +--
 2 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/clang/include/clang/Basic/Diagnostic.td 
b/clang/include/clang/Basic/Diagnostic.td
index 26ac50f391d78..f18aeee996f97 100644
--- a/clang/include/clang/Basic/Diagnostic.td
+++ b/clang/include/clang/Basic/Diagnostic.td
@@ -155,17 +155,17 @@ class DefaultWarnNoWerror {
 }
 class DefaultRemark { Severity DefaultSeverity = SEV_Remark; }
 
-// C++ compatibility warnings
+// C++ compatibility warnings.
 multiclass CXXCompat<
     string message,
-    bit default_ignore,
     int std_ver,
+    bit ext_warn = true,
     string std_ver_override = ""#std_ver> {
     // 'X is a C++YZ extension'.
     def compat_pre_cxx#std_ver#_#NAME :
         Diagnostic<!strconcat(message, " a C++", std_ver_override,  " 
extension"),
                    CLASS_EXTENSION,
-                   !if(default_ignore, SEV_Ignored, SEV_Warning)>,
+                   !if(ext_warn, SEV_Warning, SEV_Ignored)>,
         InGroup<!cast<DiagGroup>("CXX"#std_ver)>;
 
     // 'X is incompatible with C++98' (if std_ver == 11).
@@ -180,23 +180,23 @@ multiclass CXXCompat<
         DefaultIgnore;
 }
 
-multiclass CXX11Compat<string message, bit default_ignore = false>
-    : CXXCompat<message, default_ignore, 11>;
+multiclass CXX11Compat<string message, bit ext_warn = true>
+    : CXXCompat<message, 11, ext_warn>;
 
-multiclass CXX14Compat<string message, bit default_ignore = false>
-    : CXXCompat<message, default_ignore, 14>;
+multiclass CXX14Compat<string message, bit ext_warn = true>
+    : CXXCompat<message, 14, ext_warn>;
 
-multiclass CXX17Compat<string message, bit default_ignore = false>
-    : CXXCompat<message, default_ignore, 17>;
+multiclass CXX17Compat<string message, bit ext_warn = true>
+    : CXXCompat<message, 17, ext_warn>;
 
-multiclass CXX20Compat<string message, bit default_ignore = false>
-    : CXXCompat<message, default_ignore, 20>;
+multiclass CXX20Compat<string message, bit ext_warn = true>
+    : CXXCompat<message, 20, ext_warn>;
 
-multiclass CXX23Compat<string message, bit default_ignore = false>
-    : CXXCompat<message, default_ignore, 23>;
+multiclass CXX23Compat<string message, bit ext_warn = true>
+    : CXXCompat<message, 23, ext_warn>;
 
-multiclass CXX26Compat<string message, bit default_ignore = false>
-    : CXXCompat<message, default_ignore, 26, "2c">;
+multiclass CXX26Compat<string message, bit ext_warn = true>
+    : CXXCompat<message, 26, ext_warn, "2c">;
 
 // Definitions for Diagnostics.
 include "DiagnosticASTKinds.td"
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f5dfd0cfa419d..eed06657536f4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -62,9 +62,7 @@ defm decomp_decl_cond : CXX26Compat<"structured binding 
declaration in a conditi
 // Compatibility warnings duplicated across multiple language versions.
 foreach std = [14, 20, 23] in {
   defm constexpr_body_invalid_stmt : CXXCompat<
-    "use of this statement in a constexpr %select{function|constructor}0 is",
-    /*default_ignore=*/false,
-    std>;
+    "use of this statement in a constexpr %select{function|constructor}0 is", 
std>;
 }
 
 def note_previous_decl : Note<"%0 declared here">;

>From 5143d71867b8f6a0095b621d60df5d876b6c8adf Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Thu, 20 Mar 2025 02:25:41 +0100
Subject: [PATCH 6/7] These are short enough to fit on one line now

---
 clang/include/clang/Basic/Diagnostic.td | 23 ++++++-----------------
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/clang/include/clang/Basic/Diagnostic.td 
b/clang/include/clang/Basic/Diagnostic.td
index f18aeee996f97..c3d3631f04530 100644
--- a/clang/include/clang/Basic/Diagnostic.td
+++ b/clang/include/clang/Basic/Diagnostic.td
@@ -180,23 +180,12 @@ multiclass CXXCompat<
         DefaultIgnore;
 }
 
-multiclass CXX11Compat<string message, bit ext_warn = true>
-    : CXXCompat<message, 11, ext_warn>;
-
-multiclass CXX14Compat<string message, bit ext_warn = true>
-    : CXXCompat<message, 14, ext_warn>;
-
-multiclass CXX17Compat<string message, bit ext_warn = true>
-    : CXXCompat<message, 17, ext_warn>;
-
-multiclass CXX20Compat<string message, bit ext_warn = true>
-    : CXXCompat<message, 20, ext_warn>;
-
-multiclass CXX23Compat<string message, bit ext_warn = true>
-    : CXXCompat<message, 23, ext_warn>;
-
-multiclass CXX26Compat<string message, bit ext_warn = true>
-    : CXXCompat<message, 26, ext_warn, "2c">;
+multiclass CXX11Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 11, ext_warn>;
+multiclass CXX14Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 14, ext_warn>;
+multiclass CXX17Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 17, ext_warn>;
+multiclass CXX20Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 20, ext_warn>;
+multiclass CXX23Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 23, ext_warn>;
+multiclass CXX26Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 26, ext_warn, "2c">;
 
 // Definitions for Diagnostics.
 include "DiagnosticASTKinds.td"

>From 895924e59d5367fde100938483496424720fe8f9 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Thu, 20 Mar 2025 17:51:28 +0100
Subject: [PATCH 7/7] Add comment

---
 clang/include/clang/Basic/Diagnostic.td | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/clang/include/clang/Basic/Diagnostic.td 
b/clang/include/clang/Basic/Diagnostic.td
index c3d3631f04530..b31d846210a8e 100644
--- a/clang/include/clang/Basic/Diagnostic.td
+++ b/clang/include/clang/Basic/Diagnostic.td
@@ -180,6 +180,23 @@ multiclass CXXCompat<
         DefaultIgnore;
 }
 
+// These generate pairs of C++ compatibility warnings of the form:
+//
+//    - compat_cxx<std>_<name>
+//    - compat_pre_cxx<std>_<name>
+//
+// The 'compat_cxx...' warning is intended to be issued in C++<std> mode,
+// and the 'compat_pre_cxx...' warning in C++ modes before C++<std>.
+//
+// Example:
+//
+//   defm inline_variable : CXX17Compat<"inline variables are">;
+//
+// This generates two warnings:
+//
+//   - compat_cxx17_inline_variable:     'inline variables are incompatible 
with C++ standards before C++17'
+//   - compat_pre_cxx17_inline_variable: 'inline variables are a C++17 
extension'
+//
 multiclass CXX11Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 11, ext_warn>;
 multiclass CXX14Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 14, ext_warn>;
 multiclass CXX17Compat<string message, bit ext_warn = true> : 
CXXCompat<message, 17, ext_warn>;

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

Reply via email to