[cfe-commits] r38861 - in /cfe/cfe/trunk: 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:16 PDT 2007


Author: sabre
Date: Wed Jul 11 11:25:16 2007
New Revision: 38861

URL: http://llvm.org/viewvc/llvm-project?rev=38861&view=rev
Log:
implement postfix-expression parsing.

Modified:
    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/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=38861&r1=38860&r2=38861&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:16 2007
@@ -98,14 +98,83 @@
   case tok::string_literal:    // primary-expression: string-literal
     ParseStringLiteralExpression();
     break;
-  case tok::l_paren:          // primary-expression: '(' expression ')'
-    ParseParenExpression();
+  case tok::l_paren:           // primary-expression: '(' expression ')'
+                               // primary-expression: '(' compound-statement ')'
+    ParseParenExpression(false/*allow statement exprs, initializers */);
     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!");
   default:
     Diag(Tok, diag::err_expected_expression);
+    // Guarantee forward progress.
+    // FIXME: this dies on 'if ({1; });'.  Expression parsing should return a
+    // bool for failure.  This will cause higher-level parsing stuff to do the
+    // right thing.
+    ConsumeToken();
     return;
-  }  
+  }
+  
+  // Now that the primary-expression piece of the postfix-expression has been
+  // parsed, see if there are any postfix-expression pieces here.
+  SourceLocation Loc;
+  while (1) {
+    switch (Tok.getKind()) {
+    default:
+      return;
+    case tok::l_square:    // postfix-expression: p-e '[' expression ']'
+      Loc = Tok.getLocation();
+      ConsumeBracket();
+      ParseExpression();
+      if (Tok.getKind() == tok::r_square) {
+        ConsumeBracket();
+      } else {
+        Diag(Tok, diag::err_expected_rsquare);
+        Diag(Loc, diag::err_matching);
+        SkipUntil(tok::r_square);
+      }
+      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();
+        
+        if (Tok.getKind() != tok::comma)
+          break;
+        ConsumeToken();  // Next argument.
+      }
+        
+      if (Tok.getKind() == tok::r_paren) {
+        ConsumeParen();
+      } else {
+        Diag(Tok, diag::err_expected_rparen);
+        Diag(Loc, diag::err_matching);
+        SkipUntil(tok::r_paren);
+      }
+      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;
+    }
+  }
 }
 
 /// ParseStringLiteralExpression - This handles the various token types that
@@ -125,15 +194,28 @@
 }
 
 
-/// ParseParenExpression - C99 c.5.1p5
+/// ParseParenExpression - C99 6.5.1p5
 ///       primary-expression:
 ///         '(' expression ')'
-void Parser::ParseParenExpression() {
+/// [GNU]   '(' compound-statement ')'      (if !ParenExprOnly)
+///       postfix-expression: [C99 6.5.2]
+///         '(' type-name ')' '{' initializer-list '}'
+///         '(' type-name ')' '{' initializer-list ',' '}'
+///
+void Parser::ParseParenExpression(bool ParenExprOnly) {
   assert(Tok.getKind() == tok::l_paren && "Not a paren expr!");
   SourceLocation OpenLoc = Tok.getLocation();
   ConsumeParen();
   
-  ParseExpression();
+  if (!ParenExprOnly && Tok.getKind() == tok::l_brace &&
+      !getLang().NoExtensions) {
+    Diag(Tok, diag::ext_gnu_statement_expr);
+    ParseCompoundStatement();
+  } else if (!ParenExprOnly && 0 /*type */) { 
+    // FIXME: Implement compound literals: C99 6.5.2.5.  Type-name: C99 6.7.6.
+  } else {
+    ParseExpression();
+  }
   
   if (Tok.getKind() == tok::r_paren) {
     ConsumeParen();

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=38861&r1=38860&r2=38861&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:16 2007
@@ -258,7 +258,9 @@
      "variable declaration in for loop is a c99-specific feature")
 DIAG(ext_gnu_indirect_goto, EXTENSION,
      "use of GNU indirect-goto extension")
-
+DIAG(ext_gnu_statement_expr, EXTENSION,
+     "use of GNU statement expression extension")
+     
 // Generic errors.
 DIAG(err_parse_error, ERROR,
      "parse error")
@@ -270,6 +272,8 @@
      "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)")
 DIAG(err_expected_semi_decl_list, 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=38861&r1=38860&r2=38861&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:16 2007
@@ -165,7 +165,7 @@
   void ParseAssignmentExpression();  // Expr that doesn't include commas.
 
   void ParsePostfixExpression();
-  void ParseParenExpression();
+  void ParseParenExpression(bool ParenExprOnly = true);
   void ParseStringLiteralExpression();
   
   void ParseInitializer();   // C99 6.7.8





More information about the cfe-commits mailing list