[PATCH] Recover from errors in enum definition.
Serge Pavlov
sepavloff at gmail.com
Sun Nov 17 21:46:50 PST 2013
Friendly ping.
2013/11/7 Serge Pavlov <sepavloff at gmail.com>
> sepavloff added you to the CC list for the revision "Recover from errors
> in enum definition.".
>
> Previously any error in enum definition body stopped parsing it. With this
> change parser tries to recover from errors.
> The patch fixes PR10982.
>
> http://llvm-reviews.chandlerc.com/D2116
>
> 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
> @@ -475,6 +475,7 @@
> def err_expected_catch : Error<"expected catch">;
> def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
> def err_expected_rbrace_or_comma : Error<"expected '}' or ','">;
> +def err_expected_rbrace_comma_or_equal : Error<"expected '}' or ',' or
> '='">;
> def err_expected_rsquare_or_comma : Error<"expected ']' or ','">;
> def err_using_namespace_in_class : Error<
> "'using namespace' is not allowed in classes">;
> Index: lib/Parse/ParseDecl.cpp
> ===================================================================
> --- lib/Parse/ParseDecl.cpp
> +++ lib/Parse/ParseDecl.cpp
> @@ -3724,7 +3724,15 @@
> Decl *LastEnumConstDecl = 0;
>
> // Parse the enumerator-list.
> - while (Tok.is(tok::identifier)) {
> + while (Tok.isNot(tok::r_brace)) {
> + if (Tok.isNot(tok::identifier)) {
> + Diag(Tok.getLocation(), diag::err_expected_ident);
> + SkipUntil(tok::comma, tok::r_brace, true, true);
> + if (Tok.isNot(tok::comma))
> + break;
> + ConsumeToken();
> + continue;
> + }
> IdentifierInfo *Ident = Tok.getIdentifierInfo();
> SourceLocation IdentLoc = ConsumeToken();
>
> @@ -3738,7 +3746,9 @@
> ExprResult AssignedVal;
> ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
>
> + bool EqualSeen = false;
> if (Tok.is(tok::equal)) {
> + EqualSeen = true;
> EqualLoc = ConsumeToken();
> AssignedVal = ParseConstantExpression();
> if (AssignedVal.isInvalid())
> @@ -3764,19 +3774,29 @@
> continue;
> }
>
> - if (Tok.isNot(tok::comma))
> + if (Tok.is(tok::r_brace))
> break;
> + if (Tok.isNot(tok::comma)) {
> + Diag(Tok.getLocation(),
> + EqualSeen ? diag::err_expected_rbrace_or_comma
> + : diag::err_expected_rbrace_comma_or_equal);
> + SkipUntil(tok::comma, tok::r_brace, true, true);
> + if (Tok.isNot(tok::comma))
> + break;
> + }
> +
> SourceLocation CommaLoc = ConsumeToken();
>
> - if (Tok.isNot(tok::identifier)) {
> + if (Tok.is(tok::r_brace)) {
> 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,32 @@
> 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 '}' or ',' or '='}}
> + 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; }
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
--
Thanks,
--Serge
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131118/60d60eec/attachment.html>
More information about the cfe-commits
mailing list