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

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


Author: sabre
Date: Wed Jul 11 11:25:29 2007
New Revision: 38887

URL: http://llvm.org/viewvc/llvm-project?rev=38887&view=rev
Log:
Two fixes:

1. Allow argument list of a call to be empty.
2. Handle expressions in a statement context that start with an identifier.
   These are nasty to handle due to the 'label:' production which requires
   having two tokens of look-ahead, or by having tricky code (which we
   choose to do).

Modified:
    cfe/cfe/trunk/Parse/ParseExpr.cpp
    cfe/cfe/trunk/Parse/ParseStmt.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=38887&r1=38886&r2=38887&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:29 2007
@@ -195,7 +195,8 @@
   return ParseRHSOfBinaryExpression(LHS, prec::Comma);
 }
 
-// Expr that doesn't include commas.
+/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
+///
 Parser::ExprResult Parser::ParseAssignmentExpression() {
   ExprResult LHS = ParseCastExpression(false);
   if (LHS.isInvalid) return LHS;
@@ -203,6 +204,35 @@
   return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
 }
 
+/// 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
+/// part of an expression.  For example, in "A[1]+B", we consumed "A" (which is
+/// now in 'Tok') and the current token is "[".
+Parser::ExprResult Parser::
+ParseExpressionWithLeadingIdentifier(const LexerToken &Tok) {
+  // We know that 'Tok' must correspond to this production:
+  //   primary-expression: identifier
+  
+  // TODO: Pass 'Tok' to the action.
+  ExprResult Res = ExprResult(false);
+  
+  // Because we have to parse an entire cast-expression before starting the
+  // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
+  // need to handle the 'postfix-expression' rules.  We do this by invoking
+  // ParsePostfixExpressionSuffix to consume any postfix-expression suffixes:
+  Res = ParsePostfixExpressionSuffix(Res);
+  if (Res.isInvalid) return Res;
+
+  // At this point, the "A[1]" part of "A[1]+B" has been consumed. Once this is
+  // done, we know we don't have to do anything for cast-expression, because the
+  // only non-postfix-expression production starts with a '(' token, and we know
+  // we have an identifier.  As such, we can invoke ParseRHSOfBinaryExpression
+  // to consume any trailing operators (e.g. "+" in this example) and connected
+  // chunks of the expression.
+  return ParseRHSOfBinaryExpression(Res, prec::Comma);
+}
+
 /// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
 /// LHS and has a precedence of at least MinPrec.
 Parser::ExprResult
@@ -476,11 +506,13 @@
       Loc = Tok.getLocation();
       ConsumeParen();
       
-      while (1) {
-        ParseAssignmentExpression();
-        if (Tok.getKind() != tok::comma)
-          break;
-        ConsumeToken();  // Next argument.
+      if (Tok.getKind() != tok::r_paren) {
+        while (1) {
+          ParseAssignmentExpression();
+          if (Tok.getKind() != tok::comma)
+            break;
+          ConsumeToken();  // Next argument.
+        }
       }
         
       // Match the ')'.

Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=38887&r1=38886&r2=38887&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:25:29 2007
@@ -185,6 +185,7 @@
   IdentifierInfo *II = Tok.getIdentifierInfo();
   assert(Tok.getKind() == tok::identifier && II && "Not an identifier!");
 
+  LexerToken IdentTok = Tok;  // Save the token.
   ConsumeToken();  // eat the identifier.
   
   // identifier ':' statement
@@ -211,9 +212,16 @@
     return;
   }
   
-  // Otherwise, this is an expression.  Seed it with II.
-  
-  assert(0);
+  // Otherwise, this is an expression.  Seed it with II and parse it.
+  ExprResult Res = ParseExpressionWithLeadingIdentifier(IdentTok);
+  if (Res.isInvalid)
+    SkipUntil(tok::semi);
+  else if (Tok.getKind() == tok::semi)
+    ConsumeToken();
+  else {
+    Diag(Tok, diag::err_expected_semi_after, "expression");
+    SkipUntil(tok::semi);
+  }
 }
 
 /// ParseCaseStatement

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=38887&r1=38886&r2=38887&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:29 2007
@@ -178,6 +178,7 @@
   //===--------------------------------------------------------------------===//
   // C99 6.5: Expressions.
   //ExprResult ParseExpression();  // Above.
+  ExprResult ParseExpressionWithLeadingIdentifier(const LexerToken &Tok);
   ExprResult ParseAssignmentExpression();  // Expr that doesn't include commas.
 
   ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);





More information about the cfe-commits mailing list