[cfe-commits] r38896 - in /cfe/cfe/trunk: Parse/ParseDecl.cpp Parse/ParseExpr.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Parser.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:25:34 PDT 2007


Author: sabre
Date: Wed Jul 11 11:25:34 2007
New Revision: 38896

URL: http://llvm.org/viewvc/llvm-project?rev=38896&view=rev
Log:
Implement parsing of enum-specifiers.

Modified:
    cfe/cfe/trunk/Parse/ParseDecl.cpp
    cfe/cfe/trunk/Parse/ParseExpr.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=38896&r1=38895&r2=38896&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:25:34 2007
@@ -105,11 +105,11 @@
 
 /// ParseDeclarationSpecifiers
 ///       declaration-specifiers: [C99 6.7]
-///         storage-class-specifier declaration-specifiers [opt]
-///         type-specifier declaration-specifiers [opt]
-///         type-qualifier declaration-specifiers [opt]
-/// [C99]   function-specifier declaration-specifiers [opt]
-/// [GNU]   attributes declaration-specifiers [opt]                [TODO]
+///         storage-class-specifier declaration-specifiers[opt]
+///         type-specifier declaration-specifiers[opt]
+///         type-qualifier declaration-specifiers[opt]
+/// [C99]   function-specifier declaration-specifiers[opt]
+/// [GNU]   attributes declaration-specifiers[opt]                [TODO]
 ///
 ///       storage-class-specifier: [C99 6.7.1]
 ///         'typedef'
@@ -129,7 +129,7 @@
 ///         'signed'
 ///         'unsigned'
 ///         struct-or-union-specifier             [TODO]
-///         enum-specifier                        [TODO]
+///         enum-specifier
 ///         typedef-name                          [TODO]
 /// [C99]   '_Bool'
 /// [C99]   '_Complex'
@@ -138,15 +138,15 @@
 /// [GNU]   '_Decimal64'
 /// [GNU]   '_Decimal128'
 /// [GNU]   typeof-specifier                      [TODO]
-/// [OBJC]  class-name objc-protocol-refs [opt]   [TODO]
+/// [OBJC]  class-name objc-protocol-refs[opt]    [TODO]
 /// [OBJC]  typedef-name objc-protocol-refs       [TODO]
 /// [OBJC]  objc-protocol-refs                    [TODO]
 ///       type-qualifier:
-///         const
-///         volatile
-/// [C99]   restrict
+///         'const'
+///         'volatile'
+/// [C99]   'restrict'
 ///       function-specifier: [C99 6.7.4]
-/// [C99]   inline
+/// [C99]   'inline'
 ///
 void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
   SourceLocation StartLoc = Tok.getLocation();
@@ -159,7 +159,7 @@
       // specifiers.  First verify that DeclSpec's are consistent.
       DS.Finish(StartLoc, Diags, getLang());
       return;
-    // FIXME: Handle struct/union/enum tags.
+    // FIXME: Handle struct/union tags.
       
     // storage-class-specifier
     case tok::kw_typedef:
@@ -242,7 +242,9 @@
       
     //case tok::kw_struct:
     //case tok::kw_union:
-    //case tok::kw_enum:
+    case tok::kw_enum:
+      ParseEnumSpecifier(DS);
+      continue;
     
     //case tok::identifier:
     // TODO: handle typedef names.
@@ -276,6 +278,65 @@
   }
 }
 
+/// ParseEnumSpecifier
+///       enum-specifier:
+///         'enum' identifier[opt] '{' enumerator-list '}'
+/// [C99]   'enum' identifier[opt] '{' enumerator-list ',' '}'
+///         'enum' identifier
+///       enumerator-list:
+///         enumerator
+///         enumerator-list , enumerator
+///       enumerator:
+///         enumeration-constant
+///         enumeration-constant = constant-expression
+///       enumeration-constant:
+///         identifier
+///
+void Parser::ParseEnumSpecifier(DeclSpec &DS) {
+  assert(Tok.getKind() == tok::kw_enum && "Not an enum specifier");
+  ConsumeToken();
+  
+  // Must have either 'enum name' or 'enum {...}'.
+  if (Tok.getKind() != tok::identifier &&
+      Tok.getKind() != tok::l_brace) {
+    Diag(Tok, diag::err_expected_ident_lbrace);
+    return;
+  }
+  
+  if (Tok.getKind() == tok::identifier)
+    ConsumeToken();
+  
+  if (Tok.getKind() == tok::l_brace) {
+    SourceLocation LBraceLoc = Tok.getLocation();
+    ConsumeBrace();
+    
+    // Parse the enumerator-list.
+    while (Tok.getKind() == tok::identifier) {
+      ConsumeToken();
+      
+      if (Tok.getKind() == tok::equal) {
+        ConsumeToken();
+        ExprResult Res = ParseConstantExpression();
+        if (Res.isInvalid) SkipUntil(tok::comma, true, false);
+      }
+      
+      if (Tok.getKind() != tok::comma)
+        break;
+      SourceLocation CommaLoc = Tok.getLocation();
+      ConsumeToken();
+      
+      if (Tok.getKind() != tok::identifier && !getLang().C99)
+        Diag(CommaLoc, diag::ext_c99_enumerator_list_comma);
+    }
+    
+    // Eat the }.
+    MatchRHSPunctuation(tok::r_brace, LBraceLoc, "{", 
+                        diag::err_expected_rbrace);
+  }
+  // TODO: semantic analysis on the declspec for enums.
+}
+
+
 /// isTypeSpecifierQualifier - Return true if the current token could be the
 /// start of a specifier-qualifier-list.
 bool Parser::isTypeSpecifierQualifier() const {

Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=38896&r1=38895&r2=38896&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:34 2007
@@ -204,6 +204,14 @@
   return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
 }
 
+Parser::ExprResult Parser::ParseConstantExpression() {
+  ExprResult LHS = ParseCastExpression(false);
+  if (LHS.isInvalid) return LHS;
+  
+  // TODO: Validate that this is a constant expr!
+  return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+}
+
 /// ParseExpressionWithLeadingIdentifier - This special purpose method is used
 /// in contexts where we have already consumed an identifier (which we saved in
 /// 'Tok'), then discovered that the identifier was really the leading token of

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38896&r1=38895&r2=38896&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:34 2007
@@ -258,6 +258,8 @@
      "variable declaration in for loop is a C99-specific feature")
 DIAG(ext_c99_compound_literal, EXTENSION,
      "compound literals are a C99-specific feature")
+DIAG(ext_c99_enumerator_list_comma, EXTENSION,
+     "commas at the end of enumerator lists are a C99-specific feature")
      
 DIAG(ext_gnu_indirect_goto, EXTENSION,
      "use of GNU indirect-goto extension")
@@ -277,12 +279,14 @@
      "expected identifier")
 DIAG(err_expected_ident_lparen, ERROR,
      "expected identifier or '('")
+DIAG(err_expected_ident_lbrace, ERROR,
+     "expected identifier or '{'")
 DIAG(err_expected_rparen, ERROR,
      "expected ')'")
 DIAG(err_expected_rsquare, ERROR,
      "expected ']'")
 DIAG(err_expected_rbrace, ERROR,
-     "expected '}' to end compound statement ('{}' block)")
+     "expected '}'")
 DIAG(err_expected_semi_decl_list, ERROR,
      "expected ';' at end of declaration list")
 DIAG(err_expected_fn_body, ERROR,

Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=38896&r1=38895&r2=38896&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:34 2007
@@ -58,9 +58,6 @@
     ExprResult(bool Invalid = false) : isInvalid(Invalid) {}
   };
   
-  ExprResult ParseExpression();
-  
-
   // Diagnostics.
   void Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg = "");
   void Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M = "") {
@@ -198,10 +195,12 @@
 
   //===--------------------------------------------------------------------===//
   // C99 6.5: Expressions.
-  //ExprResult ParseExpression();  // Above.
+  ExprResult ParseExpression();
+  ExprResult ParseConstantExpression();
+  ExprResult ParseAssignmentExpression();  // Expr that doesn't include commas.
+  
   ExprResult ParseExpressionWithLeadingIdentifier(const LexerToken &Tok);
   ExprResult ParseAssignmentExpressionWithLeadingStar(const LexerToken &Tok);
-  ExprResult ParseAssignmentExpression();  // Expr that doesn't include commas.
 
   ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
   ExprResult ParseCastExpression(bool isUnaryExpression);
@@ -243,6 +242,8 @@
   void ParseDeclaration(unsigned Context);
   void ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
   void ParseDeclarationSpecifiers(DeclSpec &DS);
+  void ParseEnumSpecifier(DeclSpec &DS);
+
   bool isDeclarationSpecifier() const;
   bool isTypeSpecifierQualifier() const;
 





More information about the cfe-commits mailing list