[PATCH] Recover from errors in enum definition.
Alp Toker
alp at nuanti.com
Mon Dec 30 16:35:51 PST 2013
On 30/12/2013 18:13, Serge Pavlov wrote:
> Updated patch according to Alp Toker's notes.
>
> http://llvm-reviews.chandlerc.com/D2116
>
> CHANGE SINCE LAST DIFF
> http://llvm-reviews.chandlerc.com/D2116?vs=6309&id=6316#toc
>
> Files:
> include/clang/Basic/DiagnosticParseKinds.td
> lib/Parse/ParseDecl.cpp
> test/Parser/cxx0x-ambig.cpp
> test/Parser/declarators.c
>
> Index: include/clang/Basic/DiagnosticParseKinds.td
> ===================================================================
> --- include/clang/Basic/DiagnosticParseKinds.td
> +++ include/clang/Basic/DiagnosticParseKinds.td
> @@ -354,6 +354,8 @@
> "unexpected parenthesis after '::'">;
> def err_function_definition_not_allowed : Error<
> "function definition is not allowed here">;
> +def err_expected_end_of_enumerator : Error<
> + "expected '=constant expression' or end of enumerator definition">;
Make this '= constant-expression' with a space and a hyphen.
LGTM with that change!
Alp.
>
> /// Objective-C parser diagnostics
> def err_expected_minus_or_plus : Error<
> Index: lib/Parse/ParseDecl.cpp
> ===================================================================
> --- lib/Parse/ParseDecl.cpp
> +++ lib/Parse/ParseDecl.cpp
> @@ -3888,7 +3888,16 @@
> 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();
>
> @@ -3905,7 +3914,7 @@
> 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.
> @@ -3927,19 +3936,34 @@
> 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 :
> diag::ext_enumerator_list_comma_c)
> << FixItHint::CreateRemoval(CommaLoc);
> else if (getLangOpts().CPlusPlus11)
> Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
> << FixItHint::CreateRemoval(CommaLoc);
> + break;
> }
> }
>
> Index: test/Parser/cxx0x-ambig.cpp
> ===================================================================
> --- test/Parser/cxx0x-ambig.cpp
> +++ test/Parser/cxx0x-ambig.cpp
> @@ -48,7 +48,7 @@
> };
> // 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
> @@ -64,7 +64,7 @@
> };
> // 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 {
> Index: test/Parser/declarators.c
> ===================================================================
> --- test/Parser/declarators.c
> +++ test/Parser/declarators.c
> @@ -113,3 +113,37 @@
> 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
> +};
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
--
http://www.nuanti.com
the browser experts
More information about the cfe-commits
mailing list