diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-05-27 15:17:06 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-05-27 15:17:06 +0000 |
commit | 53992adde3eda3ccf9da63bc7e45673f043de18f (patch) | |
tree | 3558f327a6f9ab59c5d7a06528d84e1560445247 /lib/Parse/ParseStmt.cpp | |
parent | 7e411337c0ed226dace6e07f1420486768161308 (diff) | |
download | FreeBSD-src-53992adde3eda3ccf9da63bc7e45673f043de18f.zip FreeBSD-src-53992adde3eda3ccf9da63bc7e45673f043de18f.tar.gz |
Update clang to r104832.
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 94 |
1 files changed, 60 insertions, 34 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 9b22270..98c0058 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -283,7 +283,7 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { if (Tok.is(tok::code_completion)) { Actions.CodeCompleteCase(CurScope); - ConsumeToken(); + ConsumeCodeCompletionToken(); } /// We don't want to treat 'case x : y' as a potential typo for 'case x::y'. @@ -536,15 +536,23 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { /// successfully parsed. Note that a successful parse can still have semantic /// errors in the condition. bool Parser::ParseParenExprOrCondition(OwningExprResult &ExprResult, - DeclPtrTy &DeclResult) { + DeclPtrTy &DeclResult, + SourceLocation Loc, + bool ConvertToBoolean) { bool ParseError = false; SourceLocation LParenLoc = ConsumeParen(); if (getLang().CPlusPlus) - ParseError = ParseCXXCondition(ExprResult, DeclResult); + ParseError = ParseCXXCondition(ExprResult, DeclResult, Loc, + ConvertToBoolean); else { ExprResult = ParseExpression(); DeclResult = DeclPtrTy(); + + // If required, convert to a boolean value. + if (!ExprResult.isInvalid() && ConvertToBoolean) + ExprResult + = Actions.ActOnBooleanCondition(CurScope, Loc, move(ExprResult)); } // If the parser was confused by the condition and we don't have a ')', try to @@ -603,7 +611,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { // Parse the condition. OwningExprResult CondExp(Actions); DeclPtrTy CondVar; - if (ParseParenExprOrCondition(CondExp, CondVar)) + if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true)) return StmtError(); FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp)); @@ -735,13 +743,25 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { // Parse the condition. OwningExprResult Cond(Actions); DeclPtrTy CondVar; - if (ParseParenExprOrCondition(Cond, CondVar)) + if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false)) return StmtError(); - FullExprArg FullCond(Actions.MakeFullExpr(Cond)); + OwningStmtResult Switch + = Actions.ActOnStartOfSwitchStmt(SwitchLoc, move(Cond), CondVar); + + if (Switch.isInvalid()) { + // Skip the switch body. + // FIXME: This is not optimal recovery, but parsing the body is more + // dangerous due to the presence of case and default statements, which + // will have no place to connect back with the switch. + if (Tok.is(tok::l_brace)) { + ConsumeBrace(); + SkipUntil(tok::r_brace, false, false); + } else + SkipUntil(tok::semi); + return move(Switch); + } - OwningStmtResult 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 // if the body isn't a compound statement to avoid push/pop in common cases. @@ -763,11 +783,6 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { InnerScope.Exit(); SwitchScope.Exit(); - if (Cond.isInvalid() && !CondVar.get()) { - Actions.ActOnSwitchBodyError(SwitchLoc, move(Switch), move(Body)); - return StmtError(); - } - if (Body.isInvalid()) // FIXME: Remove the case statement list from the Switch statement. Body = Actions.ActOnNullStmt(Tok.getLocation()); @@ -818,7 +833,7 @@ Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) { // Parse the condition. OwningExprResult Cond(Actions); DeclPtrTy CondVar; - if (ParseParenExprOrCondition(Cond, CondVar)) + if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true)) return StmtError(); FullExprArg FullCond(Actions.MakeFullExpr(Cond)); @@ -975,14 +990,17 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { bool ForEach = false; OwningStmtResult FirstPart(Actions); - OwningExprResult SecondPart(Actions), ThirdPart(Actions); + bool SecondPartIsInvalid = false; + FullExprArg SecondPart(Actions); + OwningExprResult Collection(Actions); + FullExprArg ThirdPart(Actions); DeclPtrTy SecondVar; if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(CurScope, C99orCXXorObjC? Action::CCC_ForInit : Action::CCC_Expression); - ConsumeToken(); + ConsumeCodeCompletionToken(); } // Parse the first part of the for specifier. @@ -1009,7 +1027,7 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { Actions.ActOnForEachDeclStmt(DG); // ObjC: for (id x in expr) ConsumeToken(); // consume 'in' - SecondPart = ParseExpression(); + Collection = ParseExpression(); } else { Diag(Tok, diag::err_expected_semi_for); SkipUntil(tok::semi); @@ -1025,35 +1043,44 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { ConsumeToken(); } else if ((ForEach = isTokIdentifier_in())) { ConsumeToken(); // consume 'in' - SecondPart = ParseExpression(); + Collection = ParseExpression(); } else { if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for); SkipUntil(tok::semi); } } if (!ForEach) { - assert(!SecondPart.get() && "Shouldn't have a second expression yet."); + assert(!SecondPart->get() && "Shouldn't have a second expression yet."); // Parse the second part of the for specifier. if (Tok.is(tok::semi)) { // for (...;; // no second part. } else { + OwningExprResult Second(Actions); if (getLang().CPlusPlus) - ParseCXXCondition(SecondPart, SecondVar); - else - SecondPart = ParseExpression(); + ParseCXXCondition(Second, SecondVar, ForLoc, true); + else { + Second = ParseExpression(); + if (!Second.isInvalid()) + Second = Actions.ActOnBooleanCondition(CurScope, ForLoc, + move(Second)); + } + SecondPartIsInvalid = Second.isInvalid(); + SecondPart = Actions.MakeFullExpr(Second); } if (Tok.is(tok::semi)) { ConsumeToken(); } else { - if (!SecondPart.isInvalid() || SecondVar.get()) + if (!SecondPartIsInvalid || SecondVar.get()) Diag(Tok, diag::err_expected_semi_for); SkipUntil(tok::semi); } // Parse the third part of the for specifier. - if (Tok.isNot(tok::r_paren)) // for (...;...;) - ThirdPart = ParseExpression(); + if (Tok.isNot(tok::r_paren)) { // for (...;...;) + OwningExprResult Third = ParseExpression(); + ThirdPart = Actions.MakeFullExpr(Third); + } } // Match the ')'. SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); @@ -1085,15 +1112,14 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { return StmtError(); if (!ForEach) - return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart), - Actions.MakeFullExpr(SecondPart), SecondVar, - Actions.MakeFullExpr(ThirdPart), RParenLoc, - move(Body)); - - return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, - move(FirstPart), - move(SecondPart), - RParenLoc, move(Body)); + return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart), SecondPart, + SecondVar, ThirdPart, RParenLoc, move(Body)); + + // FIXME: It isn't clear how to communicate the late destruction of + // C++ temporaries used to create the collection. + return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, move(FirstPart), + move(Collection), RParenLoc, + move(Body)); } /// ParseGotoStatement |