summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticParseKinds.td5
-rw-r--r--clang/include/clang/Basic/Features.def3
-rw-r--r--clang/lib/Parse/ParseDecl.cpp24
-rw-r--r--clang/test/Sema/fixed-enum.c18
-rw-r--r--clang/test/SemaObjC/enum-fixed-type.m5
5 files changed, 40 insertions, 15 deletions
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index dfbf1a18507..ae79c65fd3c 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -88,9 +88,12 @@ def err_enumerator_unnamed_no_def : Error<
def ext_cxx11_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a C++11 extension">,
InGroup<CXX11>;
-def ext_c_enum_fixed_underlying_type : Extension<
+def ext_ms_c_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a Microsoft extension">,
InGroup<MicrosoftFixedEnum>;
+def ext_clang_c_enum_fixed_underlying_type : Extension<
+ "enumeration types with a fixed underlying type are a Clang extension">,
+ InGroup<DiagGroup<"fixed-enum-extension">>;
def warn_cxx98_compat_enum_fixed_underlying_type : Warning<
"enumeration types with a fixed underlying type are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 0061135be66..d63c9a0354f 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -89,7 +89,7 @@ FEATURE(objc_arc, LangOpts.ObjCAutoRefCount)
FEATURE(objc_arc_fields, true)
FEATURE(objc_arc_weak, LangOpts.ObjCWeak)
FEATURE(objc_default_synthesize_properties, LangOpts.ObjC2)
-FEATURE(objc_fixed_enum, LangOpts.ObjC2)
+FEATURE(objc_fixed_enum, true)
FEATURE(objc_instancetype, LangOpts.ObjC2)
FEATURE(objc_kindof, LangOpts.ObjC2)
FEATURE(objc_modules, LangOpts.ObjC2 &&LangOpts.Modules)
@@ -232,6 +232,7 @@ EXTENSION(cxx_range_for, LangOpts.CPlusPlus)
EXTENSION(cxx_reference_qualified_functions, LangOpts.CPlusPlus)
EXTENSION(cxx_rvalue_references, LangOpts.CPlusPlus)
EXTENSION(cxx_variadic_templates, LangOpts.CPlusPlus)
+EXTENSION(cxx_fixed_enum, true)
// C++14 features supported by other languages as extensions.
EXTENSION(cxx_binary_literals, true)
EXTENSION(cxx_init_captures, LangOpts.CPlusPlus11)
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4393c8a509d..bbcc860bc2f 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4153,15 +4153,11 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// Enum definitions should not be parsed in a trailing-return-type.
bool AllowDeclaration = DSC != DeclSpecContext::DSC_trailing;
- bool AllowFixedUnderlyingType = AllowDeclaration &&
- (getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt ||
- getLangOpts().ObjC2);
-
CXXScopeSpec &SS = DS.getTypeSpecScope();
if (getLangOpts().CPlusPlus) {
// "enum foo : bar;" is not a potential typo for "enum foo::bar;"
// if a fixed underlying type is allowed.
- ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
+ ColonProtectionRAIIObject X(*this, AllowDeclaration);
CXXScopeSpec Spec;
if (ParseOptionalCXXScopeSpecifier(Spec, nullptr,
@@ -4183,7 +4179,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// Must have either 'enum name' or 'enum {...}'.
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
- !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
+ !(AllowDeclaration && Tok.is(tok::colon))) {
Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
// Skip the rest of this declarator, up until the comma or semicolon.
@@ -4216,7 +4212,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// Parse the fixed underlying type.
bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
- if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
+ if (AllowDeclaration && Tok.is(tok::colon)) {
bool PossibleBitfield = false;
if (CanBeBitfield) {
// If we're in class scope, this can either be an enum declaration with
@@ -4276,13 +4272,15 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
SourceRange Range;
BaseType = ParseTypeName(&Range);
- if (getLangOpts().CPlusPlus11) {
- Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
- } else if (!getLangOpts().ObjC2) {
- if (getLangOpts().CPlusPlus)
- Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range;
+ if (!getLangOpts().ObjC2) {
+ if (getLangOpts().CPlusPlus11)
+ Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
+ else if (getLangOpts().CPlusPlus)
+ Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type);
+ else if (getLangOpts().MicrosoftExt)
+ Diag(StartLoc, diag::ext_ms_c_enum_fixed_underlying_type);
else
- Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range;
+ Diag(StartLoc, diag::ext_clang_c_enum_fixed_underlying_type);
}
}
}
diff --git a/clang/test/Sema/fixed-enum.c b/clang/test/Sema/fixed-enum.c
new file mode 100644
index 00000000000..60a4bc474f7
--- /dev/null
+++ b/clang/test/Sema/fixed-enum.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -Weverything -xc++ -std=c++11 -DCXX11 -verify %s
+// RUN: %clang_cc1 -Weverything -xc++ -std=c++03 -DCXX03 -verify %s
+// RUN: %clang_cc1 -Weverything -xobjective-c -DOBJC -verify %s
+// RUN: %clang_cc1 -Weverything -std=c11 -xc -DC11 -verify %s
+// RUN: %clang_cc1 -Weverything -std=c11 -xc -fms-extensions -DMS -verify %s
+
+enum X : int {e};
+#if defined(CXX11)
+// expected-warning@-2{{enumeration types with a fixed underlying type are incompatible with C++98}}
+#elif defined(CXX03)
+// expected-warning@-4{{enumeration types with a fixed underlying type are a C++11 extension}}
+#elif defined(OBJC)
+// expected-no-diagnostics
+#elif defined(C11)
+// expected-warning@-8{{enumeration types with a fixed underlying type are a Clang extension}}
+#elif defined(MS)
+// expected-warning@-10{{enumeration types with a fixed underlying type are a Microsoft extension}}
+#endif
diff --git a/clang/test/SemaObjC/enum-fixed-type.m b/clang/test/SemaObjC/enum-fixed-type.m
index 37d2810a504..88c895a3398 100644
--- a/clang/test/SemaObjC/enum-fixed-type.m
+++ b/clang/test/SemaObjC/enum-fixed-type.m
@@ -1,9 +1,14 @@
// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -xc %s
#if !__has_feature(objc_fixed_enum)
# error Enumerations with a fixed underlying type are not supported
#endif
+#if !__has_extension(cxx_fixed_enum)
+# error Enumerations with a fixed underlying type are not supported
+#endif
+
typedef long Integer;
typedef enum : Integer { Enumerator1, Enumerator2 } Enumeration;
OpenPOWER on IntegriCloud