[clang] [Clang] Use Compat diagnostics for most extension/compatibility warnings (PR #216693)
Nikolas Klauser via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 2 07:59:01 PDT 2026
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/216693
>From ab53f7b82e8162d3100be46a4406baf8a63f405e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 17 Aug 2026 11:34:53 +0200
Subject: [PATCH 1/3] [Clang] Use Compat diagnostics for most
extension/compatibility warnings
---
.../clang/Basic/DiagnosticCommonKinds.td | 16 +-
.../include/clang/Basic/DiagnosticLexKinds.td | 36 +-
.../clang/Basic/DiagnosticParseKinds.td | 332 +++++-------------
.../clang/Basic/DiagnosticSemaKinds.td | 104 ++----
clang/include/clang/Lex/Lexer.h | 2 +
clang/include/clang/Lex/Preprocessor.h | 9 +
clang/lib/Lex/Lexer.cpp | 9 +-
clang/lib/Lex/PPDirectives.cpp | 22 +-
clang/lib/Lex/PPExpressions.cpp | 13 +-
clang/lib/Parse/ParseCXXInlineMethods.cpp | 18 +-
clang/lib/Parse/ParseDecl.cpp | 39 +-
clang/lib/Parse/ParseDeclCXX.cpp | 88 ++---
clang/lib/Parse/ParseExpr.cpp | 17 +-
clang/lib/Parse/ParseExprCXX.cpp | 27 +-
clang/lib/Parse/ParseObjc.cpp | 2 +-
clang/lib/Parse/ParseOpenMP.cpp | 2 +-
clang/lib/Parse/ParseStmt.cpp | 42 +--
clang/lib/Parse/ParseTemplate.cpp | 16 +-
clang/lib/Parse/Parser.cpp | 8 +-
clang/lib/Sema/SemaDeclCXX.cpp | 24 +-
clang/lib/Sema/SemaExpr.cpp | 17 +-
clang/lib/Sema/SemaLambda.cpp | 16 +-
clang/lib/Sema/SemaStmt.cpp | 4 +-
clang/lib/Sema/SemaTemplate.cpp | 14 +-
clang/lib/Sema/SemaTemplateVariadic.cpp | 4 +-
clang/lib/Sema/SemaType.cpp | 8 +-
.../basic.lookup.qual/namespace.qual/p2.cpp | 6 +-
clang/test/CXX/drs/cwg0xx.cpp | 10 +-
clang/test/CXX/drs/cwg4xx.cpp | 6 +-
clang/test/CXX/stmt.stmt/stmt.select/p3.cpp | 12 +-
clang/test/Lexer/cxx2c-raw-strings.cpp | 8 +-
clang/test/Parser/cxx0x-in-cxx98.cpp | 2 +-
.../test/Parser/cxx0x-lambda-expressions.cpp | 2 +-
.../Parser/cxx11-user-defined-literals.cpp | 2 +-
.../cxx1z-nested-namespace-definition.cpp | 2 +-
clang/test/Sema/static-assert.c | 2 +-
clang/test/SemaCXX/cxx98-compat.cpp | 4 +-
clang/test/SemaCXX/static-assert-ext.cpp | 4 +-
38 files changed, 277 insertions(+), 672 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index 192fdf9299eb4..2c9ad1d324f28 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -11,6 +11,11 @@
//===----------------------------------------------------------------------===//
let Component = "Common" in {
+// C++11 compatibility with C++98.
+defm variadic_templates : CXX11Compat<"variadic templates are">;
+
+// C++23 compatibility with C++20 and earlier.
+defm size_t_suffix : CXX23Compat<"'size_t' suffix for literals is">;
// Substitutions.
@@ -91,11 +96,6 @@ def warn_method_param_declaration : Warning<"redeclaration of method parameter %
def err_invalid_storage_class_in_func_decl : Error<
"invalid storage class specifier in function declarator">;
def err_expected_namespace_name : Error<"expected namespace name">;
-def ext_variadic_templates : ExtWarn<
- "variadic templates are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_variadic_templates :
- Warning<"variadic templates are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_default_special_members : Error<
"only special member functions %select{|and comparison operators }0"
"may be defaulted">;
@@ -223,12 +223,6 @@ def ext_cxx11_longlong : Extension<
def warn_cxx98_compat_longlong : Warning<
"'long long' is incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def ext_cxx23_size_t_suffix : ExtWarn<
- "'size_t' suffix for literals is a C++23 extension">,
- InGroup<CXX23>;
-def warn_cxx20_compat_size_t_suffix : Warning<
- "'size_t' suffix for literals is incompatible with C++ standards before "
- "C++23">, InGroup<CXXPre23Compat>, DefaultIgnore;
def err_cxx23_size_t_suffix: Error<
"'size_t' suffix for literals is a C++23 feature">;
def err_size_t_literal_too_large: Error<
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index f0791ed486a74..bb2800e0cdbc1 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -11,6 +11,17 @@
//===----------------------------------------------------------------------===//
let Component = "Lex", CategoryName = "Lexical or Preprocessor Issue" in {
+// C23 compatibility with C17 and earlier.
+defm c23_pp_directive : C23Compat<
+ "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive is", /*ext_warn*/true>;
+
+// C++23 compatibility with C++20 and earlier.
+defm cxx23_pp_directive : CXX23Compat<
+ "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive is">;
+
+// C++26 compatibility with C++23 and earlier.
+defm raw_string_literal_character_set : CXX26Compat<
+ " '%0' in a raw string literal delimiter is", /*ext_warn*/false>;
def null_in_char_or_string : Warning<
"null character(s) preserved in %select{char|string}0 literal">,
@@ -113,14 +124,6 @@ def warn_cxx98_compat_raw_string_literal : Warning<
"raw string literals are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx26_compat_raw_string_literal_character_set : Warning<
- " '%0' in a raw string literal delimiter is incompatible "
- "with standards before C++2c">,
- InGroup<CXXPre26Compat>, DefaultIgnore;
-def ext_cxx26_raw_string_literal_character_set : Extension<
- " '%0' in a raw string literal delimiter is a C++2c extension">,
- InGroup<CXX26>, DefaultIgnore;
-
def warn_multichar_character_literal : Warning<
"multi-character character constant">, InGroup<MultiChar>;
def warn_four_char_character_literal : Warning<
@@ -836,23 +839,6 @@ def warn_cxx98_compat_pp_line_too_big : Warning<
"#line number greater than 32767 is incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def warn_c23_compat_pp_directive : Warning<
- "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive "
- "is incompatible with C standards before C23">,
- InGroup<CPre23Compat>, DefaultIgnore;
-def ext_c23_pp_directive : ExtWarn<
- "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive "
- "is a C23 extension">,
- InGroup<C23>;
-def warn_cxx23_compat_pp_directive : Warning<
- "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive "
- "is incompatible with C++ standards before C++23">,
- InGroup<CXXPre23Compat>, DefaultIgnore;
-def ext_cxx23_pp_directive : ExtWarn<
- "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive "
- "is a C++23 extension">,
- InGroup<CXX23>;
-
def err_pp_visibility_non_macro : Error<"no macro named %0">;
def err_pp_arc_cf_code_audited_syntax : Error<"expected 'begin' or 'end'">;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 6a48d74079f4e..60ba00e431208 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -12,15 +12,93 @@
let Component = "Parse" in {
let CategoryName = "Parse Issue" in {
-// C2y compatibility with C89.
+// C23 compatibility with C17 and earlier.
+defm c_label_at_end_of_compound_statement : C23Compat<
+ "label at end of compound statement is", /*ext_warn*/true>;
+defm c_static_assert_no_message : C23Compat<
+ "'_Static_assert' with no message is", /*ext_warn*/true>;
+defm c23_attributes : C23Compat<"[[]] attributes are">;
+defm c_enum_fixed_underlying_type : C23Compat<
+ "enumeration types with a fixed underlying type are">;
+defm label_followed_by_declaration : C23Compat<
+ "label followed by a declaration is">;
+
+// C2y compatibility with C23 and earlier.
defm decl_statement : C2yCompat<"'%select{if|switch}0' declaration statements are">;
+defm generic_with_type_arg : C2yCompat<
+ "passing a type argument as the first operand to '_Generic' is">;
// C++11 compatibility with C++98.
-defm enum_fixed_underlying_type : CXX11Compat<
+defm cxx_enum_fixed_underlying_type : CXX11Compat<
"enumeration types with a fixed underlying type are",
/*ext_warn=*/false>;
+defm for_range : CXX11Compat<"range-based for loop is">;
+defm scoped_enum : CXX11Compat<"scoped enumerations are">;
+defm rvalue_reference : CXX11Compat<"rvalue references are">;
+defm ref_qualifier : CXX11Compat<"reference qualifiers on functions are">;
+defm generalized_initializer_lists : CXX11Compat<
+ "generalized initializer lists are">;
+defm cxx11_attributes : CXX11Compat<"[[]] attributes are", /*ext_warn*/false>;
+defm defaulted_deleted_function : CXX11Compat<
+ "%select{defaulted|deleted}0 function definitions are">;
+defm nonstatic_member_init : CXX11Compat<
+ "default member initializer for non-static data member is">;
+defm alias_declaration : CXX11Compat<"alias declarations are">;
+defm override_control_keyword : CXX11Compat<"'%0' keyword is">;
+defm inline_namespace : CXX11Compat<"inline namespaces are">;
+
+// C++14 compatibility with C++11 and earlier.
+defm decltype_auto_type_specifier : CXX14Compat<
+ "'decltype(auto)' type specifier is">;
}
+// C++17 compatibility with C++14 and earlier.
+defm cxx_static_assert_no_message : CXX17Compat<
+ "'static_assert' with no message is">;
+defm constexpr_if : CXX17Compat<"constexpr if is">;
+defm init_statement : CXX17Compat<
+ "'%select{if|switch}0' initialization statements are">;
+defm ns_enum_attribute : CXX17Compat<
+ "attributes on %select{a namespace|an enumerator}0 declaration are",
+ /*ext_warn*/false>;
+defm using_attribute_ns : CXX17Compat<
+ "default scope specifier for attributes is">;
+defm template_template_param_typename : CXX17Compat<
+ "template template parameter using 'typename' is">;
+defm fold_expression : CXX17Compat<"pack fold expression is">;
+defm multi_using_declaration : CXX17Compat<
+ "use of multiple declarators in a single using declaration is">;
+defm using_declaration_pack : CXX17Compat<
+ "pack expansion of using declaration is">;
+defm constexpr_on_lambda : CXX17Compat<"'constexpr' on lambda expressions is">;
+
+// C++20 compatibility with C++17 and earlier.
+defm using_enum_declaration : CXX20Compat<"using enum declaration is">;
+defm for_range_init_stmt : CXX20Compat<
+ "range-based for loop initialization statements are">;
+defm explicit_bool : CXX20Compat<"explicit(bool) is">;
+defm bitfield_member_init : CXX20Compat<
+ "default member initializer for bit-field is">;
+defm lambda_template_parameter_list : CXX20Compat<
+ "explicit template parameter list for lambdas is">;
+
+// C++23 compatibility with C++20 and earlier.
+defm cxx_label_at_end_of_compound_statement : CXX23Compat<
+ "label at end of compound statement is">;
+defm alias_in_init_statement : CXX23Compat<
+ "alias declaration in this context is">;
+defm consteval_if : CXX23Compat<"consteval if is">;
+defm static_lambda : CXX23Compat<"static lambdas are">;
+
+// C++26 compatibility with C++23 and earlier.
+defm static_assert_user_generated_message : CXX26Compat<
+ "'static_assert' with a user-generated message is">;
+defm attrs_on_binding : CXX26Compat<
+ "an attribute specifier sequence attached to a structured binding declaration is">;
+defm delete_with_message : CXX26Compat<"'= delete' with a message is", /*ext_warn*/false>;
+defm variadic_friends : CXX26Compat<"variadic 'friend' declarations are">;
+defm binding_pack : CXX26Compat<"structured binding packs are">;
+
def err_asm_qualifier_ignored : Error<
"expected 'volatile', 'inline', 'goto', or '('">, CatInlineAsm;
def err_global_asm_qualifier_ignored : Error<
@@ -122,12 +200,6 @@ def ext_ms_c_enum_fixed_underlying_type : Extension<
def ext_ms_c_empty_enum_type : Extension<
"empty enumeration types are a Microsoft extension">,
InGroup<MicrosoftEmptyEnum>;
-def ext_c23_enum_fixed_underlying_type : Extension<
- "enumeration types with a fixed underlying type are a C23 extension">,
- InGroup<C23>;
-def warn_c17_compat_enum_fixed_underlying_type : Warning<
- "enumeration types with a fixed underlying type are incompatible with C standards before C23">,
- DefaultIgnore, InGroup<CPre23Compat>;
def ext_enum_base_in_type_specifier : ExtWarn<
"non-defining declaration of enumeration with a fixed underlying type is "
"only permitted as a standalone declaration"
@@ -138,11 +210,6 @@ def ext_elaborated_enum_class : ExtWarn<
InGroup<DiagGroup<"elaborated-enum-class">>, DefaultError;
def err_scoped_enum_missing_identifier : Error<
"scoped enumeration requires a name">;
-def ext_scoped_enum : ExtWarn<
- "scoped enumerations are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_scoped_enum : Warning<
- "scoped enumerations are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_anonymous_enum_bitfield : Error<
"ISO C++ only allows ':' in member enumeration declaration to introduce "
"a fixed underlying type, not an anonymous bit-field">;
@@ -166,12 +233,6 @@ def err_duplicate_default_assoc : Error<
"duplicate default generic association">;
def note_previous_default_assoc : Note<
"previous default generic association is here">;
-def ext_c2y_generic_with_type_arg : Extension<
- "passing a type argument as the first operand to '_Generic' is a C2y "
- "extension">, InGroup<C2y>;
-def warn_c2y_compat_generic_with_type_arg : Warning<
- "passing a type argument as the first operand to '_Generic' is incompatible "
- "with C standards before C2y">, InGroup<CPre2yCompat>, DefaultIgnore;
def ext_c99_feature : Extension<
"'%0' is a C99 extension">, InGroup<C99>;
@@ -334,24 +395,6 @@ def note_missing_selector_name : Note<
def note_force_empty_selector_name : Note<
"or insert whitespace before ':' to use %0 as parameter name "
"and have an empty entry in the selector">;
-def ext_c_label_followed_by_declaration : ExtWarn<
- "label followed by a declaration is a C23 extension">,
- InGroup<C23>;
-def warn_c23_compat_label_followed_by_declaration : Warning<
- "label followed by a declaration is incompatible with C standards before "
- "C23">, InGroup<CPre23Compat>, DefaultIgnore;
-def ext_c_label_end_of_compound_statement : ExtWarn<
- "label at end of compound statement is a C23 extension">,
- InGroup<C23>;
-def ext_cxx_label_end_of_compound_statement : ExtWarn<
- "label at end of compound statement is a C++23 extension">,
- InGroup<CXX23>;
-def warn_c23_compat_label_end_of_compound_statement : Warning<
- "label at end of compound statement is incompatible with C standards before C23">,
- InGroup<CPre23Compat>, DefaultIgnore;
-def warn_cxx20_compat_label_end_of_compound_statement : Warning<
- "label at end of compound statement is incompatible with C++ standards before C++23">,
- InGroup<CXXPre23Compat>, DefaultIgnore;
def err_address_of_label_outside_fn : Error<
"use of address-of-label extension outside of a function body">;
def err_asm_operand_wide_string_literal : Error<
@@ -378,27 +421,6 @@ def err_invalid_reference_qualifier_application : Error<
"'%0' qualifier may not be applied to a reference">;
def err_illegal_decl_reference_to_reference : Error<
"%0 declared as a reference to a reference">;
-def ext_rvalue_reference : ExtWarn<
- "rvalue references are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_rvalue_reference : Warning<
- "rvalue references are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_ref_qualifier : ExtWarn<
- "reference qualifiers on functions are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_ref_qualifier : Warning<
- "reference qualifiers on functions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_inline_namespace : ExtWarn<
- "inline namespaces are a C++11 feature">, InGroup<CXX11InlineNamespace>;
-def warn_cxx98_compat_inline_namespace : Warning<
- "inline namespaces are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_generalized_initializer_lists : ExtWarn<
- "generalized initializer lists are a C++11 extension">,
- InGroup<CXX11>;
-def warn_cxx98_compat_generalized_initializer_lists : Warning<
- "generalized initializer lists are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_init_list_bin_op : Error<"initializer list cannot be used on the "
"%select{left|right}0 hand side of operator '%1'">;
def warn_cxx98_compat_trailing_return_type : Warning<
@@ -413,19 +435,9 @@ def err_requires_clause_inside_parens : Error<
def ext_auto_storage_class : ExtWarn<
"'auto' storage class specifier is not permitted in C++11, and will not "
"be supported in future releases">, InGroup<DiagGroup<"auto-storage-class">>;
-def ext_decltype_auto_type_specifier : ExtWarn<
- "'decltype(auto)' type specifier is a C++14 extension">, InGroup<CXX14>;
-def warn_cxx11_compat_decltype_auto_type_specifier : Warning<
- "'decltype(auto)' type specifier is incompatible with C++ standards before "
- "C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
def ext_auto_type : Extension<
"'__auto_type' is a GNU extension">,
InGroup<GNUAutoType>;
-def ext_for_range : ExtWarn<
- "range-based for loop is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_for_range : Warning<
- "range-based for loop is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_for_range_identifier : Error<
"%select{range-based for loop|expansion statement}0 requires "
"type for %select{loop|expansion}0 variable">;
@@ -503,24 +515,6 @@ def err_bool_redeclaration : Error<
def warn_cxx98_compat_static_assert : Warning<
"'static_assert' declarations are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
-def ext_cxx_static_assert_no_message : ExtWarn<
- "'static_assert' with no message is a C++17 extension">, InGroup<CXX17>;
-def ext_c_static_assert_no_message : ExtWarn<
- "'_Static_assert' with no message is a C23 extension">, InGroup<C23>;
-def warn_cxx14_compat_static_assert_no_message : Warning<
- "'static_assert' with no message is incompatible with C++ standards before "
- "C++17">,
- DefaultIgnore, InGroup<CXXPre17Compat>;
-def warn_c17_compat_static_assert_no_message : Warning<
- "'_Static_assert' with no message is incompatible with C standards before "
- "C23">,
- DefaultIgnore, InGroup<CPre23Compat>;
-def ext_cxx_static_assert_user_generated_message : ExtWarn<
- "'static_assert' with a user-generated message is a C++26 extension">,
- InGroup<CXX26>;
-def warn_cxx20_compat_static_assert_user_generated_message : Warning<
- "'static_assert' with a user-generated message is incompatible with "
- "C++ standards before C++26">, DefaultIgnore, InGroup<CXXPre26Compat>;
def err_function_definition_not_allowed : Error<
"function definition is not allowed here">;
def err_expected_end_of_enumerator : Error<
@@ -535,15 +529,6 @@ def ext_decomp_decl_empty : ExtWarn<
def err_function_parameter_limit_exceeded : Error<
"too many function parameters; subsequent parameters will be ignored">;
-// C++26 structured bindings
-def ext_decl_attrs_on_binding : ExtWarn<
- "an attribute specifier sequence attached to a structured binding declaration "
- "is a C++2c extension">, InGroup<CXX26>;
-def warn_cxx23_compat_decl_attrs_on_binding : Warning<
- "an attribute specifier sequence attached to a structured binding declaration "
- "is incompatible with C++ standards before C++2c">,
- InGroup<CXXPre26Compat>, DefaultIgnore;
-
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
"method type specifier must start with '-' or '+'">;
@@ -645,12 +630,6 @@ def err_expected_init_in_condition_lparen : Error<
"variable declaration in condition cannot have a parenthesized initializer">;
def err_extraneous_rparen_in_condition : Error<
"extraneous ')' after condition, expected a statement">;
-def ext_alias_in_init_statement : ExtWarn<
- "alias declaration in this context is a C++23 extension">,
- InGroup<CXX23>;
-def warn_cxx20_alias_in_init_statement : Warning<
- "alias declaration in this context is incompatible with C++ standards before C++23">,
- DefaultIgnore, InGroup<CXXPre23Compat>;
def warn_dangling_else : Warning<
"add explicit braces to avoid dangling else">,
InGroup<DanglingElse>;
@@ -682,12 +661,6 @@ def warn_cxx98_compat_noexcept_decl : Warning<
def err_expected_catch : Error<"expected catch">;
def err_using_namespace_in_class : Error<
"'using namespace' is not allowed in classes">;
-def warn_cxx17_compat_using_enum_declaration : Warning<
- "using enum declaration is incompatible with C++ standards before C++20">,
- InGroup<CXXPre20Compat>, DefaultIgnore;
-def ext_using_enum_declaration : ExtWarn<
- "using enum declaration is a C++20 extension">,
- InGroup<CXX20>;
def err_using_enum_expect_identifier : Error<
"using enum %select{requires an enum or typedef name|"
"does not permit an elaborated enum specifier}0">;
@@ -726,30 +699,7 @@ def err_function_is_not_record : Error<
"unexpected %0 in function call; perhaps remove the %0?">;
def err_super_in_using_declaration : Error<
"'__super' cannot be used with a using declaration">;
-def ext_constexpr_if : ExtWarn<
- "constexpr if is a C++17 extension">, InGroup<CXX17>;
-def warn_cxx14_compat_constexpr_if : Warning<
- "constexpr if is incompatible with C++ standards before C++17">,
- DefaultIgnore, InGroup<CXXPre17Compat>;
-def ext_consteval_if : ExtWarn<
- "consteval if is a C++23 extension">,
- InGroup<CXX23>;
-def warn_cxx20_compat_consteval_if : Warning<
- "consteval if is incompatible with C++ standards before C++23">,
- InGroup<CXXPre23Compat>, DefaultIgnore;
-def ext_init_statement : ExtWarn<
- "'%select{if|switch}0' initialization statements are a C++17 extension">,
- InGroup<CXX17>;
-def warn_cxx14_compat_init_statement : Warning<
- "%select{if|switch}0 initialization statements are incompatible with "
- "C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>;
-def ext_for_range_init_stmt : ExtWarn<
- "range-based for loop initialization statements are a C++20 extension">,
- InGroup<CXX20>;
-def warn_cxx17_compat_for_range_init_stmt : Warning<
- "range-based for loop initialization statements are incompatible with "
- "C++ standards before C++20">, DefaultIgnore, InGroup<CXXPre20Compat>;
def warn_empty_init_statement : Warning<
"empty initialization statement of '%select{if|switch|range-based for}0' "
"has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore;
@@ -789,39 +739,14 @@ def ext_c_nullptr : Extension<
def warn_wrong_clang_attr_namespace : Warning<
"'__clang__' is a predefined macro name, not an attribute scope specifier; "
"did you mean '_Clang' instead?">, InGroup<IgnoredAttributes>;
-def ext_ns_enum_attribute : Extension<
- "attributes on %select{a namespace|an enumerator}0 declaration are "
- "a C++17 extension">, InGroup<CXX17>;
-def warn_cxx14_compat_ns_enum_attribute : Warning<
- "attributes on %select{a namespace|an enumerator}0 declaration are "
- "incompatible with C++ standards before C++17">,
- InGroup<CXXPre17CompatPedantic>, DefaultIgnore;
def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
-def warn_cxx98_compat_attribute : Warning<
- "[[]] attributes are incompatible with C++ standards before C++11">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def warn_ext_cxx11_attributes : Extension<
- "[[]] attributes are a C++11 extension">,
- InGroup<CXX11>;
-def warn_pre_c23_compat_attributes : Warning<
- "[[]] attributes are incompatible with C standards before C23">,
- DefaultIgnore, InGroup<CPre23Compat>;
-def warn_ext_c23_attributes : Extension<
- "[[]] attributes are a C23 extension">,
- InGroup<C23>;
def err_cxx11_attribute_forbids_arguments : Error<
"attribute %0 cannot have an argument list">;
def err_attribute_requires_arguments : Error<
"parentheses must be omitted if %0 attribute's argument list is empty">;
def err_cxx11_attribute_forbids_ellipsis : Error<
"attribute %0 cannot be used as an attribute pack">;
-def warn_cxx14_compat_using_attribute_ns : Warning<
- "default scope specifier for attributes is incompatible with C++ standards "
- "before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore;
-def ext_using_attribute_ns : ExtWarn<
- "default scope specifier for attributes is a C++17 extension">,
- InGroup<CXX17>;
def err_using_attribute_ns_conflict : Error<
"attribute with scope specifier cannot follow default scope specifier">;
def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
@@ -866,11 +791,6 @@ def err_assume_attr_expects_cond_expr : Error<
def warn_cxx20_compat_explicit_bool : Warning<
"this expression will be parsed as explicit(bool) in C++20">,
InGroup<CXX20Compat>, DefaultIgnore;
-def warn_cxx17_compat_explicit_bool : Warning<
- "explicit(bool) is incompatible with C++ standards before C++20">,
- InGroup<CXXPre20Compat>, DefaultIgnore;
-def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++20 extension">,
- InGroup<CXX20>;
/// C++ Templates
def err_expected_template : Error<"expected template">;
@@ -881,13 +801,6 @@ def err_expected_comma_greater : Error<
def err_class_on_template_template_param
: Error<"template template parameter requires 'class'%select{| or "
"'typename'}0 after the parameter list">;
-def ext_template_template_param_typename : ExtWarn<
- "template template parameter using 'typename' is a C++17 extension">,
- InGroup<CXX17>;
-def warn_cxx14_compat_template_template_param_typename : Warning<
- "template template parameter using 'typename' is "
- "incompatible with C++ standards before C++17">,
- InGroup<CXXPre17Compat>, DefaultIgnore;
def err_template_spec_syntax_non_template : Error<
"identifier followed by '<' indicates a class template specialization but "
"%0 %select{does not refer to a template|refers to a function template|"
@@ -994,12 +907,6 @@ def err_default_template_template_parameter_not_template : Error<
"default template argument for a template template parameter must be a class "
"template">;
-def ext_fold_expression : ExtWarn<
- "pack fold expression is a C++17 extension">,
- InGroup<CXX17>;
-def warn_cxx14_compat_fold_expression : Warning<
- "pack fold expression is incompatible with C++ standards before C++17">,
- InGroup<CXXPre17Compat>, DefaultIgnore;
def err_expected_fold_operator : Error<
"expected a foldable binary operator in fold expression">;
def err_fold_operator_mismatch : Error<
@@ -1016,52 +923,16 @@ def err_missing_whitespace_digraph : Error<
"%select{template name|addrspace_cast|const_cast|dynamic_cast|reinterpret_cast|static_cast}0"
" which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?">;
-def ext_defaulted_deleted_function : ExtWarn<
- "%select{defaulted|deleted}0 function definitions are a C++11 extension">,
- InGroup<CXX11>;
-def warn_cxx98_compat_defaulted_deleted_function : Warning<
- "%select{defaulted|deleted}0 function definitions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
-def ext_delete_with_message : Extension<
- "'= delete' with a message is a C++2c extension">, InGroup<CXX26>;
-def warn_cxx23_delete_with_message : Warning<
- "'= delete' with a message is incompatible with C++ standards before C++2c">,
- DefaultIgnore, InGroup<CXXPre26Compat>;
-
-def ext_variadic_friends : ExtWarn<
- "variadic 'friend' declarations are a C++2c extension">, InGroup<CXX26>;
-def warn_cxx23_variadic_friends : Warning<
- "variadic 'friend' declarations are incompatible with C++ standards before C++2c">,
- DefaultIgnore, InGroup<CXXPre26Compat>;
-
def err_friend_concept : Error<
"friend declaration cannot be a concept">;
// C++11 default member initialization
-def ext_nonstatic_member_init : ExtWarn<
- "default member initializer for non-static data member is a C++11 "
- "extension">, InGroup<CXX11>;
-def warn_cxx98_compat_nonstatic_member_init : Warning<
- "default member initializer for non-static data members is incompatible with "
- "C++98">, InGroup<CXX98Compat>, DefaultIgnore;
-def ext_bitfield_member_init: ExtWarn<
- "default member initializer for bit-field is a C++20 extension">,
- InGroup<CXX20>;
-def warn_cxx17_compat_bitfield_member_init: Warning<
- "default member initializer for bit-field is incompatible with "
- "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_anon_bitfield_member_init : Error<
"anonymous bit-field cannot have a default member initializer">;
def err_incomplete_array_member_init: Error<
"array bound cannot be deduced from a default member initializer">;
// C++11 alias-declaration
-def ext_alias_declaration : ExtWarn<
- "alias declarations are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_alias_declaration : Warning<
- "alias declarations are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_alias_declaration_not_identifier : Error<
"name defined in alias declaration must be an identifier">;
def err_alias_declaration_specialization : Error<
@@ -1069,26 +940,7 @@ def err_alias_declaration_specialization : Error<
def err_alias_declaration_pack_expansion : Error<
"alias declaration cannot be a pack expansion">;
-// C++17 using-declaration pack expansions
-def ext_multi_using_declaration : ExtWarn<
- "use of multiple declarators in a single using declaration is "
- "a C++17 extension">, InGroup<CXX17>;
-def warn_cxx17_compat_multi_using_declaration : Warning<
- "use of multiple declarators in a single using declaration is "
- "incompatible with C++ standards before C++17">,
- InGroup<CXXPre17Compat>, DefaultIgnore;
-def ext_using_declaration_pack : ExtWarn<
- "pack expansion of using declaration is a C++17 extension">, InGroup<CXX17>;
-def warn_cxx17_compat_using_declaration_pack : Warning<
- "pack expansion using declaration is incompatible with C++ standards "
- "before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore;
-
// C++11 override control
-def ext_override_control_keyword : ExtWarn<
- "'%0' keyword is a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_override_control_keyword : Warning<
- "'%0' keyword is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_override_control_interface : Error<
"'%0' keyword not permitted with interface types">;
def ext_ms_sealed_keyword : ExtWarn<
@@ -1144,12 +996,6 @@ def err_binding_multiple_ellipses : Error<
"multiple packs in structured binding declaration">;
def note_previous_ellipsis : Note<
"previous binding pack specified here">;
-def ext_cxx_binding_pack : ExtWarn<
- "structured binding packs are a C++2c extension ">,
- InGroup<CXX26>;
-def warn_cxx23_compat_binding_pack : Warning<
- "structured binding packs are incompatible with C++ standards before C++2c">,
- InGroup<CXXPre26Compat>, DefaultIgnore;
def err_capture_default_first : Error<
"capture default must be first">;
def ext_decl_attrs_on_lambda : ExtWarn<
@@ -1167,29 +1013,11 @@ def warn_cxx20_compat_decl_attrs_on_lambda : Warning<
def err_expected_star_this_capture : Error<
"expected 'this' following '*' in lambda capture list">;
-// C++17 constexpr lambda expressions
-def warn_cxx14_compat_constexpr_on_lambda : Warning<
- "constexpr on lambda expressions is incompatible with C++ standards before C++17">,
- InGroup<CXXPre17Compat>, DefaultIgnore;
-def ext_constexpr_on_lambda_cxx17 : ExtWarn<
- "'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>;
-
// C++20 template lambdas
-def ext_lambda_template_parameter_list: ExtWarn<
- "explicit template parameter list for lambdas is a C++20 extension">,
- InGroup<CXX20>;
-def warn_cxx17_compat_lambda_template_parameter_list: Warning<
- "explicit template parameter list for lambdas is incompatible with "
- "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_lambda_template_parameter_list_empty : Error<
"lambda template parameter list cannot be empty">;
// C++23 static lambdas
-def err_static_lambda: ExtWarn<
- "static lambdas are a C++23 extension">, InGroup<CXX23>;
-def warn_cxx20_compat_static_lambda : Warning<
- "static lambdas are incompatible with C++ standards before C++23">,
- InGroup<CXXPre23Compat>, DefaultIgnore;
def err_static_mutable_lambda : Error<
"lambda cannot be both mutable and static">;
def err_static_lambda_captures : Error<
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b314c17ad27bd..9b9b98ca5b5f0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -31,6 +31,13 @@ defm templ_default_in_function_templ : CXX11Compat<
defm template_arg_extra_parens : CXX11Compat<
"parentheses around address non-type template argument are">;
defm typename_outside_of_template : CXX11Compat<"'typename' outside of a template is">;
+defm template_arg_object_internal : CXX11Compat<
+ "non-type template argument referring to %select{function|object}0 %1 with "
+ "internal linkage is">;
+defm template_outside_of_template : CXX11Compat<
+ "use of 'template' keyword outside of a template is">;
+defm explicit_conversion_functions : CXX11Compat<
+ "explicit conversion functions are">;
// C++14 compatibility with C++11 and earlier.
defm constexpr_type_definition : CXX14Compat<
@@ -40,10 +47,14 @@ defm constexpr_local_var : CXX14Compat<
defm constexpr_body_multiple_return : CXX14Compat<
"multiple return statements in constexpr function is">;
defm variable_template : CXX14Compat<"variable templates are">;
+defm init_capture : CXX14Compat<"initialized lambda captures are">;
// C++17 compatibility with C++14 and earlier.
defm decomp_decl : CXX17Compat<"structured binding declarations are">;
defm inline_variable : CXX17Compat<"inline variables are">;
+defm for_range_begin_end_types_differ : CXX17Compat<
+ "'begin' and 'end' returning different types (%0 and %1) is">;
+defm star_this_lambda_capture : CXX17Compat<"by value capture of '*this' is">;
// C++20 compatibility with C++17 and earlier.
defm decomp_decl_spec
@@ -63,17 +74,27 @@ defm ctad_for_alias_templates
: CXX20Compat<"class template argument deduction for alias templates is">;
defm implicit_typename
: CXX20Compat<"missing 'typename' prior to dependent type name %0 is">;
-
defm auto_param : CXX20Compat<"'auto' parameters are">;
+defm using_decl_scoped_enumerator : CXX20Compat<
+ "using declaration naming a scoped enumerator is">;
+defm init_capture_pack : CXX20Compat<"initialized lambda capture packs are">;
+defm equals_this_lambda_capture : CXX20Compat<
+ "explicit capture of 'this' with a capture default of '=' is">;
+defm capture_binding : CXX20Compat<"captured structured bindings are">;
+defm defaulted_comparison : CXX20Compat<"defaulted comparison operators are">;
// C++23 compatibility with C++20 and earlier.
defm constexpr_static_var : CXX23Compat<
"definition of a %select{static|thread_local}1 variable "
"in a constexpr %select{function|constructor}0 "
"is">;
+defm operator_overload_static : CXX23Compat<
+ "declaring overloaded %0 as 'static' is">;
// C++26 compatibility with C++23 and earlier.
defm decomp_decl_cond : CXX26Compat<"structured binding declaration in a condition is">;
+defm pack_indexing : CXX26Compat<"pack indexing is">;
+defm placeholder_var_definition : CXX26Compat<"placeholder variables are">;
// Compatibility warnings duplicated across multiple language versions.
foreach std = [14, 20, 23] in {
@@ -715,12 +736,6 @@ def err_using_decl_can_not_refer_to_namespace : Error<
"using declaration cannot refer to a namespace">;
def note_namespace_using_decl : Note<
"did you mean 'using namespace'?">;
-def warn_cxx17_compat_using_decl_scoped_enumerator: Warning<
- "using declaration naming a scoped enumerator is incompatible with "
- "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
-def ext_using_decl_scoped_enumerator : ExtWarn<
- "using declaration naming a scoped enumerator is a C++20 extension">,
- InGroup<CXX20>;
def err_using_decl_constructor : Error<
"using declaration cannot refer to a constructor">;
def warn_cxx98_compat_using_decl_constructor : Warning<
@@ -2970,12 +2985,6 @@ def err_for_range_incomplete_type : Error<
"cannot use incomplete type %0 as a range">;
def err_for_range_iter_deduction_failure : Error<
"cannot use type %0 as an iterator">;
-def ext_for_range_begin_end_types_differ : ExtWarn<
- "'begin' and 'end' returning different types (%0 and %1) is a C++17 extension">,
- InGroup<CXX17>;
-def warn_for_range_begin_end_types_differ : Warning<
- "'begin' and 'end' returning different types (%0 and %1) is incompatible "
- "with C++ standards before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore;
def note_in_for_range: Note<
"when looking up '%select{begin|end}0' function for range expression "
"of type %1">;
@@ -5789,13 +5798,6 @@ def err_template_arg_method : Error<
def err_template_arg_object_no_linkage : Error<
"non-type template argument refers to %select{function|object}0 %1 that "
"does not have linkage">;
-def warn_cxx98_compat_template_arg_object_internal : Warning<
- "non-type template argument referring to %select{function|object}0 %1 with "
- "internal linkage is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-def ext_template_arg_object_internal : ExtWarn<
- "non-type template argument referring to %select{function|object}0 %1 with "
- "internal linkage is a C++11 extension">, InGroup<CXX11>;
def err_template_arg_thread_local : Error<
"non-type template argument refers to thread-local object">;
def note_template_arg_internal_object : Note<
@@ -6245,11 +6247,6 @@ def note_referenced_type_template : Note<
"%select{class|type alias}0 template declared here">;
def err_template_kw_missing
: Error<"missing 'template' keyword prior to dependent template name %0">;
-def ext_template_outside_of_template : ExtWarn<
- "'template' keyword outside of a template">, InGroup<CXX11>;
-def warn_cxx98_compat_template_outside_of_template : Warning<
- "use of 'template' keyword outside of a template is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def err_non_type_template_in_nested_name_specifier : Error<
"qualified name refers into a specialization of %select{function|variable}0 "
@@ -6320,12 +6317,6 @@ def err_expected_name_of_pack : Error<
def err_pack_index_out_of_bound : Error<
"invalid index %0 for pack %1 of size %2">;
-def ext_pack_indexing : ExtWarn<
- "pack indexing is a C++2c extension">, InGroup<CXX26>;
-def warn_cxx23_pack_indexing : Warning<
- "pack indexing is incompatible with C++ standards before C++2c">,
- DefaultIgnore, InGroup<CXXPre26Compat>;
-
def err_pack_outside_template : Error<
"pack declaration outside of template">;
@@ -7533,11 +7524,6 @@ def err_using_placeholder_variable : Error<
"ambiguous reference to placeholder '_', which is defined multiple times">;
def note_reference_placeholder : Note<
"placeholder declared here">;
-def ext_placeholder_var_definition : ExtWarn<
- "placeholder variables are a C++2c extension">, InGroup<CXX26>;
-def warn_cxx23_placeholder_var_definition : Warning<
- "placeholder variables are incompatible with C++ standards before C++2c">,
- DefaultIgnore, InGroup<CXXPre26Compat>;
def ext_sizeof_alignof_function_type : Extension<
"invalid application of '%0' to a function type">, InGroup<PointerArith>;
@@ -8969,11 +8955,6 @@ let CategoryName = "Lambda Issue" in {
"%select{| explicitly}1 captured here">;
// C++14 lambda init-captures.
- def warn_cxx11_compat_init_capture : Warning<
- "initialized lambda captures are incompatible with C++ standards "
- "before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore;
- def ext_init_capture : ExtWarn<
- "initialized lambda captures are a C++14 extension">, InGroup<CXX14>;
def err_init_capture_no_expression : Error<
"initializer missing for lambda capture %0">;
def err_init_capture_multiple_expressions : Error<
@@ -8985,11 +8966,6 @@ let CategoryName = "Lambda Issue" in {
"cannot deduce type for lambda capture %0 from initializer of type %2">;
def err_init_capture_deduction_failure_from_init_list : Error<
"cannot deduce type for lambda capture %0 from initializer list">;
- def warn_cxx17_compat_init_capture_pack : Warning<
- "initialized lambda capture packs are incompatible with C++ standards "
- "before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
- def ext_init_capture_pack : ExtWarn<
- "initialized lambda pack captures are a C++20 extension">, InGroup<CXX20>;
// C++14 generic lambdas.
def warn_cxx11_compat_generic_lambda : Warning<
@@ -8998,24 +8974,11 @@ let CategoryName = "Lambda Issue" in {
def err_lambda_explicit_temp_spec : Error<
"a member of a lambda should not be explicitly %select{specialized|instantiated}0">;
- // C++17 '*this' captures.
- def warn_cxx14_compat_star_this_lambda_capture : Warning<
- "by value capture of '*this' is incompatible with C++ standards before C++17">,
- InGroup<CXXPre17Compat>, DefaultIgnore;
- def ext_star_this_lambda_capture_cxx17 : ExtWarn<
- "capture of '*this' by copy is a C++17 extension">, InGroup<CXX17>;
-
// C++17 parameter shadows capture
def err_parameter_shadow_capture : Error<
"a lambda parameter cannot shadow an explicitly captured entity">;
// C++20 [=, this] captures.
- def warn_cxx17_compat_equals_this_lambda_capture : Warning<
- "explicit capture of 'this' with a capture default of '=' is incompatible "
- "with C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
- def ext_equals_this_lambda_capture_cxx20 : ExtWarn<
- "explicit capture of 'this' with a capture default of '=' "
- "is a C++20 extension">, InGroup<CXX20>;
def warn_deprecated_this_capture : Warning<
"implicit capture of 'this' with a capture default of '=' is deprecated">,
InGroup<DeprecatedThisCapture>;
@@ -10331,12 +10294,6 @@ def err_local_nested_class_invalid_scope : Error<
"nested local class %0 must be defined in the same block scope as %1">;
def err_capture_binding_openmp : Error<
"capturing a structured binding is not yet supported in OpenMP">;
-def ext_capture_binding : ExtWarn<
- "captured structured bindings are a C++20 extension">, InGroup<CXX20>;
-def warn_cxx17_compat_capture_binding : Warning<
- "captured structured bindings are incompatible with "
- "C++ standards before C++20">,
- InGroup<CXXPre20Compat>, DefaultIgnore;
def err_static_data_member_not_allowed_in_local_class : Error<
"static data member %0 not allowed in local %sub{select_tag_type_kind}2 %1">;
@@ -10388,11 +10345,6 @@ def err_operator_overload_needs_class_or_enum : Error<
"or enumeration type">;
def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
-def warn_cxx20_compat_operator_overload_static : Warning<
- "declaring overloaded %0 as 'static' is incompatible with C++ standards "
- "before C++23">, InGroup<CXXPre23Compat>, DefaultIgnore;
-def ext_operator_overload_static : ExtWarn<
- "declaring overloaded %0 as 'static' is a C++23 extension">, InGroup<CXX23>;
def err_operator_overload_static : Error<
"overloaded %0 cannot be a static member function">;
def err_operator_overload_default_arg : Error<
@@ -10535,13 +10487,6 @@ def warn_conv_to_void_not_used : Warning<
def warn_not_compound_assign : Warning<
"use of unary operator that may be intended as compound assignment (%0=)">;
-// C++11 explicit conversion operators
-def ext_explicit_conversion_functions : ExtWarn<
- "explicit conversion functions are a C++11 extension">, InGroup<CXX11>;
-def warn_cxx98_compat_explicit_conversion_functions : Warning<
- "explicit conversion functions are incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
-
// C++11 defaulted functions
def err_defaulted_special_member_params : Error<
"an explicitly-defaulted %sub{select_special_member_kind}0 cannot "
@@ -10603,11 +10548,6 @@ def note_vbase_moved_here : Note<
def select_defaulted_comparison_kind : TextSubstitution<
"%select{<ERROR>|equality|three-way|equality|relational}0 comparison "
"operator">;
-def ext_defaulted_comparison : ExtWarn<
- "defaulted comparison operators are a C++20 extension">, InGroup<CXX20>;
-def warn_cxx17_compat_defaulted_comparison : Warning<
- "defaulted comparison operators are incompatible with C++ standards "
- "before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_defaulted_comparison_template : Error<
"comparison operator template cannot be defaulted">;
def err_defaulted_comparison_num_args : Error<
diff --git a/clang/include/clang/Lex/Lexer.h b/clang/include/clang/Lex/Lexer.h
index b042e5fb088fa..92bd25888a7b6 100644
--- a/clang/include/clang/Lex/Lexer.h
+++ b/clang/include/clang/Lex/Lexer.h
@@ -294,6 +294,8 @@ class Lexer : public PreprocessorLexer {
/// position in the current buffer into a SourceLocation object for rendering.
DiagnosticBuilder Diag(const char *Loc, unsigned DiagID) const;
+ DiagnosticBuilder DiagCompat(const char *Loc, unsigned CompatDiagId) const;
+
/// getSourceLocation - Return a source location identifier for the specified
/// offset in the current file.
SourceLocation getSourceLocation(const char *Loc, unsigned TokLen = 1) const;
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index e752010dd2062..cf2acaa0168d0 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -2162,6 +2162,15 @@ class Preprocessor {
return Diags->Report(Tok.getLocation(), DiagID);
}
+ DiagnosticBuilder DiagCompat(SourceLocation Loc,
+ unsigned CompatDiagID) const {
+ return Diag(Loc, DiagnosticIDs::getCompatDiagId(LangOpts, CompatDiagID));
+ }
+
+ DiagnosticBuilder DiagCompat(const Token &Tok, unsigned CompatDiagID) const {
+ return Diag(Tok, DiagnosticIDs::getCompatDiagId(LangOpts, CompatDiagID));
+ }
+
/// Return the 'spelling' of the token at the given
/// location; does not go up to the spelling location or down to the
/// expansion location.
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 37e33861c4470..46d61b1826633 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -1284,6 +1284,11 @@ DiagnosticBuilder Lexer::Diag(const char *Loc, unsigned DiagID) const {
return PP->Diag(getSourceLocation(Loc), DiagID);
}
+DiagnosticBuilder Lexer::DiagCompat(const char *Loc,
+ unsigned CompatDiagId) const {
+ return Diag(Loc, DiagnosticIDs::getCompatDiagId(LangOpts, CompatDiagId));
+}
+
//===----------------------------------------------------------------------===//
// Trigraph and Escaped Newline Handling Code.
//===----------------------------------------------------------------------===//
@@ -2391,9 +2396,7 @@ bool Lexer::LexRawStringLiteral(Token &Result, const char *CurPtr,
if (!isLexingRawMode() &&
llvm::is_contained({'$', '@', '`'}, CurPtr[PrefixLen])) {
const char *Pos = &CurPtr[PrefixLen];
- Diag(Pos, LangOpts.CPlusPlus26
- ? diag::warn_cxx26_compat_raw_string_literal_character_set
- : diag::ext_cxx26_raw_string_literal_character_set)
+ DiagCompat(Pos, diag_compat::raw_string_literal_character_set)
<< StringRef(Pos, 1);
}
++PrefixLen;
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index ec387a4d582fc..e7e01873213dc 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -882,14 +882,9 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
// Warn if using `#elifdef` & `#elifndef` in not C23 & C++23 mode even
// if this branch is in a skipping block.
- unsigned DiagID;
- if (LangOpts.CPlusPlus)
- DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
- : diag::ext_cxx23_pp_directive;
- else
- DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
- : diag::ext_c23_pp_directive;
- Diag(Tok, DiagID) << (IsElifDef ? PED_Elifdef : PED_Elifndef);
+ unsigned DiagID = LangOpts.CPlusPlus ? diag_compat::cxx23_pp_directive
+ : diag_compat::c23_pp_directive;
+ DiagCompat(Tok, DiagID) << (IsElifDef ? PED_Elifdef : PED_Elifndef);
// If this is a #elif with a #else before it, report the error.
if (CondInfo.FoundElse)
@@ -3698,14 +3693,9 @@ void Preprocessor::HandleElifFamilyDirective(Token &ElifToken,
switch (DirKind) {
case PED_Elifdef:
case PED_Elifndef:
- unsigned DiagID;
- if (LangOpts.CPlusPlus)
- DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive
- : diag::ext_cxx23_pp_directive;
- else
- DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive
- : diag::ext_c23_pp_directive;
- Diag(ElifToken, DiagID) << DirKind;
+ DiagCompat(ElifToken, LangOpts.CPlusPlus ? diag_compat::cxx23_pp_directive
+ : diag_compat::c23_pp_directive)
+ << DirKind;
break;
default:
break;
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index 1040b83e8745d..eb614cba959a4 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -328,12 +328,13 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
}
// 'z/uz' literals are a C++23 feature.
- if (Literal.isSizeT)
- PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus
- ? PP.getLangOpts().CPlusPlus23
- ? diag::warn_cxx20_compat_size_t_suffix
- : diag::ext_cxx23_size_t_suffix
- : diag::err_cxx23_size_t_suffix);
+ if (Literal.isSizeT) {
+ if (PP.getLangOpts().CPlusPlus) {
+ PP.DiagCompat(PeekTok, diag_compat::size_t_suffix);
+ } else {
+ PP.Diag(PeekTok, diag::err_cxx23_size_t_suffix);
+ }
+ }
// 'wb/uwb' literals are a C23 feature.
// '__wb/__uwb' are a C++ extension.
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 3f101feb26a6d..8612cfe119edf 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -32,9 +32,7 @@ StringLiteral *Parser::ParseCXXDeletedFunctionMessage() {
ExprResult Res = ParseUnevaluatedStringLiteralExpression();
if (Res.isUsable()) {
Message = Res.getAs<StringLiteral>();
- Diag(Message->getBeginLoc(), getLangOpts().CPlusPlus26
- ? diag::warn_cxx23_delete_with_message
- : diag::ext_delete_with_message)
+ DiagCompat(Message->getBeginLoc(), diag_compat::delete_with_message)
<< Message->getSourceRange();
}
} else {
@@ -102,10 +100,8 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
bool Delete = false;
SourceLocation KWLoc;
if (TryConsumeToken(tok::kw_delete, KWLoc)) {
- Diag(KWLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_defaulted_deleted_function
- : diag::ext_defaulted_deleted_function)
- << 1 /* deleted */;
+ DiagCompat(KWLoc, diag_compat::defaulted_deleted_function)
+ << 1 /* deleted */;
StringLiteral *Message = ParseCXXDeletedFunctionMessage();
Actions.SetDeclDeleted(FnD, KWLoc, Message);
Delete = true;
@@ -113,10 +109,8 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
DeclAsFunction->setRangeEnd(PrevTokLocation);
}
} else if (TryConsumeToken(tok::kw_default, KWLoc)) {
- Diag(KWLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_defaulted_deleted_function
- : diag::ext_defaulted_deleted_function)
- << 0 /* defaulted */;
+ DiagCompat(KWLoc, diag_compat::defaulted_deleted_function)
+ << 0 /* defaulted */;
Actions.SetDeclDefaulted(FnD, KWLoc);
if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {
DeclAsFunction->setRangeEnd(PrevTokLocation);
@@ -434,7 +428,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
ExprResult DefArgResult;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
DefArgResult = ParseBraceInitializer();
} else
DefArgResult = ParseAssignmentExpression();
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 2bbc76fc7c4df..2c52a517b09b3 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -441,7 +441,7 @@ bool Parser::ParseAttributeArgumentList(
if (ArgsProperties.isStringLiteralArg(Arg)) {
Expr = ParseUnevaluatedStringInAttribute(AttrName);
} else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
Expr = ParseBraceInitializer();
} else {
Expr = ParseAssignmentExpression();
@@ -2727,7 +2727,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
}
case InitKind::CXXBraced: {
// Parse C++0x braced-init-list.
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
InitializerScopeRAII InitScope(*this, D, ThisDecl);
@@ -4224,9 +4224,7 @@ void Parser::ParseDeclarationSpecifiers(
ConsumeToken(); // kw_explicit
if (Tok.is(tok::l_paren)) {
if (getLangOpts().CPlusPlus20 || isExplicitBool() == TPResult::True) {
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus20
- ? diag::warn_cxx17_compat_explicit_bool
- : diag::ext_explicit_bool);
+ DiagCompat(Tok.getLocation(), diag_compat::explicit_bool);
ExprResult ExplicitExpr(static_cast<Expr *>(nullptr));
BalancedDelimiterTracker Tracker(*this, tok::l_paren);
@@ -5072,8 +5070,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// In C++11, recognize 'enum class' and 'enum struct'.
if (Tok.isOneOf(tok::kw_class, tok::kw_struct) && getLangOpts().CPlusPlus) {
- Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum
- : diag::ext_scoped_enum);
+ DiagCompat(Tok, diag_compat::scoped_enum);
IsScopedUsingClassTag = Tok.is(tok::kw_class);
ScopedEnumKWLoc = ConsumeToken();
@@ -5224,15 +5221,13 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
if (!getLangOpts().ObjC) {
if (getLangOpts().CPlusPlus)
- DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
+ DiagCompat(ColonLoc, diag_compat::cxx_enum_fixed_underlying_type)
<< BaseRange;
else if (getLangOpts().MicrosoftExt && !getLangOpts().C23)
Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
<< BaseRange;
else
- Diag(ColonLoc, getLangOpts().C23
- ? diag::warn_c17_compat_enum_fixed_underlying_type
- : diag::ext_c23_enum_fixed_underlying_type)
+ DiagCompat(ColonLoc, diag_compat::c_enum_fixed_underlying_type)
<< BaseRange;
}
}
@@ -5480,9 +5475,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl,
MaybeParseGNUAttributes(attrs);
if (isAllowedCXX11AttributeSpecifier()) {
if (getLangOpts().CPlusPlus)
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
- ? diag::warn_cxx14_compat_ns_enum_attribute
- : diag::ext_ns_enum_attribute)
+ DiagCompat(Tok.getLocation(), diag_compat::ns_enum_attribute)
<< 1 /*enumerator*/;
ParseCXX11Attributes(attrs);
}
@@ -6599,9 +6592,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
// Complain about rvalue references in C++03, but then go on and build
// the declarator.
if (Kind == tok::ampamp)
- Diag(Loc, getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_rvalue_reference :
- diag::ext_rvalue_reference);
+ DiagCompat(Loc, diag_compat::rvalue_reference);
// GNU-style and C++11 attributes are allowed here, as is restrict.
ParseTypeQualifierListOpt(DS);
@@ -7080,8 +7071,7 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) {
SourceLocation EllipsisLoc;
if (Tok.is(tok::ellipsis)) {
- Diag(Tok, getLangOpts().CPlusPlus26 ? diag::warn_cxx23_compat_binding_pack
- : diag::ext_cxx_binding_pack);
+ DiagCompat(Tok, diag_compat::binding_pack);
if (PrevEllipsisLoc.isValid()) {
Diag(Tok, diag::err_binding_multiple_ellipses);
Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
@@ -7111,9 +7101,7 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) {
ParsedAttributes Attrs(AttrFactory);
if (isCXX11AttributeSpecifier() !=
CXX11AttributeKind::NotAttributeSpecifier) {
- Diag(Tok, getLangOpts().CPlusPlus26
- ? diag::warn_cxx23_compat_decl_attrs_on_binding
- : diag::ext_decl_attrs_on_binding);
+ DiagCompat(Tok, diag_compat::attrs_on_binding);
MaybeParseCXX11Attributes(Attrs);
}
@@ -7481,10 +7469,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
bool Parser::ParseRefQualifier(bool &RefQualifierIsLValueRef,
SourceLocation &RefQualifierLoc) {
if (Tok.isOneOf(tok::amp, tok::ampamp)) {
- Diag(Tok, getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_ref_qualifier :
- diag::ext_ref_qualifier);
-
+ DiagCompat(Tok, diag_compat::ref_qualifier);
RefQualifierIsLValueRef = Tok.is(tok::amp);
RefQualifierLoc = ConsumeToken();
return true;
@@ -7775,7 +7760,7 @@ void Parser::ParseParameterDeclarationClause(
ExprResult DefArgResult;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
DefArgResult = ParseBraceInitializer();
} else {
if (Tok.is(tok::l_paren) && NextToken().is(tok::l_brace)) {
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index a3617c3db49c4..b88dd0e2912c0 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -57,9 +57,7 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
while (MaybeParseGNUAttributes(attrs) || isAllowedCXX11AttributeSpecifier()) {
if (isAllowedCXX11AttributeSpecifier()) {
if (getLangOpts().CPlusPlus11)
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
- ? diag::warn_cxx14_compat_ns_enum_attribute
- : diag::ext_ns_enum_attribute)
+ DiagCompat(Tok.getLocation(), diag_compat::ns_enum_attribute)
<< 0 /*namespace*/;
ParseCXX11Attributes(attrs);
}
@@ -194,9 +192,7 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
// If we're still good, complain about inline namespaces in non-C++0x now.
if (InlineLoc.isValid())
- Diag(InlineLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_inline_namespace
- : diag::ext_inline_namespace);
+ DiagCompat(InlineLoc, diag_compat::inline_namespace);
// Enter a scope for the namespace.
ParseScope NamespaceScope(this, Scope::DeclScope);
@@ -608,9 +604,7 @@ bool Parser::ParseUsingDeclarator(DeclaratorContext Context,
}
if (TryConsumeToken(tok::ellipsis, D.EllipsisLoc))
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
- ? diag::warn_cxx17_compat_using_declaration_pack
- : diag::ext_using_declaration_pack);
+ DiagCompat(Tok.getLocation(), diag_compat::using_declaration_pack);
return false;
}
@@ -625,10 +619,7 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
if (TryConsumeToken(tok::kw_enum, UELoc) && !InInitStatement) {
// C++20 using-enum
- Diag(UELoc, getLangOpts().CPlusPlus20
- ? diag::warn_cxx17_compat_using_enum_declaration
- : diag::ext_using_enum_declaration);
-
+ DiagCompat(UELoc, diag_compat::using_enum_declaration);
DiagnoseCXX11AttributeExtension(PrefixAttrs);
if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate) {
@@ -819,10 +810,7 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
}
if (DeclsInGroup.size() > 1)
- Diag(Tok.getLocation(),
- getLangOpts().CPlusPlus17
- ? diag::warn_cxx17_compat_multi_using_declaration
- : diag::ext_multi_using_declaration);
+ DiagCompat(Tok.getLocation(), diag_compat::multi_using_declaration);
// Eat ';'.
DeclEnd = Tok.getLocation();
@@ -844,9 +832,7 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator(
return nullptr;
}
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_alias_declaration
- : diag::ext_alias_declaration);
+ DiagCompat(Tok.getLocation(), diag_compat::alias_declaration);
// Type alias templates cannot be specialized.
int SpecKind = -1;
@@ -959,17 +945,11 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
ExprResult AssertMessage;
if (Tok.is(tok::r_paren)) {
- unsigned DiagVal;
- if (getLangOpts().CPlusPlus17)
- DiagVal = diag::warn_cxx14_compat_static_assert_no_message;
- else if (getLangOpts().CPlusPlus)
- DiagVal = diag::ext_cxx_static_assert_no_message;
- else if (getLangOpts().C23)
- DiagVal = diag::warn_c17_compat_static_assert_no_message;
- else
- DiagVal = diag::ext_c_static_assert_no_message;
- Diag(Tok, DiagVal) << getStaticAssertNoMessageFixIt(AssertExpr.get(),
- Tok.getLocation());
+ auto diag = getLangOpts().CPlusPlus
+ ? diag_compat::cxx_static_assert_no_message
+ : diag_compat::c_static_assert_no_message;
+ DiagCompat(Tok, diag) << getStaticAssertNoMessageFixIt(AssertExpr.get(),
+ Tok.getLocation());
} else {
if (ExpectAndConsume(tok::comma)) {
SkipUntil(tok::semi);
@@ -992,10 +972,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
if (ParseAsExpression) {
AssertMessage = ParseConstantExpressionInExprEvalContext();
if (Tok.is(tok::r_paren)) {
- Diag(Tok,
- getLangOpts().CPlusPlus26
- ? diag::warn_cxx20_compat_static_assert_user_generated_message
- : diag::ext_cxx_static_assert_user_generated_message);
+ DiagCompat(Tok, diag_compat::static_assert_user_generated_message);
} else {
T.consumeClose();
return nullptr;
@@ -1062,10 +1039,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
if (Tok.is(tok::kw_auto) && NextToken().is(tok::r_paren)) {
// the typename-specifier in a function-style cast expression may
// be 'auto' since C++23.
- Diag(Tok.getLocation(),
- getLangOpts().CPlusPlus14
- ? diag::warn_cxx11_compat_decltype_auto_type_specifier
- : diag::ext_decltype_auto_type_specifier);
+ DiagCompat(Tok.getLocation(), diag_compat::decltype_auto_type_specifier);
ConsumeToken();
} else {
// Parse the expression
@@ -2470,10 +2444,7 @@ void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
} else if (Specifier == VirtSpecifiers::VS_GNU_Final) {
Diag(Tok.getLocation(), diag::ext_warn_gnu_final);
} else {
- Diag(Tok.getLocation(),
- getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_override_control_keyword
- : diag::ext_override_control_keyword)
+ DiagCompat(Tok.getLocation(), diag_compat::override_control_keyword)
<< VirtSpecifiers::getSpecifierName(Specifier);
}
ConsumeToken();
@@ -2869,9 +2840,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
// Handle C++26's variadic friend declarations. These don't even have
// declarators, so we get them out of the way early here.
if (DS.isFriendSpecifiedFirst() && Tok.isOneOf(tok::comma, tok::ellipsis)) {
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus26
- ? diag::warn_cxx23_variadic_friends
- : diag::ext_variadic_friends);
+ DiagCompat(Tok.getLocation(), diag_compat::variadic_friends);
SourceLocation FriendLoc = DS.getFriendSpecLoc();
SmallVector<Decl *> Decls;
@@ -3094,9 +3063,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
TemplateInfo.Kind == ParsedTemplateKind::NonTemplate) {
// It's a default member initializer.
if (BitfieldSize.get())
- Diag(Tok, getLangOpts().CPlusPlus20
- ? diag::warn_cxx17_compat_bitfield_member_init
- : diag::ext_bitfield_member_init);
+ DiagCompat(Tok, diag_compat::bitfield_member_init);
HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit;
} else {
HasStaticInitializer = true;
@@ -3160,9 +3127,7 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
// Handle the initializer.
if (HasInClassInit != ICIS_NoInit) {
// The initializer was deferred; parse it and cache the tokens.
- Diag(Tok, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_nonstatic_member_init
- : diag::ext_nonstatic_member_init);
+ DiagCompat(Tok, diag_compat::nonstatic_member_init);
if (DeclaratorInfo.isArrayOfUnknownBound()) {
// C++11 [dcl.array]p3: An array bound may also be omitted when the
@@ -3587,9 +3552,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
Diag(FinalLoc, diag::err_override_control_interface)
<< VirtSpecifiers::getSpecifierName(Specifier);
else if (Specifier == VirtSpecifiers::VS_Final)
- Diag(FinalLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_override_control_keyword
- : diag::ext_override_control_keyword)
+ DiagCompat(FinalLoc, diag_compat::override_control_keyword)
<< VirtSpecifiers::getSpecifierName(Specifier);
else if (Specifier == VirtSpecifiers::VS_Sealed)
Diag(FinalLoc, diag::ext_ms_sealed_keyword);
@@ -3864,7 +3827,7 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
// Parse the '('.
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
// FIXME: Add support for signature help inside initializer lists.
ExprResult InitList = ParseBraceInitializer();
@@ -4605,13 +4568,8 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
"Not a double square bracket attribute list");
SourceLocation OpenLoc = Tok.getLocation();
- if (getLangOpts().CPlusPlus) {
- Diag(OpenLoc, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_attribute
- : diag::warn_ext_cxx11_attributes);
- } else {
- Diag(OpenLoc, getLangOpts().C23 ? diag::warn_pre_c23_compat_attributes
- : diag::warn_ext_c23_attributes);
- }
+ DiagCompat(OpenLoc, getLangOpts().CPlusPlus ? diag_compat::cxx11_attributes
+ : diag_compat::c23_attributes);
ConsumeBracket();
checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);
@@ -4620,9 +4578,7 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
SourceLocation CommonScopeLoc;
IdentifierInfo *CommonScopeName = nullptr;
if (Tok.is(tok::kw_using)) {
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
- ? diag::warn_cxx14_compat_using_attribute_ns
- : diag::ext_using_attribute_ns);
+ DiagCompat(Tok.getLocation(), diag_compat::using_attribute_ns);
ConsumeToken();
CommonScopeName = TryParseCXX11AttributeIdentifier(
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 87cd7a01451cf..cfc7c199cbdb5 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -525,8 +525,8 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
if (!RHS.isInvalid() && RHSIsInitList) {
if (ThisPrec == prec::Assignment) {
- Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists)
- << Actions.getExprRange(RHS.get());
+ Diag(OpToken, diag::compat_cxx11_generalized_initializer_lists)
+ << Actions.getExprRange(RHS.get());
} else if (ColonLoc.isValid()) {
Diag(ColonLoc, diag::err_init_list_bin_op)
<< /*RHS*/1 << ":"
@@ -1386,7 +1386,7 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand,
<< DS.getSourceRange());
if (Tok.is(tok::l_brace))
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
Res = ParseCXXTypeConstructExpression(DS);
break;
@@ -1735,7 +1735,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (!getLangOpts().CPlusPlus23) {
ExprResult Idx;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
Idx = ParseBraceInitializer();
} else {
Idx = ParseExpression(); // May be a comma expression
@@ -3068,8 +3068,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
}
const auto *LIT = cast<LocInfoType>(ControllingType.get().get());
SourceLocation Loc = LIT->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
- Diag(Loc, getLangOpts().C2y ? diag::warn_c2y_compat_generic_with_type_arg
- : diag::ext_c2y_generic_with_type_arg);
+ DiagCompat(Loc, diag_compat::generic_with_type_arg);
} else {
// C11 6.5.1.1p3 "The controlling expression of a generic selection is
// not evaluated."
@@ -3178,9 +3177,7 @@ ExprResult Parser::ParseFoldExpression(ExprResult LHS,
}
}
- Diag(EllipsisLoc, getLangOpts().CPlusPlus17
- ? diag::warn_cxx14_compat_fold_expression
- : diag::ext_fold_expression);
+ DiagCompat(EllipsisLoc, diag_compat::fold_expression);
T.consumeClose();
return Actions.ActOnCXXFoldExpr(getCurScope(), T.getOpenLocation(), LHS.get(),
@@ -3224,7 +3221,7 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
ExprResult Expr;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
Expr = ParseBraceInitializer();
} else
Expr = ParseAssignmentExpression();
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index f9a0dcc7d53af..559d61549f658 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1130,9 +1130,7 @@ static void tryConsumeLambdaSpecifierToken(Parser &P,
static void addStaticToLambdaDeclSpecifier(Parser &P, SourceLocation StaticLoc,
DeclSpec &DS) {
if (StaticLoc.isValid()) {
- P.Diag(StaticLoc, !P.getLangOpts().CPlusPlus23
- ? diag::err_static_lambda
- : diag::warn_cxx20_compat_static_lambda);
+ P.DiagCompat(StaticLoc, diag_compat::static_lambda);
const char *PrevSpec = nullptr;
unsigned DiagID = 0;
DS.SetStorageClassSpec(P.getActions(), DeclSpec::SCS_static, StaticLoc,
@@ -1147,9 +1145,7 @@ static void
addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc,
DeclSpec &DS) {
if (ConstexprLoc.isValid()) {
- P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus17
- ? diag::ext_constexpr_on_lambda_cxx17
- : diag::warn_cxx14_compat_constexpr_on_lambda);
+ P.DiagCompat(ConstexprLoc, diag_compat::constexpr_on_lambda);
const char *PrevSpec = nullptr;
unsigned DiagID = 0;
DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, ConstexprLoc, PrevSpec,
@@ -1244,9 +1240,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
MultiParseScope TemplateParamScope(*this);
if (Tok.is(tok::less)) {
- Diag(Tok, getLangOpts().CPlusPlus20
- ? diag::warn_cxx17_compat_lambda_template_parameter_list
- : diag::ext_lambda_template_parameter_list);
+ DiagCompat(Tok, diag_compat::lambda_template_parameter_list);
SmallVector<NamedDecl*, 4> TemplateParams;
SourceLocation LAngleLoc, RAngleLoc;
@@ -1857,10 +1851,7 @@ Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
if (!DG)
return DG;
- Diag(DeclStart, !getLangOpts().CPlusPlus23
- ? diag::ext_alias_in_init_statement
- : diag::warn_cxx20_alias_in_init_statement)
- << SourceRange(DeclStart, DeclEnd);
+ DiagCompat(DeclStart, diag_compat::alias_in_init_statement);
return DG;
}
@@ -1903,9 +1894,7 @@ Sema::ConditionResult Parser::ParseCondition(StmtResult *InitStmt,
const auto WarnOnInit = [this, &CK] {
if (getLangOpts().CPlusPlus)
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
- ? diag::warn_cxx14_compat_init_statement
- : diag::ext_init_statement)
+ DiagCompat(Tok.getLocation(), diag_compat::init_statement)
<< (CK == Sema::ConditionKind::Switch);
else
DiagCompat(Tok.getLocation(), diag_compat::decl_statement)
@@ -2062,8 +2051,7 @@ Sema::ConditionResult Parser::ParseCondition(StmtResult *InitStmt,
ExprResult InitExpr = ExprError();
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok.getLocation(),
- diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok.getLocation(), diag::compat_cxx11_generalized_initializer_lists);
InitExpr = ParseBraceInitializer();
} else if (CopyInitialization) {
PreferredType.enterVariableInit(Tok.getLocation(), DeclOut);
@@ -3015,8 +3003,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
ConstructorRParen,
ConstructorArgs);
} else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) {
- Diag(Tok.getLocation(),
- diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok.getLocation(), diag::compat_cxx11_generalized_initializer_lists);
Initializer = ParseBraceInitializer();
}
if (Initializer.isInvalid())
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index d01b0abf917cb..8cb39da3c9d40 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -2881,7 +2881,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
ExprResult Expr;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
Expr = ParseBraceInitializer();
} else
Expr = ParseAssignmentExpression();
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 30b6c64e69f4c..102128b657cc9 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -389,7 +389,7 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
}
} else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
// Parse C++0x braced-init-list.
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
ExprResult Init(ParseBraceInitializer());
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 219bcd980e860..78d0648c7b4d9 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -713,10 +713,8 @@ static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt) {
// label that is followed by a declaration rather than a statement.
if (!P.getLangOpts().CPlusPlus && !P.getLangOpts().MicrosoftExt &&
isa<DeclStmt>(SubStmt)) {
- P.Diag(SubStmt->getBeginLoc(),
- P.getLangOpts().C23
- ? diag::warn_c23_compat_label_followed_by_declaration
- : diag::ext_c_label_followed_by_declaration);
+ P.DiagCompat(SubStmt->getBeginLoc(),
+ diag_compat::label_followed_by_declaration);
}
}
@@ -1086,15 +1084,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() {
}
void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
- if (getLangOpts().CPlusPlus) {
- Diag(Tok, getLangOpts().CPlusPlus23
- ? diag::warn_cxx20_compat_label_end_of_compound_statement
- : diag::ext_cxx_label_end_of_compound_statement);
- } else {
- Diag(Tok, getLangOpts().C23
- ? diag::warn_c23_compat_label_end_of_compound_statement
- : diag::ext_c_label_end_of_compound_statement);
- }
+ DiagCompat(Tok, getLangOpts().CPlusPlus
+ ? diag_compat::cxx_label_at_end_of_compound_statement
+ : diag_compat::c_label_at_end_of_compound_statement);
}
bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
@@ -1473,8 +1465,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
if (Tok.is(tok::kw_constexpr)) {
// C23 supports constexpr keyword, but only for object definitions.
if (getLangOpts().CPlusPlus) {
- Diag(Tok, getLangOpts().CPlusPlus17 ? diag::warn_cxx14_compat_constexpr_if
- : diag::ext_constexpr_if);
+ DiagCompat(Tok, diag_compat::constexpr_if);
IsConstexpr = true;
ConsumeToken();
}
@@ -1484,8 +1475,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
}
if (Tok.is(tok::kw_consteval)) {
- Diag(Tok, getLangOpts().CPlusPlus23 ? diag::warn_cxx20_compat_consteval_if
- : diag::ext_consteval_if);
+ DiagCompat(Tok, diag_compat::consteval_if);
IsConsteval = true;
ConstevalLoc = ConsumeToken();
} else if (Tok.is(tok::code_completion)) {
@@ -2128,9 +2118,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc,
MightBeForRangeStmt ? &ForRangeInfo : nullptr);
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
if (ForRangeInfo.ParsedForRangeDecl()) {
- Diag(ForRangeInfo.ColonLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_for_range
- : diag::ext_for_range);
+ DiagCompat(ForRangeInfo.ColonLoc, diag_compat::for_range);
ForRangeInfo.LoopVar = FirstPart;
FirstPart = StmtResult();
} else if (Tok.is(tok::semi)) { // for (int x = 4;
@@ -2229,11 +2217,9 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc,
/*MissingOK=*/true, MightBeForRangeStmt ? &ForRangeInfo : nullptr);
if (ForRangeInfo.ParsedForRangeDecl()) {
- Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
- : ForRangeInfo.ColonLoc,
- getLangOpts().CPlusPlus20
- ? diag::warn_cxx17_compat_for_range_init_stmt
- : diag::ext_for_range_init_stmt)
+ DiagCompat(FirstPart.get() ? FirstPart.get()->getBeginLoc()
+ : ForRangeInfo.ColonLoc,
+ diag_compat::for_range_init_stmt)
<< (FirstPart.get() ? FirstPart.get()->getSourceRange()
: SourceRange());
if (EmptyInitStmtSemiLoc.isValid()) {
@@ -2497,11 +2483,7 @@ StmtResult Parser::ParseReturnStatement() {
if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) {
R = ParseInitializer();
if (R.isUsable())
- Diag(R.get()->getBeginLoc(),
- getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_generalized_initializer_lists
- : diag::ext_generalized_initializer_lists)
- << R.get()->getSourceRange();
+ DiagCompat(R.get()->getBeginLoc(), diag_compat::generalized_initializer_lists);
} else
R = ParseExpression();
if (R.isInvalid()) {
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 735a9bd1f9f1c..34d3e69071d3b 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -625,10 +625,7 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
// Grab the ellipsis (if given).
SourceLocation EllipsisLoc;
if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {
- Diag(EllipsisLoc,
- getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_variadic_templates
- : diag::ext_variadic_templates);
+ DiagCompat(EllipsisLoc, diag_compat::variadic_templates);
}
// Grab the template parameter name (if given)
@@ -736,10 +733,8 @@ NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth,
if (Tok.is(tok::kw_typename)) {
TypenameKeyword = true;
Kind = TemplateNameKind::TNK_Type_template;
- Diag(Tok.getLocation(),
- getLangOpts().CPlusPlus17
- ? diag::warn_cxx14_compat_template_template_param_typename
- : diag::ext_template_template_param_typename)
+ DiagCompat(Tok.getLocation(),
+ diag_compat::template_template_param_typename)
<< (!getLangOpts().CPlusPlus17
? FixItHint::CreateReplacement(Tok.getLocation(), "class")
: FixItHint());
@@ -772,10 +767,7 @@ NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth,
// Parse the ellipsis, if given.
if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
- Diag(EllipsisLoc,
- getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_variadic_templates
- : diag::ext_variadic_templates);
+ DiagCompat(EllipsisLoc, diag_compat::variadic_templates);
// Get the identifier, if given.
NameLoc = Tok.getLocation();
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index d83b75072f844..da8d00edefcf5 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1301,17 +1301,13 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
if (TryConsumeToken(tok::kw_delete, KWLoc)) {
- Diag(KWLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_defaulted_deleted_function
- : diag::ext_defaulted_deleted_function)
+ DiagCompat(KWLoc, diag_compat::defaulted_deleted_function)
<< 1 /* deleted */;
BodyKind = Sema::FnBodyKind::Delete;
DeletedMessage = ParseCXXDeletedFunctionMessage();
D.SetRangeEnd(PrevTokLocation);
} else if (TryConsumeToken(tok::kw_default, KWLoc)) {
- Diag(KWLoc, getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_defaulted_deleted_function
- : diag::ext_defaulted_deleted_function)
+ DiagCompat(KWLoc, diag_compat::defaulted_deleted_function)
<< 0 /* defaulted */;
BodyKind = Sema::FnBodyKind::Default;
D.SetRangeEnd(PrevTokLocation);
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index dd95f9220bb9d..85ec63782802a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -748,9 +748,7 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old,
}
void Sema::DiagPlaceholderVariableDefinition(SourceLocation Loc) {
- Diag(Loc, getLangOpts().CPlusPlus26
- ? diag::warn_cxx23_placeholder_var_definition
- : diag::ext_placeholder_var_definition);
+ DiagCompat(Loc, diag_compat::placeholder_var_definition);
}
NamedDecl *
@@ -11609,10 +11607,8 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
// C++0x explicit conversion operators.
if (DS.hasExplicitSpecifier() && !getLangOpts().CPlusPlus20)
- Diag(DS.getExplicitSpecLoc(),
- getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_explicit_conversion_functions
- : diag::ext_explicit_conversion_functions)
+ DiagCompat(DS.getExplicitSpecLoc(),
+ diag_compat::explicit_conversion_functions)
<< SourceRange(DS.getExplicitSpecRange());
}
@@ -13664,10 +13660,7 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, bool HasTypename,
// A using-declaration shall not name a scoped enumerator.
// C++20 p1099 permits enumerators.
if (EC && R && ED->isScoped())
- Diag(SS.getBeginLoc(),
- getLangOpts().CPlusPlus20
- ? diag::warn_cxx17_compat_using_decl_scoped_enumerator
- : diag::ext_using_decl_scoped_enumerator)
+ DiagCompat(SS.getBeginLoc(), diag_compat::using_decl_scoped_enumerator)
<< SS.getRange();
// We want to consider the scope of the enumerator
@@ -17009,10 +17002,7 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {
if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(FnDecl)) {
if (MethodDecl->isStatic()) {
if (Op == OO_Call || Op == OO_Subscript)
- Diag(FnDecl->getLocation(),
- (LangOpts.CPlusPlus23
- ? diag::warn_cxx20_compat_operator_overload_static
- : diag::ext_operator_overload_static))
+ DiagCompat(FnDecl->getLocation(), diag_compat::operator_overload_static)
<< FnDecl;
else
return Diag(FnDecl->getLocation(), diag::err_operator_overload_static)
@@ -18776,9 +18766,7 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {
// 'operator<=>' when parsing the '<=>' token.
if (DefKind.isComparison() &&
DefKind.asComparison() != DefaultedComparisonKind::ThreeWay) {
- Diag(DefaultLoc, getLangOpts().CPlusPlus20
- ? diag::warn_cxx17_compat_defaulted_comparison
- : diag::ext_defaulted_comparison);
+ DiagCompat(DefaultLoc, diag_compat::defaulted_comparison);
}
FD->setDefaulted();
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f25829ae676dc..1e81767ea7ae9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4058,12 +4058,12 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
QualType Ty;
// 'z/uz' literals are a C++23 feature.
- if (Literal.isSizeT)
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus
- ? getLangOpts().CPlusPlus23
- ? diag::warn_cxx20_compat_size_t_suffix
- : diag::ext_cxx23_size_t_suffix
- : diag::err_cxx23_size_t_suffix);
+ if (Literal.isSizeT) {
+ if (getLangOpts().CPlusPlus)
+ DiagCompat(Tok.getLocation(), diag_compat::size_t_suffix);
+ else
+ Diag(Tok.getLocation(), diag::err_cxx23_size_t_suffix);
+ }
// 'wb/uwb' literals are a C23 feature. We support _BitInt as a type in C++,
// but we do not currently support the suffix in C++ mode because it's not
@@ -19497,10 +19497,7 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, ValueDecl *Var,
diagnoseUncapturableValueReferenceOrBinding(S, Loc, Var);
return false;
} else if (Diagnose && S.getLangOpts().CPlusPlus) {
- S.Diag(Loc, S.LangOpts.CPlusPlus20
- ? diag::warn_cxx17_compat_capture_binding
- : diag::ext_capture_binding)
- << Var;
+ S.DiagCompat(Loc, diag_compat::capture_binding) << Var;
S.Diag(Var->getLocation(), diag::note_entity_declared_at) << Var;
}
}
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index b97c6d8b95f62..a773f4bcfa11e 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -860,9 +860,7 @@ QualType Sema::buildLambdaInitCaptureInitialization(
}
if (EllipsisLoc.isValid()) {
if (Init->containsUnexpandedParameterPack()) {
- Diag(EllipsisLoc, getLangOpts().CPlusPlus20
- ? diag::warn_cxx17_compat_init_capture_pack
- : diag::ext_init_capture_pack);
+ DiagCompat(EllipsisLoc, diag_compat::init_capture_pack);
DeductType = Context.getPackExpansionType(DeductType, NumExpansions,
/*ExpectPackInType=*/false);
TLB.push<PackExpansionTypeLoc>(DeductType).setEllipsisLoc(EllipsisLoc);
@@ -1193,9 +1191,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
PrevCaptureLoc = C->Loc, ++C) {
if (C->Kind == LCK_This || C->Kind == LCK_StarThis) {
if (C->Kind == LCK_StarThis)
- Diag(C->Loc, !getLangOpts().CPlusPlus17
- ? diag::ext_star_this_lambda_capture_cxx17
- : diag::warn_cxx14_compat_star_this_lambda_capture);
+ DiagCompat(C->Loc, diag_compat::star_this_lambda_capture);
// C++11 [expr.prim.lambda]p8:
// An identifier or this shall not appear more than once in a
@@ -1214,9 +1210,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
// "&identifier", "this", or "* this". [ Note: The form [&,this] is
// redundant but accepted for compatibility with ISO C++14. --end note ]
if (Intro.Default == LCD_ByCopy && C->Kind != LCK_StarThis)
- Diag(C->Loc, !getLangOpts().CPlusPlus20
- ? diag::ext_equals_this_lambda_capture_cxx20
- : diag::warn_cxx17_compat_equals_this_lambda_capture);
+ DiagCompat(C->Loc, diag_compat::equals_this_lambda_capture);
// C++11 [expr.prim.lambda]p12:
// If this is captured by a local lambda expression, its nearest
@@ -1242,9 +1236,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
ValueDecl *Var = nullptr;
if (C->Init.isUsable()) {
- Diag(C->Loc, getLangOpts().CPlusPlus14
- ? diag::warn_cxx11_compat_init_capture
- : diag::ext_init_capture);
+ DiagCompat(C->Loc, diag_compat::init_capture);
// If the initializer expression is usable, but the InitCaptureType
// is not, then an error has occurred - so ignore the capture for now.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 1fde5a45977dd..331c1866e36ec 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2990,9 +2990,7 @@ StmtResult Sema::BuildCXXForRangeStmt(
SourceLocation RangeLoc = RangeVar->getLocation();
QualType BeginType = BeginVar->getType(), EndType = EndVar->getType();
if (!Context.hasSameType(BeginType, EndType)) {
- Diag(RangeLoc, getLangOpts().CPlusPlus17
- ? diag::warn_for_range_begin_end_types_differ
- : diag::ext_for_range_begin_end_types_differ)
+ DiagCompat(RangeLoc, diag_compat::for_range_begin_end_types_differ)
<< BeginType << EndType;
NoteForRangeBeginEndFunction(*this, BeginExpr, BEF_begin);
NoteForRangeBeginEndFunction(*this, EndExpr, BEF_end);
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 643392833759d..e897159c416c8 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5071,11 +5071,8 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S,
TemplateTy &Result,
bool AllowInjectedClassName) {
if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent())
- Diag(TemplateKWLoc,
- getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_template_outside_of_template :
- diag::ext_template_outside_of_template)
- << FixItHint::CreateRemoval(TemplateKWLoc);
+ DiagCompat(TemplateKWLoc, diag_compat::template_outside_of_template)
+ << FixItHint::CreateRemoval(TemplateKWLoc);
if (SS.isInvalid())
return TNK_Non_template;
@@ -6924,13 +6921,10 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
// Address / reference template args must have external linkage in C++98.
if (Entity->getFormalLinkage() == Linkage::Internal) {
- S.Diag(Arg->getBeginLoc(),
- S.getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_template_arg_object_internal
- : diag::ext_template_arg_object_internal)
+ S.DiagCompat(Arg->getBeginLoc(), diag_compat::template_arg_object_internal)
<< !Func << Entity << Arg->getSourceRange();
S.Diag(Entity->getLocation(), diag::note_template_arg_internal_object)
- << !Func;
+ << !Func;
} else if (!Entity->hasLinkage()) {
S.Diag(Arg->getBeginLoc(), diag::err_template_arg_object_no_linkage)
<< !Func << Entity << Arg->getSourceRange();
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index aa818aad7ff68..d48131c595980 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -1346,9 +1346,7 @@ ExprResult Sema::ActOnPackIndexingExpr(Scope *S, Expr *PackExpression,
ExprResult Res =
BuildPackIndexingExpr(PackExpression, EllipsisLoc, IndexExpr, RSquareLoc);
if (!Res.isInvalid())
- Diag(Res.get()->getBeginLoc(), getLangOpts().CPlusPlus26
- ? diag::warn_cxx23_pack_indexing
- : diag::ext_pack_indexing);
+ DiagCompat(Res.get()->getBeginLoc(), diag_compat::pack_indexing);
return Res;
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index f9033ecb48581..c27e0d95f42e0 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5717,10 +5717,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
if (T->containsUnexpandedParameterPack())
T = Context.getPackExpansionType(T, std::nullopt);
else
- S.Diag(D.getEllipsisLoc(),
- LangOpts.CPlusPlus11
- ? diag::warn_cxx98_compat_variadic_templates
- : diag::ext_variadic_templates);
+ S.DiagCompat(D.getEllipsisLoc(), diag_compat::variadic_templates);
break;
case DeclaratorContext::File:
@@ -10093,8 +10090,7 @@ QualType Sema::ActOnPackIndexingType(QualType Pattern, Expr *IndexExpr,
QualType Type = BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc);
if (!Type.isNull())
- Diag(Loc, getLangOpts().CPlusPlus26 ? diag::warn_cxx23_pack_indexing
- : diag::ext_pack_indexing);
+ DiagCompat(Loc, diag_compat::pack_indexing);
return Type;
}
diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
index 73c043fec4057..49ff4c7fa0ccf 100644
--- a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
+++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
@@ -22,10 +22,10 @@ namespace Numbers {
void test() {
int i = Ints::zero;
Ints::f(i);
-
+
float f = Floats::zero;
Floats::f(f);
-
+
double n = Numbers::zero; // expected-error {{reference to 'zero' is ambiguous}}
Numbers::f(n); // expected-error{{call to 'f' is ambiguous}}
Numbers::f(i);
@@ -74,7 +74,7 @@ namespace inline_ns {
int x; // expected-note 2{{found}}
inline namespace A {
#if __cplusplus <= 199711L // C++03 or earlier
- // expected-warning at -2 {{inline namespaces are a C++11 feature}}
+ // expected-warning at -2 {{inline namespaces are a C++11 extension}}
#endif
int x; // expected-note 2{{found}}
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index ea1daee25610c..05fe817e4fc66 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -451,11 +451,11 @@ namespace cwg30 { // cwg30: sup 468 c++11
} a, *p = &a;
// FIXME: It's not clear whether CWG468 applies to C++98 too.
int x = A::template f<0>();
- // cxx98-error at -1 {{'template' keyword outside of a template}}
+ // cxx98-error at -1 {{use of 'template' keyword outside of a template is a C++11 extension}}
int y = a.template f<0>();
- // cxx98-error at -1 {{'template' keyword outside of a template}}
+ // cxx98-error at -1 {{use of 'template' keyword outside of a template is a C++11 extension}}
int z = p->template f<0>();
- // cxx98-error at -1 {{'template' keyword outside of a template}}
+ // cxx98-error at -1 {{use of 'template' keyword outside of a template is a C++11 extension}}
} // namespace cwg30
namespace cwg31 { // cwg31: 2.8
@@ -1115,12 +1115,12 @@ namespace cwg68 { // cwg68: 2.8
template<typename T> struct X {};
struct ::cwg68::X<int> x1;
struct ::cwg68::template X<int> x2;
- // cxx98-error at -1 {{'template' keyword outside of a template}}
+ // cxx98-error at -1 {{use of 'template' keyword outside of a template is a C++11 extension}}
struct Y {
friend struct X<int>;
friend struct ::cwg68::X<char>;
friend struct ::cwg68::template X<double>;
- // cxx98-error at -1 {{'template' keyword outside of a template}}
+ // cxx98-error at -1 {{use of 'template' keyword outside of a template is a C++11 extension}}
};
template<typename>
struct Z {
diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp
index 4f63b9ac34fb2..96a28100ee987 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -1035,8 +1035,8 @@ namespace cwg468 { // cwg468: 2.7 c++11
};
};
int k = cwg468::template A<int>::template B<char>::C;
- // cxx98-error at -1 {{'template' keyword outside of a template}}
- // cxx98-error at -2 {{'template' keyword outside of a template}}
+ // cxx98-error at -1 {{use of 'template' keyword outside of a template is a C++11 extension}}
+ // cxx98-error at -2 {{use of 'template' keyword outside of a template is a C++11 extension}}
} // namespace cwg468
namespace cwg469 { // cwg469: no
@@ -1264,7 +1264,7 @@ namespace cwg482 { // cwg482: 3.5
// expected-warning at -1 {{extra qualification on member 'f'}}
inline namespace X {
- // cxx98-error at -1 {{inline namespaces are a C++11 feature}}
+ // cxx98-error at -1 {{inline namespaces are a C++11 extension}}
extern int b;
void g();
struct S;
diff --git a/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp b/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp
index 067039aa47393..579c361a7640d 100644
--- a/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp
+++ b/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -25,9 +25,9 @@ void ifInitStatement() {
if (Var + Var; true) {}
if (; true) {}
#ifdef CPP17
- // expected-warning at -4 {{if initialization statements are incompatible with C++ standards before C++17}}
- // expected-warning at -4 {{if initialization statements are incompatible with C++ standards before C++17}}
- // expected-warning at -4 {{if initialization statements are incompatible with C++ standards before C++17}}
+ // expected-warning at -4 {{'if' initialization statements are incompatible with C++ standards before C++17}}
+ // expected-warning at -4 {{'if' initialization statements are incompatible with C++ standards before C++17}}
+ // expected-warning at -4 {{'if' initialization statements are incompatible with C++ standards before C++17}}
#else
// expected-warning at -8 {{'if' initialization statements are a C++17 extension}}
// expected-warning at -8 {{'if' initialization statements are a C++17 extension}}
@@ -42,9 +42,9 @@ void switchInitStatement() {
switch (Var + Var; Var) {}
switch (; Var) {}
#ifdef CPP17
- // expected-warning at -4 {{switch initialization statements are incompatible with C++ standards before C++17}}
- // expected-warning at -4 {{switch initialization statements are incompatible with C++ standards before C++17}}
- // expected-warning at -4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+ // expected-warning at -4 {{'switch' initialization statements are incompatible with C++ standards before C++17}}
+ // expected-warning at -4 {{'switch' initialization statements are incompatible with C++ standards before C++17}}
+ // expected-warning at -4 {{'switch' initialization statements are incompatible with C++ standards before C++17}}
#else
// expected-warning at -8 {{'switch' initialization statements are a C++17 extension}}
// expected-warning at -8 {{'switch' initialization statements are a C++17 extension}}
diff --git a/clang/test/Lexer/cxx2c-raw-strings.cpp b/clang/test/Lexer/cxx2c-raw-strings.cpp
index cf114e57d8bb1..f74763aa951ba 100644
--- a/clang/test/Lexer/cxx2c-raw-strings.cpp
+++ b/clang/test/Lexer/cxx2c-raw-strings.cpp
@@ -6,9 +6,9 @@ int main() {
//precxx26-warning at -1 {{'`' in a raw string literal delimiter is a C++2c extension}}
//precxx26-warning at -2 {{'@' in a raw string literal delimiter is a C++2c extension}}
//precxx26-warning at -3 {{'$' in a raw string literal delimiter is a C++2c extension}}
- //cxx26-warning at -4 {{'`' in a raw string literal delimiter is incompatible with standards before C++2c}}
- //cxx26-warning at -5 {{'@' in a raw string literal delimiter is incompatible with standards before C++2c}}
- //cxx26-warning at -6 {{'$' in a raw string literal delimiter is incompatible with standards before C++2c}}
+ //cxx26-warning at -4 {{'`' in a raw string literal delimiter is incompatible with C++ standards before C++2c}}
+ //cxx26-warning at -5 {{'@' in a raw string literal delimiter is incompatible with C++ standards before C++2c}}
+ //cxx26-warning at -6 {{'$' in a raw string literal delimiter is incompatible with C++ standards before C++2c}}
(void) R"\t()\t";
// expected-error at -1 {{invalid character '\' in raw string delimiter}}
@@ -23,6 +23,6 @@ int main() {
// expected-error at -2 {{expected expression}}
(void) R"@(foo)@";
- // cxx26-warning at -1 {{'@' in a raw string literal delimiter is incompatible with standards before C++2c}}
+ // cxx26-warning at -1 {{'@' in a raw string literal delimiter is incompatible with C++ standards before C++2c}}
// precxx26-warning at -2 {{'@' in a raw string literal delimiter is a C++2c extension}}
}
diff --git a/clang/test/Parser/cxx0x-in-cxx98.cpp b/clang/test/Parser/cxx0x-in-cxx98.cpp
index 10cb4d2fa53aa..90496df13b655 100644
--- a/clang/test/Parser/cxx0x-in-cxx98.cpp
+++ b/clang/test/Parser/cxx0x-in-cxx98.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s
-inline namespace N { // expected-warning{{inline namespaces are a C++11 feature}}
+inline namespace N { // expected-warning{{inline namespaces are a C++11 extension}}
struct X {
template<typename ...Args> // expected-warning{{variadic templates are a C++11 extension}}
void f(Args &&...) &; // expected-warning{{rvalue references are a C++11 extension}} \
diff --git a/clang/test/Parser/cxx0x-lambda-expressions.cpp b/clang/test/Parser/cxx0x-lambda-expressions.cpp
index 5b57c7f638e8a..f2a1972f1fc9d 100644
--- a/clang/test/Parser/cxx0x-lambda-expressions.cpp
+++ b/clang/test/Parser/cxx0x-lambda-expressions.cpp
@@ -146,7 +146,7 @@ struct A {
};
struct S {
- void mf() { A(([*this]{})); } // cxx17ext-warning {{'*this' by copy is a C++17 extension}}
+ void mf() { A(([*this]{})); } // cxx17ext-warning {{by value capture of '*this' is a C++17 extension}}
};
}
diff --git a/clang/test/Parser/cxx11-user-defined-literals.cpp b/clang/test/Parser/cxx11-user-defined-literals.cpp
index 6c15b8133b86f..cf477d8d32385 100644
--- a/clang/test/Parser/cxx11-user-defined-literals.cpp
+++ b/clang/test/Parser/cxx11-user-defined-literals.cpp
@@ -22,7 +22,7 @@ int f() {
}
static_assert(true, "foo"_bar); // expected-error {{no matching literal operator for call to 'operator""_bar'}}
-// expected-warning at -1 {{'static_assert' with a user-generated message is a C++26 extension}}
+// expected-warning at -1 {{'static_assert' with a user-generated message is a C++2c extension}}
int cake() __attribute__((availability(macosx, unavailable, message = "is a lie"_x))); // expected-error {{user-defined suffix cannot be used here}}
diff --git a/clang/test/Parser/cxx1z-nested-namespace-definition.cpp b/clang/test/Parser/cxx1z-nested-namespace-definition.cpp
index b2d6d3253c70e..cbd61b4f15677 100644
--- a/clang/test/Parser/cxx1z-nested-namespace-definition.cpp
+++ b/clang/test/Parser/cxx1z-nested-namespace-definition.cpp
@@ -14,7 +14,7 @@ namespace foo1::foo2::foo3 {
}
#ifndef FIXIT
-inline namespace goo::bar { // expected-error {{nested namespace definition cannot be 'inline'}} expected-warning 0-1{{C++11 feature}}
+inline namespace goo::bar { // expected-error {{nested namespace definition cannot be 'inline'}} expected-warning 0-1{{C++11 extension}}
int n;
}
diff --git a/clang/test/Sema/static-assert.c b/clang/test/Sema/static-assert.c
index dd83cd7684d2c..2f1c00e53cbfd 100644
--- a/clang/test/Sema/static-assert.c
+++ b/clang/test/Sema/static-assert.c
@@ -31,7 +31,7 @@ _Static_assert(1, invalid); // ext-warning {{'_Static_assert' is a C11 extension
// expected-error at -2 {{expected string literal for diagnostic message in static_assert}}
#endif
// cxx-error at -4 {{use of undeclared identifier 'invalid'}}
-// cxx-warning at -5 {{'static_assert' with a user-generated message is a C++26 extension}}
+// cxx-warning at -5 {{'static_assert' with a user-generated message is a C++2c extension}}
struct A {
int a;
diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp
index 587c242271a02..a34fded504167 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -35,7 +35,7 @@ template<int ...I> // expected-warning {{variadic templates are incompatible wi
class Variadic3 {};
alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
-int with_attribute [[ ]]; // expected-warning {{[[]] attributes are incompatible with C++ standards before C++11}}
+int with_attribute [[ ]]; // expected-warning {{[[]] attributes are incompatible with C++98}}
void Literals() {
(void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}}
@@ -133,7 +133,7 @@ void RangeFor() {
}
struct InClassInit {
- int n = 0; // expected-warning {{default member initializer for non-static data members is incompatible with C++98}}
+ int n = 0; // expected-warning {{default member initializer for non-static data member is incompatible with C++98}}
};
struct OverrideControlBase {
diff --git a/clang/test/SemaCXX/static-assert-ext.cpp b/clang/test/SemaCXX/static-assert-ext.cpp
index 05f7a0e96974a..a31034c56c606 100644
--- a/clang/test/SemaCXX/static-assert-ext.cpp
+++ b/clang/test/SemaCXX/static-assert-ext.cpp
@@ -22,7 +22,7 @@ struct X {
static_assert(false, X());
// since-cxx11-warning at -1 {{'static_assert' declarations are incompatible with C++98}}
-// precxx26-warning at -2 {{'static_assert' with a user-generated message is a C++26 extension}}
-// since-cxx26-warning at -3 {{'static_assert' with a user-generated message is incompatible with C++ standards before C++26}}
+// precxx26-warning at -2 {{'static_assert' with a user-generated message is a C++2c extension}}
+// since-cxx26-warning at -3 {{'static_assert' with a user-generated message is incompatible with C++ standards before C++2c}}
// since-cxx11-error at -4 {{static assertion failed: b}}
#endif
>From 9eada186d340ed83d87c44d3fa64058657163ca1 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 28 Aug 2026 10:05:36 +0200
Subject: [PATCH 2/3] Fix formatting
---
clang/lib/Parse/ParseStmt.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 78d0648c7b4d9..5e67cd551bff8 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2483,7 +2483,8 @@ StmtResult Parser::ParseReturnStatement() {
if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) {
R = ParseInitializer();
if (R.isUsable())
- DiagCompat(R.get()->getBeginLoc(), diag_compat::generalized_initializer_lists);
+ DiagCompat(R.get()->getBeginLoc(),
+ diag_compat::generalized_initializer_lists);
} else
R = ParseExpression();
if (R.isInvalid()) {
>From 97b8707b743eac3ea9ab1888f23018d48ab36a3e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 2 Sep 2026 16:58:39 +0200
Subject: [PATCH 3/3] Fix typo
---
clang/include/clang/Basic/DiagnosticLexKinds.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index c3ad1902f2d2b..a7e0a22488bf1 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -21,7 +21,7 @@ defm cxx23_pp_directive : CXX23Compat<
// C++26 compatibility with C++23 and earlier.
defm raw_string_literal_character_set : CXX26Compat<
- " '%0' in a raw string literal delimiter is", /*ext_warn*/false>;
+ "'%0' in a raw string literal delimiter is", /*ext_warn*/false>;
def null_in_char_or_string : Warning<
"null character(s) preserved in %select{char|string}0 literal">,
More information about the cfe-commits
mailing list