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
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

--
http://www.nuanti.com
the browser experts

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to