aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryicuixi <63290259+yicuixi@users.noreply.github.com>2025-11-05 14:43:40 +0800
committerGitHub <noreply@github.com>2025-11-05 14:43:40 +0800
commit19a9de06cd557da2289c07db0228ec8987d26dc4 (patch)
tree1b232b2e250cc98e7b36a8efc088df4cff0e138b
parent4c2a9c4ba3796799032c12673510279d51c65370 (diff)
downloadllvm-19a9de06cd557da2289c07db0228ec8987d26dc4.zip
llvm-19a9de06cd557da2289c07db0228ec8987d26dc4.tar.gz
llvm-19a9de06cd557da2289c07db0228ec8987d26dc4.tar.bz2
[clang] Accept empty enum in MSVC compatible C (#159981)
Fixes https://github.com/llvm/llvm-project/issues/114402. This patch accept empty enum in C as a microsoft extension and introduce an new warning `-Wmicrosoft-empty-enum`. --------- Signed-off-by: yicuixi <qin_17914@126.com> Co-authored-by: Erich Keane <ekeane@nvidia.com> Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
-rw-r--r--clang/docs/LanguageExtensions.rst10
-rw-r--r--clang/docs/ReleaseNotes.rst1
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td4
-rw-r--r--clang/include/clang/Basic/DiagnosticParseKinds.td3
-rw-r--r--clang/lib/Parse/ParseDecl.cpp9
-rw-r--r--clang/test/CodeGen/ms-empty-enum.c7
-rw-r--r--clang/test/Parser/ms-empty-enum.c6
7 files changed, 37 insertions, 3 deletions
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index baa0bbb..b7c18c2 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -2409,6 +2409,16 @@ those modes.
Use ``__has_feature(c_fixed_enum)`` to determine whether support for fixed
underlying types is available in C23 and later.
+Enumerations with no enumerators
+--------------------------------
+
+Clang provides support for Microsoft extensions to support enumerations with no enumerators.
+
+.. code-block:: c++
+
+ typedef enum empty { } A;
+
+
Interoperability with C++11 lambdas
-----------------------------------
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3f57ddc..32f669f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -444,6 +444,7 @@ Bug Fixes in This Version
- Fixed a failed assertion with empty filename arguments in ``__has_embed``. (#GH159898)
- Fixed a failed assertion with empty filename in ``#embed`` directive. (#GH162951)
- Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953)
+- Accept empty enumerations in MSVC-compatible C mode. (#GH114402)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 8aa3489..1e0321d 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1436,6 +1436,7 @@ def MicrosoftDrectveSection : DiagGroup<"microsoft-drectve-section">;
def MicrosoftInclude : DiagGroup<"microsoft-include">;
def MicrosoftCppMacro : DiagGroup<"microsoft-cpp-macro">;
def MicrosoftFixedEnum : DiagGroup<"microsoft-fixed-enum">;
+def MicrosoftEmptyEnum : DiagGroup<"microsoft-empty-enum">;
def MicrosoftSealed : DiagGroup<"microsoft-sealed">;
def MicrosoftAbstract : DiagGroup<"microsoft-abstract">;
def MicrosoftUnqualifiedFriend : DiagGroup<"microsoft-unqualified-friend">;
@@ -1489,7 +1490,8 @@ def Microsoft : DiagGroup<"microsoft",
MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
MicrosoftCommentPaste, MicrosoftEndOfFile,
MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined,
- MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction]>;
+ MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction,
+ MicrosoftEmptyEnum]>;
def ClangClPch : DiagGroup<"clang-cl-pch">;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index e5e071f..aa0ccb0 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -116,6 +116,9 @@ def err_enumerator_unnamed_no_def : Error<
def ext_ms_c_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a Microsoft extension">,
InGroup<MicrosoftFixedEnum>;
+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>;
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 7e4a164..5fcb659 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5370,8 +5370,13 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl,
T.consumeOpen();
// C does not allow an empty enumerator-list, C++ does [dcl.enum].
- if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
- Diag(Tok, diag::err_empty_enum);
+ if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) {
+ if (getLangOpts().MicrosoftExt)
+ Diag(T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
+ << SourceRange(T.getOpenLocation(), Tok.getLocation());
+ else
+ Diag(Tok, diag::err_empty_enum);
+ }
SmallVector<Decl *, 32> EnumConstantDecls;
SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
diff --git a/clang/test/CodeGen/ms-empty-enum.c b/clang/test/CodeGen/ms-empty-enum.c
new file mode 100644
index 0000000..6c1c87b
--- /dev/null
+++ b/clang/test/CodeGen/ms-empty-enum.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fms-extensions -triple x86_64-windows-msvc -Wno-implicit-function-declaration -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -triple i386-windows-msvc -Wno-implicit-function-declaration -emit-llvm %s -o - | FileCheck %s
+
+typedef enum tag1 {} A;
+
+// CHECK: void @empty_enum(i32 noundef %a)
+void empty_enum(A a) {}
diff --git a/clang/test/Parser/ms-empty-enum.c b/clang/test/Parser/ms-empty-enum.c
new file mode 100644
index 0000000..790547a
--- /dev/null
+++ b/clang/test/Parser/ms-empty-enum.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+typedef enum tag1 { } A; // expected-warning {{empty enumeration types are a Microsoft extension}}
+typedef enum tag2 { } B; // expected-warning {{empty enumeration types are a Microsoft extension}}
+typedef enum : unsigned { } C; // expected-warning {{enumeration types with a fixed underlying type are a Microsoft extension}}\
+ // expected-warning {{empty enumeration types are a Microsoft extension}}