diff options
Diffstat (limited to 'clang/lib/Parse/ParseStmt.cpp')
-rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index f57ff97ceb5..395fb394dc4 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -1135,6 +1135,9 @@ StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) { ScopeFlags |= Scope::DeclScope | Scope::ControlScope; ParseScope SwitchScope(this, ScopeFlags); + // Temporarily disable 'break' while parsing condition. + SwitchScope.ClearFlags(Scope::BreakScope); + // Parse the condition. ExprResult Cond; Decl *CondVar = 0; @@ -1157,6 +1160,9 @@ StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) { return Switch; } + // Enable 'break' in the body of switch statement. + SwitchScope.SetFlags(Scope::BreakScope); + // 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. @@ -1227,6 +1233,9 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) { ScopeFlags = Scope::BreakScope | Scope::ContinueScope; ParseScope WhileScope(this, ScopeFlags); + // Disable 'break' and 'continue' while parsing condition. + WhileScope.ClearFlags(Scope::BreakScope | Scope::ContinueScope); + // Parse the condition. ExprResult Cond; Decl *CondVar = 0; @@ -1235,6 +1244,9 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) { FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc)); + // Allow 'break' and 'continue' in the body of the statement. + WhileScope.SetFlags(Scope::BreakScope | Scope::ContinueScope); + // 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 // if the body isn't a compound statement to avoid push/pop in common cases. @@ -1314,6 +1326,9 @@ StmtResult Parser::ParseDoStatement() { return StmtError(); } + // Do not allow 'break' and 'continue' in 'while' condition expression. + DoScope.ClearFlags(Scope::BreakScope | Scope::ContinueScope); + // Parse the parenthesized expression. BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); @@ -1391,6 +1406,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); + // Until loop body starts, statements 'break' and 'continue' cannot + // be used. + ForScope.ClearFlags(Scope::BreakScope | Scope::ContinueScope); + ExprResult Value; bool ForEach = false, ForRange = false; @@ -1566,6 +1585,9 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { T.getCloseLocation()); } + // When parsing body of 'for' statement, 'break' and 'continue' may be used. + ForScope.SetFlags(Scope::BreakScope | Scope::ContinueScope); + // 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 // if the body isn't a compound statement to avoid push/pop in common cases. |