[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