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

Chris Lattner sabre at nondot.org
Thu Dec 11 22:31:08 PST 2008


Author: lattner
Date: Fri Dec 12 00:31:07 2008
New Revision: 60932

URL: http://llvm.org/viewvc/llvm-project?rev=60932&view=rev
Log:
apply the new error recovery smarts we have for if's to while's and switch's.


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

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Dec 12 00:31:07 2008
@@ -522,6 +522,7 @@
     TypeTy *CastTy;
     return ParseParenExpression(Op, CastTy, RParenLoc);
   }
+  
   OwningExprResult ParseStringLiteralExpression();
 
   //===--------------------------------------------------------------------===//
@@ -639,6 +640,7 @@
   OwningStmtResult ParseDefaultStatement();
   OwningStmtResult ParseCompoundStatement(bool isStmtExpr = false);
   OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
+  bool ParseParenExprOrCondition(OwningExprResult &CondExp);
   OwningStmtResult ParseIfStatement();
   OwningStmtResult ParseSwitchStatement();
   OwningStmtResult ParseWhileStatement();

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri Dec 12 00:31:07 2008
@@ -414,6 +414,42 @@
                                          Stmts.size(), isStmtExpr));
 }
 
+/// ParseParenExprOrCondition:
+/// [C  ]     '(' expression ')'
+/// [C++]     '(' condition ')'
+///
+/// This function parses and performs error recovery on the specified condition
+/// or expression (depending on whether we're in C++ or C mode).  This function
+/// goes out of its way to recover well.  It returns true if there was a parser
+/// error (the right paren couldn't be found), which indicates that the caller
+/// should try to recover harder.  It returns false if the condition is
+/// successfully parsed.  Note that a successful parse can still have semantic
+/// errors in the condition.
+bool Parser::ParseParenExprOrCondition(OwningExprResult &CondExp) {
+  SourceLocation LParenLoc = ConsumeParen();
+  
+  if (getLang().CPlusPlus)
+    CondExp = ParseCXXCondition();
+  else
+    CondExp = ParseExpression();
+  
+  // If the parser was confused by the condition and we don't have a ')', try to
+  // recover by skipping ahead to a semi and bailing out.  If condexp is
+  // semantically invalid but we have well formed code, keep going.
+  if (CondExp.isInvalid() && Tok.isNot(tok::r_paren)) {
+    SkipUntil(tok::semi);
+    // Skipping may have stopped if it found the containing ')'.  If so, we can
+    // continue parsing the if statement.
+    if (Tok.isNot(tok::r_paren))
+      return true;
+  }
+  
+  // Otherwise the condition is valid or the rparen is present.
+  MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  return false;
+}
+
+
 /// ParseIfStatement
 ///       if-statement: [C99 6.8.4.1]
 ///         'if' '(' expression ')' statement
@@ -448,27 +484,9 @@
   ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
 
   // Parse the condition.
-  SourceLocation LParenLoc = ConsumeParen();
-  
   OwningExprResult CondExp(Actions);
-  if (getLang().CPlusPlus)
-    CondExp = ParseCXXCondition();
-  else
-    CondExp = ParseExpression();
-  
-  // If the parser was confused by the condition and we don't have a ')', try to
-  // recover by skipping ahead to a semi and bailing out.  If condexp is
-  // semantically invalid but we have well formed code, keep going.
-  if (CondExp.isInvalid() && Tok.isNot(tok::r_paren)) {
-    SkipUntil(tok::semi);
-    // Skipping may have stopped if it found the containing ')'.  If so, we can
-    // continue parsing the if statement.
-    if (Tok.isNot(tok::r_paren))
-      return StmtError();
-  }
-  
-  // Otherwise the condition is valid or the rparen is present.
-  MatchRHSPunctuation(tok::r_paren, LParenLoc);
+  if (ParseParenExprOrCondition(CondExp))
+    return StmtError();
 
   // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
@@ -583,24 +601,16 @@
   // while, for, and switch statements are local to the if, while, for, or
   // switch statement (including the controlled statement).
   //
-  unsigned ScopeFlags 
-    = C99orCXX? Scope::BreakScope | Scope::DeclScope | Scope::ControlScope
-              : Scope::BreakScope;
+  unsigned ScopeFlags = Scope::BreakScope;
+  if (C99orCXX)
+    ScopeFlags |= Scope::DeclScope | Scope::ControlScope;
   ParseScope SwitchScope(this, ScopeFlags);
 
   // Parse the condition.
   OwningExprResult Cond(Actions);
-  if (getLang().CPlusPlus) {
-    SourceLocation LParenLoc = ConsumeParen();
-    Cond = ParseCXXCondition();
-    MatchRHSPunctuation(tok::r_paren, LParenLoc);
-  } else {
-    Cond = ParseSimpleParenExpression();
-  }
-  
-  if (Cond.isInvalid())
+  if (ParseParenExprOrCondition(Cond))
     return StmtError();
-
+  
   OwningStmtResult Switch(Actions,
                           Actions.ActOnStartOfSwitchStmt(Cond.release()));
 
@@ -631,6 +641,9 @@
 
   SwitchScope.Exit();
 
+  if (Cond.isInvalid())
+    return StmtError();
+  
   return Owned(Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.release(),
                                              Body.release()));
 }
@@ -674,13 +687,8 @@
 
   // Parse the condition.
   OwningExprResult Cond(Actions);
-  if (getLang().CPlusPlus) {
-    SourceLocation LParenLoc = ConsumeParen();
-    Cond = ParseCXXCondition();
-    MatchRHSPunctuation(tok::r_paren, LParenLoc);
-  } else {
-    Cond = ParseSimpleParenExpression();
-  }
+  if (ParseParenExprOrCondition(Cond))
+    return StmtError();
 
   // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
@@ -871,8 +879,7 @@
     if (Tok.is(tok::semi)) {  // for (...;;
       // no second part.
     } else {
-      SecondPart = getLang().CPlusPlus ? ParseCXXCondition()
-                                       : ParseExpression();
+      SecondPart =getLang().CPlusPlus ? ParseCXXCondition() : ParseExpression();
     }
 
     if (Tok.is(tok::semi)) {





More information about the cfe-commits mailing list