Skip to content
10 changes: 9 additions & 1 deletion clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1986,7 +1986,7 @@ Enumerations with a fixed underlying type
-----------------------------------------

Clang provides support for C++11 enumerations with a fixed underlying type
within Objective-C. For example, one can write an enumeration type as:
within Objective-C and C `prior to C23 <https://open-std.org/JTC1/SC22/WG14/www/docs/n3030.htm>`_. For example, one can write an enumeration type as:

.. code-block:: c++

Expand All @@ -1998,6 +1998,14 @@ value, is ``unsigned char``.
Use ``__has_feature(objc_fixed_enum)`` to determine whether support for fixed
underlying types is available in Objective-C.

Use ``__has_extension(c_fixed_enum)`` to determine whether support for fixed
underlying types is available in C prior to C23. This will also report ``true`` in C23
and later modes as the functionality is available even if it's not an extension in
those modes.

Use ``__has_feature(c_fixed_enum)`` to determine whether support for fixed
underlying types is available in C23 and later.

Interoperability with C++11 lambdas
-----------------------------------

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ FEATURE(c_atomic, LangOpts.C11)
FEATURE(c_generic_selections, LangOpts.C11)
FEATURE(c_static_assert, LangOpts.C11)
FEATURE(c_thread_local, LangOpts.C11 &&PP.getTargetInfo().isTLSSupported())
// C23 features
FEATURE(c_fixed_enum, LangOpts.C23)
// C++11 features
FEATURE(cxx_access_control_sfinae, LangOpts.CPlusPlus11)
FEATURE(cxx_alias_templates, LangOpts.CPlusPlus11)
Expand Down Expand Up @@ -269,6 +271,7 @@ EXTENSION(c_static_assert, true)
EXTENSION(c_thread_local, PP.getTargetInfo().isTLSSupported())
// C23 features supported by other languages as extensions
EXTENSION(c_attributes, true)
EXTENSION(c_fixed_enum, true)
// C++11 features supported by other languages as extensions.
EXTENSION(cxx_atomic, LangOpts.CPlusPlus)
EXTENSION(cxx_default_function_template_args, LangOpts.CPlusPlus)
Expand Down
11 changes: 11 additions & 0 deletions clang/test/Sema/enum.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ int NegativeShortTest[NegativeShort == -1 ? 1 : -1];
enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}}

// Enumerations with a fixed underlying type.
// https://github.com/llvm/llvm-project/issues/116880
#if __STDC_VERSION__ >= 202311L
static_assert(__has_feature(c_fixed_enum));
static_assert(__has_extension(c_fixed_enum)); // Matches behavior for c_alignas, etc
#else
_Static_assert(__has_extension(c_fixed_enum), "");
_Static_assert(!__has_feature(c_fixed_enum), "");
#endif
typedef enum : unsigned char { Pink, Black, Cyan } Color; // pre-c23-warning {{enumeration types with a fixed underlying type are a C23 extension}}

// PR28903
// In C it is valid to define tags inside enums.
struct PR28903 {
Expand Down
Loading