From 71517c47e6dacc8944e93665d750c60f148e7580 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 17 Apr 2009 00:29:51 +0000 Subject: [PATCH] PCH support for do-while and for loops llvm-svn: 69334 --- clang/include/clang/AST/Stmt.h | 19 +++++++++++++++ clang/include/clang/Frontend/PCHBitCodes.h | 4 ++++ clang/lib/Frontend/PCHReader.cpp | 28 ++++++++++++++++++++++ clang/lib/Frontend/PCHWriter.cpp | 20 ++++++++++++++++ clang/test/PCH/stmts.h | 9 ++++++- 5 files changed, 79 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 23027076de31..0f489d229172 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -715,11 +715,19 @@ public: SubExprs[BODY] = body; DoLoc = DL; } + + /// \brief Build an empty do-while statement. + explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, 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 getDoLoc() const { return DoLoc; } + void setDoLoc(SourceLocation L) { DoLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); @@ -756,6 +764,9 @@ public: ForLoc = FL; } + /// \brief Build an empty for statement. + explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } + Stmt *getInit() { return SubExprs[INIT]; } Expr *getCond() { return reinterpret_cast(SubExprs[COND]); } Expr *getInc() { return reinterpret_cast(SubExprs[INC]); } @@ -766,6 +777,14 @@ public: const Expr *getInc() const { return reinterpret_cast(SubExprs[INC]); } const Stmt *getBody() const { return SubExprs[BODY]; } + void setInit(Stmt *S) { SubExprs[INIT] = S; } + void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast(E); } + void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast(E); } + void setBody(Stmt *S) { SubExprs[BODY] = S; } + + SourceLocation getForLoc() const { return ForLoc; } + void setForLoc(SourceLocation L) { ForLoc = L; } + virtual SourceRange getSourceRange() const { return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); } diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index d95ba85b82ed..06c120e4653c 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -389,6 +389,10 @@ namespace clang { STMT_SWITCH, /// \brief A WhileStmt record. STMT_WHILE, + /// \brief A DoStmt record. + STMT_DO, + /// \brief A ForStmt record. + STMT_FOR, /// \brief A ContinueStmt record. STMT_CONTINUE, /// \brief A BreakStmt record. diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index bdadd35e3f22..d2fb8ab3cbd8 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -252,6 +252,8 @@ namespace { unsigned VisitIfStmt(IfStmt *S); unsigned VisitSwitchStmt(SwitchStmt *S); unsigned VisitWhileStmt(WhileStmt *S); + unsigned VisitDoStmt(DoStmt *S); + unsigned VisitForStmt(ForStmt *S); unsigned VisitContinueStmt(ContinueStmt *S); unsigned VisitBreakStmt(BreakStmt *S); unsigned VisitExpr(Expr *E); @@ -366,6 +368,24 @@ unsigned PCHStmtReader::VisitWhileStmt(WhileStmt *S) { return 2; } +unsigned PCHStmtReader::VisitDoStmt(DoStmt *S) { + VisitStmt(S); + S->setCond(cast_or_null(StmtStack[StmtStack.size() - 2])); + S->setBody(StmtStack.back()); + S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 2; +} + +unsigned PCHStmtReader::VisitForStmt(ForStmt *S) { + VisitStmt(S); + S->setInit(StmtStack[StmtStack.size() - 4]); + S->setCond(cast_or_null(StmtStack[StmtStack.size() - 3])); + S->setInc(cast_or_null(StmtStack[StmtStack.size() - 2])); + S->setBody(StmtStack.back()); + S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + return 4; +} + unsigned PCHStmtReader::VisitContinueStmt(ContinueStmt *S) { VisitStmt(S); S->setContinueLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); @@ -2136,6 +2156,14 @@ Stmt *PCHReader::ReadStmt() { S = new (Context) WhileStmt(Empty); break; + case pch::STMT_DO: + S = new (Context) DoStmt(Empty); + break; + + case pch::STMT_FOR: + S = new (Context) ForStmt(Empty); + break; + case pch::STMT_CONTINUE: S = new (Context) ContinueStmt(Empty); break; diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 0d514016692c..29c9eb81f444 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -454,6 +454,8 @@ namespace { void VisitIfStmt(IfStmt *S); void VisitSwitchStmt(SwitchStmt *S); void VisitWhileStmt(WhileStmt *S); + void VisitDoStmt(DoStmt *S); + void VisitForStmt(ForStmt *S); void VisitContinueStmt(ContinueStmt *S); void VisitBreakStmt(BreakStmt *S); void VisitExpr(Expr *E); @@ -560,6 +562,24 @@ void PCHStmtWriter::VisitWhileStmt(WhileStmt *S) { Code = pch::STMT_WHILE; } +void PCHStmtWriter::VisitDoStmt(DoStmt *S) { + VisitStmt(S); + Writer.WriteSubStmt(S->getCond()); + Writer.WriteSubStmt(S->getBody()); + Writer.AddSourceLocation(S->getDoLoc(), Record); + Code = pch::STMT_DO; +} + +void PCHStmtWriter::VisitForStmt(ForStmt *S) { + VisitStmt(S); + Writer.WriteSubStmt(S->getInit()); + Writer.WriteSubStmt(S->getCond()); + Writer.WriteSubStmt(S->getInc()); + Writer.WriteSubStmt(S->getBody()); + Writer.AddSourceLocation(S->getForLoc(), Record); + Code = pch::STMT_FOR; +} + void PCHStmtWriter::VisitContinueStmt(ContinueStmt *S) { VisitStmt(S); Writer.AddSourceLocation(S->getContinueLoc(), Record); diff --git a/clang/test/PCH/stmts.h b/clang/test/PCH/stmts.h index 798058a176e3..d67ae187bb69 100644 --- a/clang/test/PCH/stmts.h +++ b/clang/test/PCH/stmts.h @@ -24,6 +24,13 @@ void f0(int x) { if (x > 30) { --x; continue; - } + } else if (x < 5) + break; } + + do { + x++; + } while (x < 10); + + for (; x < 20; ++x) ; }