aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseStmt.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-25 00:27:52 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-25 00:27:52 +0000
commit99e9b4d172f6877e6ba5ebe75bb8238721f5e01c (patch)
tree16c143b06b39022258614b713ed5999a7d7679c0 /lib/Parse/ParseStmt.cpp
parentd1a7846699a82f85ff3ce6b2e383409537c3f5c5 (diff)
Eliminate CXXConditionDeclExpr with extreme prejudice.
All statements that involve conditions can now hold on to a separate condition declaration (a VarDecl), and will use a DeclRefExpr referring to that VarDecl for the condition expression. ForStmts now have such a VarDecl (I'd missed those in previous commits). Also, since this change reworks the Action interface for if/while/switch/for, use FullExprArg for the full expressions in those expressions, to ensure that we're emitting Note that we are (still) not generating the right cleanups for condition variables in for statements. That will be a follow-on commit. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89817 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r--lib/Parse/ParseStmt.cpp66
1 files changed, 38 insertions, 28 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 294f872988..2022fa51cf 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -517,22 +517,22 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
/// 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,
- bool OnlyAllowCondition,
- SourceLocation *LParenLocPtr,
- SourceLocation *RParenLocPtr) {
+bool Parser::ParseParenExprOrCondition(OwningExprResult &ExprResult,
+ DeclPtrTy &DeclResult) {
+ bool ParseError = false;
+
SourceLocation LParenLoc = ConsumeParen();
- if (LParenLocPtr) *LParenLocPtr = LParenLoc;
-
- if (getLang().CPlusPlus)
- CondExp = ParseCXXCondition();
- else
- CondExp = ParseExpression();
+ if (getLang().CPlusPlus)
+ ParseError = ParseCXXCondition(ExprResult, DeclResult);
+ else {
+ ExprResult = ParseExpression();
+ DeclResult = DeclPtrTy();
+ }
// 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)) {
+ if (ExprResult.isInvalid() && !DeclResult.get() && 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.
@@ -541,8 +541,7 @@ bool Parser::ParseParenExprOrCondition(OwningExprResult &CondExp,
}
// Otherwise the condition is valid or the rparen is present.
- SourceLocation RPLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
- if (RParenLocPtr) *RParenLocPtr = RPLoc;
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
return false;
}
@@ -583,7 +582,8 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) {
// Parse the condition.
OwningExprResult CondExp(Actions);
- if (ParseParenExprOrCondition(CondExp))
+ DeclPtrTy CondVar;
+ if (ParseParenExprOrCondition(CondExp, CondVar))
return StmtError();
FullExprArg FullCondExp(Actions.FullExpr(CondExp));
@@ -650,7 +650,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) {
// If the condition was invalid, discard the if statement. We could recover
// better by replacing it with a valid expr, but don't do that yet.
- if (CondExp.isInvalid())
+ if (CondExp.isInvalid() && !CondVar.get())
return StmtError();
// If the then or else stmt is invalid and the other is valid (and present),
@@ -669,7 +669,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) {
if (ElseStmt.isInvalid())
ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
- return Actions.ActOnIfStmt(IfLoc, FullCondExp, move(ThenStmt),
+ return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, move(ThenStmt),
ElseLoc, move(ElseStmt));
}
@@ -709,12 +709,15 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
// Parse the condition.
OwningExprResult Cond(Actions);
- if (ParseParenExprOrCondition(Cond))
+ DeclPtrTy CondVar;
+ if (ParseParenExprOrCondition(Cond, CondVar))
return StmtError();
+ FullExprArg FullCond(Actions.FullExpr(Cond));
+
OwningStmtResult Switch(Actions);
- if (!Cond.isInvalid())
- Switch = Actions.ActOnStartOfSwitchStmt(move(Cond));
+ if (!Cond.isInvalid() || CondVar.get())
+ Switch = Actions.ActOnStartOfSwitchStmt(FullCond, CondVar);
// C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do this
@@ -743,7 +746,7 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
SwitchScope.Exit();
- if (Cond.isInvalid())
+ if (Cond.isInvalid() && !CondVar.get())
return StmtError();
return Actions.ActOnFinishSwitchStmt(SwitchLoc, move(Switch), move(Body));
@@ -789,7 +792,8 @@ Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
// Parse the condition.
OwningExprResult Cond(Actions);
- if (ParseParenExprOrCondition(Cond))
+ DeclPtrTy CondVar;
+ if (ParseParenExprOrCondition(Cond, CondVar))
return StmtError();
FullExprArg FullCond(Actions.FullExpr(Cond));
@@ -815,10 +819,10 @@ Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
InnerScope.Exit();
WhileScope.Exit();
- if (Cond.isInvalid() || Body.isInvalid())
+ if ((Cond.isInvalid() && !CondVar.get()) || Body.isInvalid())
return StmtError();
- return Actions.ActOnWhileStmt(WhileLoc, FullCond, move(Body));
+ return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, move(Body));
}
/// ParseDoStatement
@@ -943,7 +947,8 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) {
bool ForEach = false;
OwningStmtResult FirstPart(Actions);
OwningExprResult SecondPart(Actions), ThirdPart(Actions);
-
+ DeclPtrTy SecondVar;
+
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteOrdinaryName(CurScope);
ConsumeToken();
@@ -1001,13 +1006,17 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) {
if (Tok.is(tok::semi)) { // for (...;;
// no second part.
} else {
- SecondPart =getLang().CPlusPlus ? ParseCXXCondition() : ParseExpression();
+ if (getLang().CPlusPlus)
+ ParseCXXCondition(SecondPart, SecondVar);
+ else
+ SecondPart = ParseExpression();
}
if (Tok.is(tok::semi)) {
ConsumeToken();
} else {
- if (!SecondPart.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
+ if (!SecondPart.isInvalid() || SecondVar.get())
+ Diag(Tok, diag::err_expected_semi_for);
SkipUntil(tok::semi);
}
@@ -1046,8 +1055,9 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) {
if (!ForEach)
return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart),
- move(SecondPart), move(ThirdPart),
- RParenLoc, move(Body));
+ Actions.FullExpr(SecondPart), SecondVar,
+ Actions.FullExpr(ThirdPart), RParenLoc,
+ move(Body));
return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
move(FirstPart),