[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