Decl *LastEnumConstDecl = 0;
// Parse the enumerator-list.
- while (Tok.is(tok::identifier)) {
+ while (Tok.isNot(tok::r_brace)) {
+ // Parse enumerator. If failed, try skipping till the start of the next
+ // enumerator definition.
+ if (Tok.isNot(tok::identifier)) {
+ Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
+ if (SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch) &&
+ TryConsumeToken(tok::comma))
+ continue;
+ break;
+ }
IdentifierInfo *Ident = Tok.getIdentifierInfo();
SourceLocation IdentLoc = ConsumeToken();
if (TryConsumeToken(tok::equal, EqualLoc)) {
AssignedVal = ParseConstantExpression();
if (AssignedVal.isInvalid())
- SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch);
+ SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch);
}
// Install the enumerator constant into EnumDecl.
continue;
}
+ // Emumerator definition must be finished, only comma or r_brace are
+ // allowed here.
SourceLocation CommaLoc;
- if (!TryConsumeToken(tok::comma, CommaLoc))
- break;
+ if (Tok.isNot(tok::r_brace) && !TryConsumeToken(tok::comma, CommaLoc)) {
+ if (EqualLoc.isValid())
+ Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
+ << tok::comma;
+ else
+ Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
+ if (SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch)) {
+ if (TryConsumeToken(tok::comma, CommaLoc))
+ continue;
+ } else {
+ break;
+ }
+ }
- if (Tok.isNot(tok::identifier)) {
+ // If comma is followed by r_brace, emit appropriate warning.
+ if (Tok.is(tok::r_brace) && CommaLoc.isValid()) {
if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)
Diag(CommaLoc, getLangOpts().CPlusPlus ?
diag::ext_enumerator_list_comma_cxx :
else if (getLangOpts().CPlusPlus11)
Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
<< FixItHint::CreateRemoval(CommaLoc);
+ break;
}
}
};
// This could be a bit-field.
struct S2 {
- enum E : T { a = 1, b = 2, c = 3, 4 }; // expected-error {{non-integral type}} expected-error {{expected '}'}} expected-note {{to match}}
+ enum E : T { a = 1, b = 2, c = 3, 4 }; // expected-error {{non-integral type}} expected-error {{expected identifier}}
};
struct S3 {
enum E : int { a = 1, b = 2, c = 3, d }; // ok, defines an enum
};
// This could be a bit-field.
struct S6 {
- enum E : int { 1 }; // expected-error {{expected '}'}} expected-note {{to match}}
+ enum E : int { 1 }; // expected-error {{expected identifier}}
};
struct U {
struct S { int n; }: // expected-error {{expected ';'}}
};
+
+// PR10982
+enum E11 {
+ A1 = 1,
+};
+
+enum E12 {
+ , // expected-error{{expected identifier}}
+ A2
+};
+void func_E12(enum E12 *p) { *p = A2; }
+
+enum E13 {
+ 1D, // expected-error{{expected identifier}}
+ A3
+};
+void func_E13(enum E13 *p) { *p = A3; }
+
+enum E14 {
+ A4 12, // expected-error{{expected '= constant-expression' or end of enumerator definition}}
+ A4a
+};
+void func_E14(enum E14 *p) { *p = A4a; }
+
+enum E15 {
+ A5=12 4, // expected-error{{expected '}' or ','}}
+ A5a
+};
+void func_E15(enum E15 *p) { *p = A5a; }
+
+enum E16 {
+ A6; // expected-error{{expected '= constant-expression' or end of enumerator definition}}
+ A6a
+};