[PATCH] D91659: Allow anonymous enum typedefs to be referenced with the 'enum' specifier under MSVC compat mode
Shivanshu Goyal via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 17 21:48:30 PST 2020
shivanshu3 updated this revision to Diff 305971.
shivanshu3 added a reviewer: rsmith.
shivanshu3 added a comment.
Addressing some of rsmith's comments:
- Add a test case where an enum variable is declared in the same scope as the enum definition
- Fix a style issue with parentheses
- Simplify the if condition for the C case
- The C++ case should only apply for TUK_Reference
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91659/new/
https://reviews.llvm.org/D91659
Files:
clang/lib/Sema/SemaDecl.cpp
clang/test/Sema/enum-typedef-msvc.c
clang/test/Sema/enum-typedef-msvc.cpp
Index: clang/test/Sema/enum-typedef-msvc.cpp
===================================================================
--- /dev/null
+++ clang/test/Sema/enum-typedef-msvc.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility %s
+
+typedef enum {
+ First,
+ Second
+} MyEnum;
+
+class AMyInterface {
+ virtual void MyFunc(enum MyEnum *param) = 0;
+};
+
+class MyImpl : public AMyInterface {
+ virtual void MyFunc(enum MyEnum *param) override {}
+};
+
+enum MyEnum myEnum;
+
+// expected-no-diagnostics
Index: clang/test/Sema/enum-typedef-msvc.c
===================================================================
--- /dev/null
+++ clang/test/Sema/enum-typedef-msvc.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility -DUSE_MSVC_COMPAT %s
+
+typedef enum {
+ A
+} Foo;
+
+void func() {
+#ifdef USE_MSVC_COMPAT
+ enum Foo foo; // expected-no-diagnostics
+#else
+ enum Foo foo; // expected-error {{variable has incomplete type 'enum Foo'}} // expected-note {{forward declaration of 'enum Foo'}}
+#endif
+ (void)foo;
+}
+
+#ifdef USE_MSVC_COMPAT
+enum Foo foo2; // expected-no-diagnostics
+#else
+enum Foo foo2; // expected-error {{tentative definition has type 'enum Foo' that is never completed}}
+ // expected-note at -1 {{forward declaration of 'enum Foo'}}
+#endif
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -15539,6 +15539,21 @@
// shouldn't be diagnosing.
LookupName(Previous, S);
+ // Under MSVC, the 'enum' specifier can be used for typedef'd enums.
+ // Note that lookup only fails in C, not C++, so this if condition
+ // is only used for C code.
+ if (getLangOpts().MSVCCompat && Kind == TTK_Enum && Previous.empty() &&
+ TUK == TUK_Reference) {
+ LookupResult TypedefEnumLookup(*this, Name, NameLoc, LookupOrdinaryName,
+ Redecl);
+ LookupName(TypedefEnumLookup, S);
+
+ if (auto *TD = TypedefEnumLookup.getAsSingle<TypedefNameDecl>())
+ if (auto *ED = dyn_cast_or_null<EnumDecl>(
+ TD->getAnonDeclWithTypedefName(true)))
+ Previous.addDecl(ED);
+ }
+
// When declaring or defining a tag, ignore ambiguities introduced
// by types using'ed into this scope.
if (Previous.isAmbiguous() &&
@@ -15721,9 +15736,12 @@
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(PrevDecl)) {
if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
TagDecl *Tag = TT->getDecl();
- if (Tag->getDeclName() == Name &&
- Tag->getDeclContext()->getRedeclContext()
- ->Equals(TD->getDeclContext()->getRedeclContext())) {
+ bool AnonymousEnumEligible =
+ getLangOpts().MSVCCompat && TUK == TUK_Reference &&
+ Kind == TTK_Enum && Tag->getDeclName().isEmpty();
+ if ((Tag->getDeclName() == Name || AnonymousEnumEligible) &&
+ Tag->getDeclContext()->getRedeclContext()->Equals(
+ TD->getDeclContext()->getRedeclContext())) {
PrevDecl = Tag;
Previous.clear();
Previous.addDecl(Tag);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91659.305971.patch
Type: text/x-patch
Size: 3338 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201118/1866f9ad/attachment-0001.bin>
More information about the cfe-commits
mailing list