On 30/12/2013 03:45, Serge Pavlov wrote:
   Updated the patch for new interface of SkipUntil.

Hi Serge,

You've had this patch for a while so I'll try to get the ball rolling.

There's some trailing whitespace and formatting which you can fix with clang-format but I'll focus on the implementation from here out..


http://llvm-reviews.chandlerc.com/D2116

CHANGE SINCE LAST DIFF
   http://llvm-reviews.chandlerc.com/D2116?vs=5391&id=6309#toc

Files:
   include/clang/Basic/DiagnosticCommonKinds.td
   lib/Parse/ParseDecl.cpp
   test/Parser/cxx0x-ambig.cpp
   test/Parser/declarators.c



D2116.2.patch


Index: include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- include/clang/Basic/DiagnosticCommonKinds.td
+++ include/clang/Basic/DiagnosticCommonKinds.td
@@ -62,6 +62,7 @@
def err_expected : Error<"expected %0">;
  def err_expected_either : Error<"expected %0 or %1">;
+def err_expected_one_of_three : Error<"expected %0 or %1 or %2">;
  def err_expected_after : Error<"expected %1 after %0">;
def err_param_redefinition : Error<"redefinition of parameter %0">;
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -3888,58 +3888,82 @@
    Decl *LastEnumConstDecl = 0;
// Parse the enumerator-list.
-  while (Tok.is(tok::identifier)) {
-    IdentifierInfo *Ident = Tok.getIdentifierInfo();
-    SourceLocation IdentLoc = ConsumeToken();
-
-    // If attributes exist after the enumerator, parse them.
-    ParsedAttributesWithRange attrs(AttrFactory);
-    MaybeParseGNUAttributes(attrs);
-    MaybeParseCXX11Attributes(attrs);
-    ProhibitAttributes(attrs);
-
-    SourceLocation EqualLoc;
-    ExprResult AssignedVal;
-    ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
-
-    if (TryConsumeToken(tok::equal, EqualLoc)) {
-      AssignedVal = ParseConstantExpression();
-      if (AssignedVal.isInvalid())
-        SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch);
-    }
-
-    // Install the enumerator constant into EnumDecl.
-    Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
-                                                    LastEnumConstDecl,
-                                                    IdentLoc, Ident,
-                                                    attrs.getList(), EqualLoc,
-                                                    AssignedVal.release());
-    PD.complete(EnumConstDecl);
-
-    EnumConstantDecls.push_back(EnumConstDecl);
-    LastEnumConstDecl = EnumConstDecl;
-
-    if (Tok.is(tok::identifier)) {
-      // We're missing a comma between enumerators.
-      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
-      Diag(Loc, diag::err_enumerator_list_missing_comma)
-        << FixItHint::CreateInsertion(Loc, ", ");
-      continue;
-    }
-
-    SourceLocation CommaLoc;
-    if (!TryConsumeToken(tok::comma, CommaLoc))
-      break;
-
-    if (Tok.isNot(tok::identifier)) {
-      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);
+  if (Tok.isNot(tok::r_brace)) {

Nesting is getting deep here. Can this loop be restructured so it's easier to follow the flow as it iterates through the enumerator-list?

+    while (true) {
+      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();
+
+      // If attributes exist after the enumerator, parse them.
+      ParsedAttributesWithRange attrs(AttrFactory);
+      MaybeParseGNUAttributes(attrs);
+      MaybeParseCXX11Attributes(attrs);
+      ProhibitAttributes(attrs);
+
+      SourceLocation EqualLoc;
+      ExprResult AssignedVal;
+      ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
+
+      if (TryConsumeToken(tok::equal, EqualLoc)) {
+        AssignedVal = ParseConstantExpression();
+        if (AssignedVal.isInvalid())
+          SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch);
+      }
+
+      // Install the enumerator constant into EnumDecl.
+      Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
+                                                      LastEnumConstDecl,
+                                                      IdentLoc, Ident,
+                                                      attrs.getList(), 
EqualLoc,
+                                                      AssignedVal.release());
+      PD.complete(EnumConstDecl);
+
+      EnumConstantDecls.push_back(EnumConstDecl);
+      LastEnumConstDecl = EnumConstDecl;
+
+      if (Tok.is(tok::identifier)) {
+        // We're missing a comma between enumerators.
+        SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
+        Diag(Loc, diag::err_enumerator_list_missing_comma)
+          << FixItHint::CreateInsertion(Loc, ", ");
+        continue;
+      }
+
+      if (Tok.is(tok::r_brace))
+        break;
+
+      SourceLocation CommaLoc;
+      if (!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_one_of_three)
+            << tok::r_brace << tok::comma << tok::equal;

Good work updating your patch to use the new diagnostic formatter.

Listing three kinds of tokens the parser wants here seems a little brusque. In this instance it seems better to provide a custom diagnostic tailored for enumerators.


+        if (SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch)) {
+          if (TryConsumeToken(tok::comma, CommaLoc))
+            continue;
+        } else {
+          break;
+        }
+      }
+
+      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}}

Nice QOI improvement here.

Alp.


    };
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 '}' 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; }
+
+enum E16 {
+  A6;  // expected-error{{expected '}' or ',' or '='}}
+  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