<div dir="ltr">Friendly ping.</div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/11/7 Serge Pavlov <span dir="ltr"><<a href="mailto:sepavloff@gmail.com" target="_blank">sepavloff@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">sepavloff added you to the CC list for the revision "Recover from errors in enum definition.".<br>
<div class="HOEnZb"><div class="h5"><br>
Previously any error in enum definition body stopped parsing it. With this<br>
change parser tries to recover from errors.<br>
The patch fixes PR10982.<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D2116" target="_blank">http://llvm-reviews.chandlerc.com/D2116</a><br>
<br>
Files:<br>
include/clang/Basic/DiagnosticParseKinds.td<br>
lib/Parse/ParseDecl.cpp<br>
test/Parser/cxx0x-ambig.cpp<br>
test/Parser/declarators.c<br>
<br>
Index: include/clang/Basic/DiagnosticParseKinds.td<br>
===================================================================<br>
--- include/clang/Basic/DiagnosticParseKinds.td<br>
+++ include/clang/Basic/DiagnosticParseKinds.td<br>
@@ -475,6 +475,7 @@<br>
def err_expected_catch : Error<"expected catch">;<br>
def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;<br>
def err_expected_rbrace_or_comma : Error<"expected '}' or ','">;<br>
+def err_expected_rbrace_comma_or_equal : Error<"expected '}' or ',' or '='">;<br>
def err_expected_rsquare_or_comma : Error<"expected ']' or ','">;<br>
def err_using_namespace_in_class : Error<<br>
"'using namespace' is not allowed in classes">;<br>
Index: lib/Parse/ParseDecl.cpp<br>
===================================================================<br>
--- lib/Parse/ParseDecl.cpp<br>
+++ lib/Parse/ParseDecl.cpp<br>
@@ -3724,7 +3724,15 @@<br>
Decl *LastEnumConstDecl = 0;<br>
<br>
// Parse the enumerator-list.<br>
- while (Tok.is(tok::identifier)) {<br>
+ while (Tok.isNot(tok::r_brace)) {<br>
+ if (Tok.isNot(tok::identifier)) {<br>
+ Diag(Tok.getLocation(), diag::err_expected_ident);<br>
+ SkipUntil(tok::comma, tok::r_brace, true, true);<br>
+ if (Tok.isNot(tok::comma))<br>
+ break;<br>
+ ConsumeToken();<br>
+ continue;<br>
+ }<br>
IdentifierInfo *Ident = Tok.getIdentifierInfo();<br>
SourceLocation IdentLoc = ConsumeToken();<br>
<br>
@@ -3738,7 +3746,9 @@<br>
ExprResult AssignedVal;<br>
ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);<br>
<br>
+ bool EqualSeen = false;<br>
if (Tok.is(tok::equal)) {<br>
+ EqualSeen = true;<br>
EqualLoc = ConsumeToken();<br>
AssignedVal = ParseConstantExpression();<br>
if (AssignedVal.isInvalid())<br>
@@ -3764,19 +3774,29 @@<br>
continue;<br>
}<br>
<br>
- if (Tok.isNot(tok::comma))<br>
+ if (Tok.is(tok::r_brace))<br>
break;<br>
+ if (Tok.isNot(tok::comma)) {<br>
+ Diag(Tok.getLocation(),<br>
+ EqualSeen ? diag::err_expected_rbrace_or_comma<br>
+ : diag::err_expected_rbrace_comma_or_equal);<br>
+ SkipUntil(tok::comma, tok::r_brace, true, true);<br>
+ if (Tok.isNot(tok::comma))<br>
+ break;<br>
+ }<br>
+<br>
SourceLocation CommaLoc = ConsumeToken();<br>
<br>
- if (Tok.isNot(tok::identifier)) {<br>
+ if (Tok.is(tok::r_brace)) {<br>
if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)<br>
Diag(CommaLoc, getLangOpts().CPlusPlus ?<br>
diag::ext_enumerator_list_comma_cxx :<br>
diag::ext_enumerator_list_comma_c)<br>
<< FixItHint::CreateRemoval(CommaLoc);<br>
else if (getLangOpts().CPlusPlus11)<br>
Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)<br>
<< FixItHint::CreateRemoval(CommaLoc);<br>
+ break;<br>
}<br>
}<br>
<br>
Index: test/Parser/cxx0x-ambig.cpp<br>
===================================================================<br>
--- test/Parser/cxx0x-ambig.cpp<br>
+++ test/Parser/cxx0x-ambig.cpp<br>
@@ -48,7 +48,7 @@<br>
};<br>
// This could be a bit-field.<br>
struct S2 {<br>
- enum E : T { a = 1, b = 2, c = 3, 4 }; // expected-error {{non-integral type}} expected-error {{expected '}'}} expected-note {{to match}}<br>
+ enum E : T { a = 1, b = 2, c = 3, 4 }; // expected-error {{non-integral type}} expected-error {{expected identifier}}<br>
};<br>
struct S3 {<br>
enum E : int { a = 1, b = 2, c = 3, d }; // ok, defines an enum<br>
@@ -64,7 +64,7 @@<br>
};<br>
// This could be a bit-field.<br>
struct S6 {<br>
- enum E : int { 1 }; // expected-error {{expected '}'}} expected-note {{to match}}<br>
+ enum E : int { 1 }; // expected-error {{expected identifier}}<br>
};<br>
<br>
struct U {<br>
Index: test/Parser/declarators.c<br>
===================================================================<br>
--- test/Parser/declarators.c<br>
+++ test/Parser/declarators.c<br>
@@ -113,3 +113,32 @@<br>
struct S { int n; }: // expected-error {{expected ';'}}<br>
<br>
};<br>
+<br>
+// PR10982<br>
+enum E11 {<br>
+ A1 = 1,<br>
+};<br>
+<br>
+enum E12 {<br>
+ , // expected-error{{expected identifier}}<br>
+ A2<br>
+};<br>
+void func_E12(enum E12 *p) { *p = A2; }<br>
+<br>
+enum E13 {<br>
+ 1D, // expected-error{{expected identifier}}<br>
+ A3<br>
+};<br>
+void func_E13(enum E13 *p) { *p = A3; }<br>
+<br>
+enum E14 {<br>
+ A4 12, // expected-error{{expected '}' or ',' or '='}}<br>
+ A4a<br>
+};<br>
+void func_E14(enum E14 *p) { *p = A4a; }<br>
+<br>
+enum E15 {<br>
+ A5=12 4, // expected-error{{expected '}' or ','}}<br>
+ A5a<br>
+};<br>
+void func_E15(enum E15 *p) { *p = A5a; }<br>
</div></div><br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>Thanks,<br>--Serge<br>
</div>