diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 2c88ff42540f..23027076de31 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -673,10 +673,18 @@ public: WhileLoc = WL; } + /// \brief Build an empty while statement. + explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { } + Expr *getCond() { return reinterpret_cast(SubExprs[COND]); } const Expr *getCond() const { return reinterpret_cast(SubExprs[COND]);} + void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast(E); } Stmt *getBody() { return SubExprs[BODY]; } const Stmt *getBody() const { return SubExprs[BODY]; } + void setBody(Stmt *S) { SubExprs[BODY] = S; } + + SourceLocation getWhileLoc() const { return WhileLoc; } + void setWhileLoc(SourceLocation L) { WhileLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); @@ -838,6 +846,12 @@ class ContinueStmt : public Stmt { public: ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} + /// \brief Build an empty continue statement. + explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { } + + SourceLocation getContinueLoc() const { return ContinueLoc; } + void setContinueLoc(SourceLocation L) { ContinueLoc = L; } + virtual SourceRange getSourceRange() const { return SourceRange(ContinueLoc); } diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index 98d27a091603..d95ba85b82ed 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -387,6 +387,10 @@ namespace clang { STMT_IF, /// \brief A SwitchStmt record. STMT_SWITCH, + /// \brief A WhileStmt record. + STMT_WHILE, + /// \brief A ContinueStmt record. + STMT_CONTINUE, /// \brief A BreakStmt record. STMT_BREAK, /// \brief A PredefinedExpr record. diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index e39f3e580b8f..bdadd35e3f22 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -251,6 +251,8 @@ namespace { unsigned VisitDefaultStmt(DefaultStmt *S); unsigned VisitIfStmt(IfStmt *S); unsigned VisitSwitchStmt(SwitchStmt *S); + unsigned VisitWhileStmt(WhileStmt *S); + unsigned VisitContinueStmt(ContinueStmt *S); unsigned VisitBreakStmt(BreakStmt *S); unsigned VisitExpr(Expr *E); unsigned VisitPredefinedExpr(PredefinedExpr *E); @@ -356,6 +358,20 @@ unsigned PCHStmtReader::VisitSwitchStmt(SwitchStmt *S) { return 2; } +unsigned PCHStmtReader::VisitWhileStmt(WhileStmt *S) { + VisitStmt(S); + S->setCond(cast_or_null(StmtStack[StmtStack.size() - 2])); + S->setBody(StmtStack.back()); + S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 2; +} + +unsigned PCHStmtReader::VisitContinueStmt(ContinueStmt *S) { + VisitStmt(S); + S->setContinueLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 0; +} + unsigned PCHStmtReader::VisitBreakStmt(BreakStmt *S) { VisitStmt(S); S->setBreakLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); @@ -2116,6 +2132,14 @@ Stmt *PCHReader::ReadStmt() { S = new (Context) SwitchStmt(Empty); break; + case pch::STMT_WHILE: + S = new (Context) WhileStmt(Empty); + break; + + case pch::STMT_CONTINUE: + S = new (Context) ContinueStmt(Empty); + break; + case pch::STMT_BREAK: S = new (Context) BreakStmt(Empty); break; diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 8f09030ac800..0d514016692c 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -453,6 +453,8 @@ namespace { void VisitDefaultStmt(DefaultStmt *S); void VisitIfStmt(IfStmt *S); void VisitSwitchStmt(SwitchStmt *S); + void VisitWhileStmt(WhileStmt *S); + void VisitContinueStmt(ContinueStmt *S); void VisitBreakStmt(BreakStmt *S); void VisitExpr(Expr *E); void VisitPredefinedExpr(PredefinedExpr *E); @@ -550,6 +552,20 @@ void PCHStmtWriter::VisitSwitchStmt(SwitchStmt *S) { Code = pch::STMT_SWITCH; } +void PCHStmtWriter::VisitWhileStmt(WhileStmt *S) { + VisitStmt(S); + Writer.WriteSubStmt(S->getCond()); + Writer.WriteSubStmt(S->getBody()); + Writer.AddSourceLocation(S->getWhileLoc(), Record); + Code = pch::STMT_WHILE; +} + +void PCHStmtWriter::VisitContinueStmt(ContinueStmt *S) { + VisitStmt(S); + Writer.AddSourceLocation(S->getContinueLoc(), Record); + Code = pch::STMT_CONTINUE; +} + void PCHStmtWriter::VisitBreakStmt(BreakStmt *S) { VisitStmt(S); Writer.AddSourceLocation(S->getBreakLoc(), Record); diff --git a/clang/test/PCH/stmts.h b/clang/test/PCH/stmts.h index ab71c5044034..798058a176e3 100644 --- a/clang/test/PCH/stmts.h +++ b/clang/test/PCH/stmts.h @@ -19,4 +19,11 @@ void f0(int x) { default: break; } + + while (x > 20) { + if (x > 30) { + --x; + continue; + } + } }