[PATCH] Recover from errors in enum definition.

Serge Pavlov sepavloff at gmail.com
Tue Dec 3 23:31:09 PST 2013


Any feedback?


2013/11/18 Serge Pavlov <sepavloff at gmail.com>

> 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
>



-- 
Thanks,
--Serge
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131204/0dbfb264/attachment.html>


More information about the cfe-commits mailing list