]> granicus.if.org Git - clang/commitdiff
PCH support for while and continue statements
authorDouglas Gregor <dgregor@apple.com>
Fri, 17 Apr 2009 00:16:09 +0000 (00:16 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 17 Apr 2009 00:16:09 +0000 (00:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69332 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Stmt.h
include/clang/Frontend/PCHBitCodes.h
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp
test/PCH/stmts.h

index 2c88ff42540fa61906794848fbee561938eb8d3d..23027076de31a775256eb80974efbc6610fa2754 100644 (file)
@@ -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<Expr*>(SubExprs[COND]); }
   const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(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); 
   }
index 98d27a09160365c82c3fea40755e6c45b47cb98b..d95ba85b82edac647c7fdbcb6986e6e5b9ce4395 100644 (file)
@@ -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.
index e39f3e580b8f35d74b0024cdffad267ba3c27620..bdadd35e3f22f98377316e937040320c30f37821 100644 (file)
@@ -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<Expr>(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;
index 8f09030ac8007d9822c14d28f25301264f3579e8..0d514016692c52699c322d8c758b34c179a7796a 100644 (file)
@@ -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);
index ab71c50440345897a6613c84932eaa1aa91f91ac..798058a176e376a9f62e57e87eaf49fb973cbc75 100644 (file)
@@ -19,4 +19,11 @@ void f0(int x) {
   default:
     break;
   }
+
+  while (x > 20) {
+    if (x > 30) {
+      --x;
+      continue;
+    }
+  }
 }