[cfe-commits] r38871 - in /cfe/cfe/trunk: Parse/ParseExpr.cpp include/clang/Parse/Parser.h

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


Author: sabre
Date: Wed Jul 11 11:25:22 2007
New Revision: 38871

URL: http://llvm.org/viewvc/llvm-project?rev=38871&view=rev
Log:
Merge ParsePostfixExpression into ParseCastExpression.  This allows us to
implement support for compound literals followed by postfix-expr suffixes,
such as:
(struct{ int a;}){ 1}.a

Modified:
    cfe/cfe/trunk/Parse/ParseExpr.cpp
    cfe/cfe/trunk/include/clang/Parse/Parser.h

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

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:22 2007
@@ -53,6 +53,7 @@
 ///       cast-expression: [C99 6.5.4]
 ///         unary-expression
 ///         '(' type-name ')' cast-expression
+///
 ///       unary-expression:  [C99 6.5.3]
 ///         postfix-expression
 ///         '++' unary-expression
@@ -63,103 +64,11 @@
 /// [GNU]   '__alignof' unary-expression
 /// [GNU]   '__alignof' '(' type-name ')'
 /// [GNU]   '&&' identifier
+///
 ///       unary-operator: one of
 ///         '&'  '*'  '+'  '-'  '~'  '!'
 /// [GNU]   '__extension__'  '__real'  '__imag'
 ///
-///
-void Parser::ParseCastExpression(bool isUnaryExpression) {
-  // If this doesn't start with an '(', then it is a unary-expression.
-  switch (Tok.getKind()) {
-  case tok::l_paren:
-    // If this expression is limited to being a unary-expression, the parent can
-    // not start a cast expression.
-    ParenParseOption ParenExprType =
-      isUnaryExpression ? CompoundLiteral : CastExpr;
-    ParseParenExpression(ParenExprType);
-
-    switch (ParenExprType) {
-    case SimpleExpr: return;    // Nothing else to do.
-    case CompoundStmt: return;  // Nothing else to do.
-    case CompoundLiteral:
-      // We parsed '(' type-name ')' '{' ... '}'.  If any suffixes of
-      // postfix-expression exist, parse them now.
-      //Diag(Tok, diag::err_parse_error);
-      //assert(0 && "FIXME");
-      return;
-    case CastExpr:
-      // We parsed '(' type-name ')' and the thing after it wasn't a '{'.  Parse
-      // the cast-expression that follows it next.
-      ParseCastExpression(false);
-      return;
-    }
-  default:                 // unary-expression: postfix-expression
-    ParsePostfixExpression();
-    break;
-  case tok::plusplus:      // unary-expression: '++' unary-expression
-  case tok::minusminus:    // unary-expression: '--' unary-expression
-    ConsumeToken();
-    ParseCastExpression(true);
-    break;
-  case tok::amp:           // unary-expression: '&' cast-expression
-  case tok::star:          // unary-expression: '*' cast-expression
-  case tok::plus:          // unary-expression: '+' cast-expression
-  case tok::minus:         // unary-expression: '-' cast-expression
-  case tok::tilde:         // unary-expression: '~' cast-expression
-  case tok::exclaim:       // unary-expression: '!' cast-expression
-  case tok::kw___real:     // unary-expression: '__real' cast-expression [GNU]
-  case tok::kw___imag:     // unary-expression: '__real' cast-expression [GNU]
-  //case tok::kw__extension__:  [TODO]
-    ConsumeToken();
-    ParseCastExpression(false);
-    break;
-    
-  case tok::kw_sizeof:     // unary-expression: 'sizeof' unary-expression
-                           // unary-expression: 'sizeof' '(' type-name ')'
-  case tok::kw___alignof:  // unary-expression: '__alignof' unary-expression
-                           // unary-expression: '__alignof' '(' type-name ')'
-    ParseSizeofAlignofExpression();
-    break;
-  case tok::ampamp:        // unary-expression: '&&' identifier
-    Diag(Tok, diag::ext_gnu_address_of_label);
-    ConsumeToken();
-    if (Tok.getKind() == tok::identifier) {
-      ConsumeToken();
-    } else {
-      Diag(Tok, diag::err_expected_ident);
-      ConsumeToken(); // FIXME: Should just return error!
-      return;
-    }
-    break;
-  }
-}
-
-/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
-///       unary-expression:  [C99 6.5.3]
-///         'sizeof' unary-expression
-///         'sizeof' '(' type-name ')'
-/// [GNU]   '__alignof' unary-expression
-/// [GNU]   '__alignof' '(' type-name ')'
-void Parser::ParseSizeofAlignofExpression() {
-  assert((Tok.getKind() == tok::kw_sizeof ||
-          Tok.getKind() == tok::kw___alignof) &&
-         "Not a sizeof/alignof expression!");
-  ConsumeToken();
-  
-  // If the operand doesn't start with an '(', it must be an expression.
-  if (Tok.getKind() != tok::l_paren) {
-    ParseCastExpression(true);
-    return;
-  }
-  
-  // If it starts with a '(', we know that it is either a parenthesized
-  // type-name, or it is a unary-expression that starts with a compound literal,
-  // or starts with a primary-expression that is a parenthesized expression.
-  ParenParseOption ExprType = CastExpr;
-  ParseParenExpression(ExprType);
-}
-
-/// ParsePostfixExpression
 ///       postfix-expression: [C99 6.5.2]
 ///         primary-expression
 ///         postfix-expression '[' expression ']'
@@ -206,9 +115,41 @@
 /// [GNU]   offsetof-member-designator '.' identifier
 /// [GNU]   offsetof-member-designator '[' expression ']'
 ///
-void Parser::ParsePostfixExpression() {
-  // First step, parse the primary expression.
+///
+void Parser::ParseCastExpression(bool isUnaryExpression) {
+  // This handles all of cast-expression, unary-expression, postfix-expression,
+  // and primary-expression.  We handle them together like this for efficiency
+  // and to simplify handling of an expression starting with a '(' token: which
+  // may be one of a parenthesized expression, cast-expression, compound literal
+  // expression, or statement expression.
+  //
+  // If the parsed tokens consist of a primary-expression, the cases below
+  // 'break' out of the switch.  This allows the postfix expression pieces to
+  // be applied to them.  Cases that cannot be followed by postfix exprs should
+  // return instead.
   switch (Tok.getKind()) {
+  case tok::l_paren:
+    // If this expression is limited to being a unary-expression, the parent can
+    // not start a cast expression.
+    ParenParseOption ParenExprType =
+      isUnaryExpression ? CompoundLiteral : CastExpr;
+    ParseParenExpression(ParenExprType);
+
+    switch (ParenExprType) {
+    case SimpleExpr:   break;    // Nothing else to do.
+    case CompoundStmt: break;  // Nothing else to do.
+    case CompoundLiteral:
+      // We parsed '(' type-name ')' '{' ... '}'.  If any suffixes of
+      // postfix-expression exist, parse them now.
+      break;
+    case CastExpr:
+      // We parsed '(' type-name ')' and the thing after it wasn't a '{'.  Parse
+      // the cast-expression that follows it next.
+      ParseCastExpression(false);
+      return;
+    }
+    break;  // These can be followed by postfix-expr pieces.
+      
     // primary-expression
   case tok::identifier:        // primary-expression: identifier
                                // constant: enumeration-constant
@@ -223,19 +164,46 @@
   case tok::string_literal:    // primary-expression: string-literal
     ParseStringLiteralExpression();
     break;
-  case tok::l_paren: {  // primary-expr: '(' expression ')'
-                        // primary-expr: '(' compound-statement ')'
-                        // postfix-expr: '(' type-name ')' '{' init-list '}'
-                        // postfix-expr: '(' type-name ')' '{' init-list ',' '}'
-    ParenParseOption ParenExprType = CompoundLiteral;
-    ParseParenExpression(ParenExprType);
-    break;
-  }
   case tok::kw___builtin_va_arg:
   case tok::kw___builtin_offsetof:
   case tok::kw___builtin_choose_expr:
   case tok::kw___builtin_types_compatible_p:
     assert(0 && "FIXME: UNIMP!");
+  case tok::plusplus:      // unary-expression: '++' unary-expression
+  case tok::minusminus:    // unary-expression: '--' unary-expression
+    ConsumeToken();
+    ParseCastExpression(true);
+    return;
+  case tok::amp:           // unary-expression: '&' cast-expression
+  case tok::star:          // unary-expression: '*' cast-expression
+  case tok::plus:          // unary-expression: '+' cast-expression
+  case tok::minus:         // unary-expression: '-' cast-expression
+  case tok::tilde:         // unary-expression: '~' cast-expression
+  case tok::exclaim:       // unary-expression: '!' cast-expression
+  case tok::kw___real:     // unary-expression: '__real' cast-expression [GNU]
+  case tok::kw___imag:     // unary-expression: '__real' cast-expression [GNU]
+  //case tok::kw__extension__:  [TODO]
+    ConsumeToken();
+    ParseCastExpression(false);
+    return;
+    
+  case tok::kw_sizeof:     // unary-expression: 'sizeof' unary-expression
+                           // unary-expression: 'sizeof' '(' type-name ')'
+  case tok::kw___alignof:  // unary-expression: '__alignof' unary-expression
+                           // unary-expression: '__alignof' '(' type-name ')'
+    ParseSizeofAlignofExpression();
+    return;
+  case tok::ampamp:        // unary-expression: '&&' identifier
+    Diag(Tok, diag::ext_gnu_address_of_label);
+    ConsumeToken();
+    if (Tok.getKind() == tok::identifier) {
+      ConsumeToken();
+    } else {
+      Diag(Tok, diag::err_expected_ident);
+      ConsumeToken(); // FIXME: Should just return error!
+      return;
+    }
+    return;
   default:
     Diag(Tok, diag::err_expected_expression);
     // Guarantee forward progress.
@@ -251,51 +219,76 @@
   SourceLocation Loc;
   while (1) {
     switch (Tok.getKind()) {
-    default:
-      return;
-    case tok::l_square:    // postfix-expression: p-e '[' expression ']'
-      Loc = Tok.getLocation();
-      ConsumeBracket();
-      ParseExpression();
-      // Match the ']'.
-      MatchRHSPunctuation(tok::r_square, Loc, "[", diag::err_expected_rsquare);
-      break;
-      
-    case tok::l_paren:     // p-e: p-e '(' argument-expression-list[opt] ')'
-      Loc = Tok.getLocation();
-      ConsumeParen();
-
-      while (1) {
-        // FIXME: This should be argument-expression!
-        ParseAssignmentExpression();
+      default:
+        return;
+      case tok::l_square:    // postfix-expression: p-e '[' expression ']'
+        Loc = Tok.getLocation();
+        ConsumeBracket();
+        ParseExpression();
+        // Match the ']'.
+        MatchRHSPunctuation(tok::r_square, Loc, "[", diag::err_expected_rsquare);
+        break;
         
-        if (Tok.getKind() != tok::comma)
-          break;
-        ConsumeToken();  // Next argument.
-      }
+      case tok::l_paren:     // p-e: p-e '(' argument-expression-list[opt] ')'
+        Loc = Tok.getLocation();
+        ConsumeParen();
         
-      // Match the ')'.
-      MatchRHSPunctuation(tok::r_paren, Loc, "(", diag::err_expected_rparen);
-      break;
-      
-    case tok::arrow:       // postfix-expression: p-e '->' identifier
-    case tok::period:      // postfix-expression: p-e '.' identifier
-      ConsumeToken();
-      if (Tok.getKind() != tok::identifier) {
-        Diag(Tok, diag::err_expected_ident);
-        return;
-      }
-      ConsumeToken();
-      break;
-      
-    case tok::plusplus:    // postfix-expression: postfix-expression '++'
-    case tok::minusminus:  // postfix-expression: postfix-expression '--'
-      ConsumeToken();
-      break;
+        while (1) {
+          // FIXME: This should be argument-expression!
+          ParseAssignmentExpression();
+          
+          if (Tok.getKind() != tok::comma)
+            break;
+          ConsumeToken();  // Next argument.
+        }
+          
+          // Match the ')'.
+          MatchRHSPunctuation(tok::r_paren, Loc, "(", diag::err_expected_rparen);
+        break;
+        
+      case tok::arrow:       // postfix-expression: p-e '->' identifier
+      case tok::period:      // postfix-expression: p-e '.' identifier
+        ConsumeToken();
+        if (Tok.getKind() != tok::identifier) {
+          Diag(Tok, diag::err_expected_ident);
+          return;
+        }
+          ConsumeToken();
+        break;
+        
+      case tok::plusplus:    // postfix-expression: postfix-expression '++'
+      case tok::minusminus:  // postfix-expression: postfix-expression '--'
+        ConsumeToken();
+        break;
     }
   }
 }
 
+/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
+///       unary-expression:  [C99 6.5.3]
+///         'sizeof' unary-expression
+///         'sizeof' '(' type-name ')'
+/// [GNU]   '__alignof' unary-expression
+/// [GNU]   '__alignof' '(' type-name ')'
+void Parser::ParseSizeofAlignofExpression() {
+  assert((Tok.getKind() == tok::kw_sizeof ||
+          Tok.getKind() == tok::kw___alignof) &&
+         "Not a sizeof/alignof expression!");
+  ConsumeToken();
+  
+  // If the operand doesn't start with an '(', it must be an expression.
+  if (Tok.getKind() != tok::l_paren) {
+    ParseCastExpression(true);
+    return;
+  }
+  
+  // If it starts with a '(', we know that it is either a parenthesized
+  // type-name, or it is a unary-expression that starts with a compound literal,
+  // or starts with a primary-expression that is a parenthesized expression.
+  ParenParseOption ExprType = CastExpr;
+  ParseParenExpression(ExprType);
+}
+
 /// ParseStringLiteralExpression - This handles the various token types that
 /// form string literals, and also handles string concatenation [C99 5.1.1.2,
 /// translation phase #6].

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=38871&r1=38870&r2=38871&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:22 2007
@@ -174,7 +174,6 @@
 
   void ParseCastExpression(bool isUnaryExpression);
   void ParseSizeofAlignofExpression();
-  void ParsePostfixExpression();
   
   /// ParenParseOption - Control what ParseParenExpression will parse.
   enum ParenParseOption {





More information about the cfe-commits mailing list