Stmt.h revision fe795956194141c91ae555985c9b930595bff43f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file was developed by Chris Lattner and is distributed under
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the University of Illinois Open Source License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  This file defines the Stmt interface and subclasses.
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#ifndef LLVM_CLANG_AST_STMT_H
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define LLVM_CLANG_AST_STMT_H
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "clang/Basic/SourceLocation.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "clang/AST/StmtIterator.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "llvm/ADT/SmallVector.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "llvm/ADT/iterator"
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "llvm/Bitcode/SerializationFwd.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <iosfwd>
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace clang {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Expr;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Decl;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class ScopedDecl;
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  class IdentifierInfo;
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  class SourceManager;
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  class SwitchStmt;
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  class PrinterHelper;
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/// Stmt - This represents one statement.
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)///
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Stmt {
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum StmtClass {
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define STMT(N, CLASS, PARENT) CLASS##Class = N,
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define FIRST_STMT(N) firstStmtConstant = N,
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define LAST_STMT(N) lastStmtConstant = N,
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define FIRST_EXPR(N) firstExprConstant = N,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define LAST_EXPR(N) lastExprConstant = N
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "clang/AST/StmtNodes.def"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)private:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const StmtClass sClass;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stmt(StmtClass SC) : sClass(SC) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~Stmt() {}
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StmtClass getStmtClass() const { return sClass; }
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const char *getStmtClassName() const;
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  /// SourceLocation tokens are not useful in isolation - they are low level
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// value objects created/interpreted by SourceManager. We assume AST
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  /// clients will have a pointer to the respective SourceManager.
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual SourceRange getSourceRange() const = 0;
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // global temp stats (until we have a per-module visitor)
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static void addStmtClass(const StmtClass s);
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static bool CollectingStats(bool enable=false);
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static void PrintStats();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  /// dump - This does a local dump of the specified AST fragment.  It dumps the
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  /// specified node and a few nodes underneath it, but not the whole subtree.
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  /// This is useful in a debugger.
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void dump() const;
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void dump(SourceManager &SM) const;
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void dumpAll() const;
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void dumpAll(SourceManager &SM) const;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  /// back to its original source language syntax.
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void dumpPretty() const;
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void printPretty(std::ostream &OS, PrinterHelper* = NULL) const;
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void viewAST() const;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Implement isa<T> support.
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool classof(const Stmt *) { return true; }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///  contain implicit control-flow in the order their subexpressions
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///  are evaluated.  This predicate returns true if this statement has
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///  such implicit control-flow.  Such statements are also specially handled
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///  within CFGs.
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool hasImplicitControlFlow() const;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// Child Iterators: All subclasses must implement child_begin and child_end
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ///  to permit easy iteration over the substatements/subexpessions of an
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ///  AST node.  This permits easy iteration over all nodes in the AST.
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  typedef StmtIterator       child_iterator;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef ConstStmtIterator  const_child_iterator;
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  typedef std::reverse_iterator<child_iterator>
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          reverse_child_iterator;
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  typedef std::reverse_iterator<const_child_iterator>
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          const_reverse_child_iterator;
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual child_iterator child_begin() = 0;
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual child_iterator child_end()   = 0;
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const_child_iterator child_begin() const {
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const_child_iterator child_end() const {
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reverse_child_iterator child_rbegin() {
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return reverse_child_iterator(child_end());
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reverse_child_iterator child_rend() {
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return reverse_child_iterator(child_begin());
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const_reverse_child_iterator child_rbegin() const {
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return const_reverse_child_iterator(child_end());
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const_reverse_child_iterator child_rend() const {
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return const_reverse_child_iterator(child_begin());
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// DeclStmt - Adaptor class for mixing declarations with statements and
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// expressions. For example, CompoundStmt mixes statements, expressions
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// and declarations (variables, types). Another example is ForStmt, where
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// the first statement can be an expression or a declaration.
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)///
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class DeclStmt : public Stmt {
14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedDecl *TheDecl;
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)public:
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DeclStmt(ScopedDecl *D) : Stmt(DeclStmtClass), TheDecl(D) {}
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const ScopedDecl *getDecl() const { return TheDecl; }
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ScopedDecl *getDecl() { return TheDecl; }
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual SourceRange getSourceRange() const { return SourceRange(); }
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static bool classof(const Stmt *T) {
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return T->getStmtClass() == DeclStmtClass;
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static bool classof(const DeclStmt *) { return true; }
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Iterators
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual child_iterator child_begin();
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual child_iterator child_end();
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/// NullStmt - This is the null statement ";": C99 6.8.3p3.
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci///
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class NullStmt : public Stmt {
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SourceLocation SemiLoc;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)public:
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SourceLocation getSemiLoc() const { return SemiLoc; }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool classof(const Stmt *T) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return T->getStmtClass() == NullStmtClass;
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static bool classof(const NullStmt *) { return true; }
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Iterators
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual child_iterator child_begin();
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual child_iterator child_end();
1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)};
1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// CompoundStmt - This represents a group of statements like { stmt stmt }.
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci///
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass CompoundStmt : public Stmt {
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  llvm::SmallVector<Stmt*, 16> Body;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SourceLocation LBracLoc, RBracLoc;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompoundStmt(Stmt **StmtStart, unsigned NumStmts,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SourceLocation LB, SourceLocation RB)
191    : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts),
192      LBracLoc(LB), RBracLoc(RB) {}
193
194  bool body_empty() const { return Body.empty(); }
195
196  typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
197  body_iterator body_begin() { return Body.begin(); }
198  body_iterator body_end() { return Body.end(); }
199  Stmt *body_back() { return Body.back(); }
200
201  typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
202  const_body_iterator body_begin() const { return Body.begin(); }
203  const_body_iterator body_end() const { return Body.end(); }
204  const Stmt *body_back() const { return Body.back(); }
205
206  typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator;
207  reverse_body_iterator body_rbegin() { return Body.rbegin(); }
208  reverse_body_iterator body_rend() { return Body.rend(); }
209
210  typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator
211    const_reverse_body_iterator;
212  const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); }
213  const_reverse_body_iterator body_rend() const { return Body.rend(); }
214
215  void push_back(Stmt *S) { Body.push_back(S); }
216
217  virtual SourceRange getSourceRange() const {
218    return SourceRange(LBracLoc, RBracLoc);
219  }
220
221  SourceLocation getLBracLoc() const { return LBracLoc; }
222  SourceLocation getRBracLoc() const { return RBracLoc; }
223
224  static bool classof(const Stmt *T) {
225    return T->getStmtClass() == CompoundStmtClass;
226  }
227  static bool classof(const CompoundStmt *) { return true; }
228
229  // Iterators
230  virtual child_iterator child_begin();
231  virtual child_iterator child_end();
232};
233
234// SwitchCase is the base class for CaseStmt and DefaultStmt,
235class SwitchCase : public Stmt {
236  // A pointer to the following CaseStmt or DefaultStmt class,
237  // used by SwitchStmt.
238  SwitchCase *NextSwitchCase;
239protected:
240  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
241
242public:
243  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
244
245  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
246
247  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
248
249  virtual Stmt* v_getSubStmt() = 0;
250  Stmt *getSubStmt() { return v_getSubStmt(); }
251
252  virtual SourceRange getSourceRange() const { return SourceRange(); }
253
254  static bool classof(const Stmt *T) {
255    return T->getStmtClass() == CaseStmtClass ||
256    T->getStmtClass() == DefaultStmtClass;
257  }
258  static bool classof(const SwitchCase *) { return true; }
259};
260
261class CaseStmt : public SwitchCase {
262  enum { SUBSTMT, LHS, RHS, END_EXPR };
263  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
264                             // GNU "case 1 ... 4" extension
265  SourceLocation CaseLoc;
266public:
267  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc)
268    : SwitchCase(CaseStmtClass) {
269    SubExprs[SUBSTMT] = substmt;
270    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
271    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
272    CaseLoc = caseLoc;
273  }
274
275  SourceLocation getCaseLoc() const { return CaseLoc; }
276
277  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
278  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
279  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
280  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
281  const Expr *getLHS() const {
282    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
283  }
284  const Expr *getRHS() const {
285    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
286  }
287  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
288
289  virtual SourceRange getSourceRange() const {
290    return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd());
291  }
292  static bool classof(const Stmt *T) {
293    return T->getStmtClass() == CaseStmtClass;
294  }
295  static bool classof(const CaseStmt *) { return true; }
296
297  // Iterators
298  virtual child_iterator child_begin();
299  virtual child_iterator child_end();
300};
301
302class DefaultStmt : public SwitchCase {
303  Stmt* SubStmt;
304  SourceLocation DefaultLoc;
305public:
306  DefaultStmt(SourceLocation DL, Stmt *substmt) :
307    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
308
309  Stmt *getSubStmt() { return SubStmt; }
310  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
311  const Stmt *getSubStmt() const { return SubStmt; }
312
313  SourceLocation getDefaultLoc() const { return DefaultLoc; }
314
315  virtual SourceRange getSourceRange() const {
316    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
317  }
318  static bool classof(const Stmt *T) {
319    return T->getStmtClass() == DefaultStmtClass;
320  }
321  static bool classof(const DefaultStmt *) { return true; }
322
323  // Iterators
324  virtual child_iterator child_begin();
325  virtual child_iterator child_end();
326};
327
328class LabelStmt : public Stmt {
329  IdentifierInfo *Label;
330  Stmt *SubStmt;
331  SourceLocation IdentLoc;
332public:
333  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
334    : Stmt(LabelStmtClass), Label(label),
335      SubStmt(substmt), IdentLoc(IL) {}
336
337  SourceLocation getIdentLoc() const { return IdentLoc; }
338  IdentifierInfo *getID() const { return Label; }
339  const char *getName() const;
340  Stmt *getSubStmt() { return SubStmt; }
341  const Stmt *getSubStmt() const { return SubStmt; }
342
343  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
344  void setSubStmt(Stmt *SS) { SubStmt = SS; }
345
346  virtual SourceRange getSourceRange() const {
347    return SourceRange(IdentLoc, SubStmt->getLocEnd());
348  }
349  static bool classof(const Stmt *T) {
350    return T->getStmtClass() == LabelStmtClass;
351  }
352  static bool classof(const LabelStmt *) { return true; }
353
354  // Iterators
355  virtual child_iterator child_begin();
356  virtual child_iterator child_end();
357};
358
359
360/// IfStmt - This represents an if/then/else.
361///
362class IfStmt : public Stmt {
363  enum { COND, THEN, ELSE, END_EXPR };
364  Stmt* SubExprs[END_EXPR];
365  SourceLocation IfLoc;
366public:
367  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
368    : Stmt(IfStmtClass)  {
369    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
370    SubExprs[THEN] = then;
371    SubExprs[ELSE] = elsev;
372    IfLoc = IL;
373  }
374
375  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
376  const Stmt *getThen() const { return SubExprs[THEN]; }
377  const Stmt *getElse() const { return SubExprs[ELSE]; }
378
379  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
380  Stmt *getThen() { return SubExprs[THEN]; }
381  Stmt *getElse() { return SubExprs[ELSE]; }
382
383  virtual SourceRange getSourceRange() const {
384    if (SubExprs[ELSE])
385      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
386    else
387      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
388  }
389
390  static bool classof(const Stmt *T) {
391    return T->getStmtClass() == IfStmtClass;
392  }
393  static bool classof(const IfStmt *) { return true; }
394
395  // Iterators
396  virtual child_iterator child_begin();
397  virtual child_iterator child_end();
398};
399
400/// SwitchStmt - This represents a 'switch' stmt.
401///
402class SwitchStmt : public Stmt {
403  enum { COND, BODY, END_EXPR };
404  Stmt* SubExprs[END_EXPR];
405  // This points to a linked list of case and default statements.
406  SwitchCase *FirstCase;
407  SourceLocation SwitchLoc;
408public:
409  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
410      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
411      SubExprs[BODY] = NULL;
412    }
413
414  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
415  const Stmt *getBody() const { return SubExprs[BODY]; }
416  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
417
418  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
419  Stmt *getBody() { return SubExprs[BODY]; }
420  SwitchCase *getSwitchCaseList() { return FirstCase; }
421
422  void setBody(Stmt *S, SourceLocation SL) {
423    SubExprs[BODY] = S;
424    SwitchLoc = SL;
425  }
426  void addSwitchCase(SwitchCase *SC) {
427    if (FirstCase)
428      SC->setNextSwitchCase(FirstCase);
429
430    FirstCase = SC;
431  }
432  virtual SourceRange getSourceRange() const {
433    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
434  }
435  static bool classof(const Stmt *T) {
436    return T->getStmtClass() == SwitchStmtClass;
437  }
438  static bool classof(const SwitchStmt *) { return true; }
439
440  // Iterators
441  virtual child_iterator child_begin();
442  virtual child_iterator child_end();
443};
444
445
446/// WhileStmt - This represents a 'while' stmt.
447///
448class WhileStmt : public Stmt {
449  enum { COND, BODY, END_EXPR };
450  Stmt* SubExprs[END_EXPR];
451  SourceLocation WhileLoc;
452public:
453  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
454    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
455    SubExprs[BODY] = body;
456    WhileLoc = WL;
457  }
458
459  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
460  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
461  Stmt *getBody() { return SubExprs[BODY]; }
462  const Stmt *getBody() const { return SubExprs[BODY]; }
463
464  virtual SourceRange getSourceRange() const {
465    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
466  }
467  static bool classof(const Stmt *T) {
468    return T->getStmtClass() == WhileStmtClass;
469  }
470  static bool classof(const WhileStmt *) { return true; }
471
472  // Iterators
473  virtual child_iterator child_begin();
474  virtual child_iterator child_end();
475};
476
477/// DoStmt - This represents a 'do/while' stmt.
478///
479class DoStmt : public Stmt {
480  enum { COND, BODY, END_EXPR };
481  Stmt* SubExprs[END_EXPR];
482  SourceLocation DoLoc;
483public:
484  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
485    : Stmt(DoStmtClass), DoLoc(DL) {
486    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
487    SubExprs[BODY] = body;
488    DoLoc = DL;
489  }
490
491  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
492  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
493  Stmt *getBody() { return SubExprs[BODY]; }
494  const Stmt *getBody() const { return SubExprs[BODY]; }
495
496  virtual SourceRange getSourceRange() const {
497    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
498  }
499  static bool classof(const Stmt *T) {
500    return T->getStmtClass() == DoStmtClass;
501  }
502  static bool classof(const DoStmt *) { return true; }
503
504  // Iterators
505  virtual child_iterator child_begin();
506  virtual child_iterator child_end();
507};
508
509
510/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
511/// the init/cond/inc parts of the ForStmt will be null if they were not
512/// specified in the source.
513///
514class ForStmt : public Stmt {
515  enum { INIT, COND, INC, BODY, END_EXPR };
516  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
517  SourceLocation ForLoc;
518public:
519  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
520    : Stmt(ForStmtClass) {
521    SubExprs[INIT] = Init;
522    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
523    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
524    SubExprs[BODY] = Body;
525    ForLoc = FL;
526  }
527
528  Stmt *getInit() { return SubExprs[INIT]; }
529  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
530  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
531  Stmt *getBody() { return SubExprs[BODY]; }
532
533  const Stmt *getInit() const { return SubExprs[INIT]; }
534  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
535  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
536  const Stmt *getBody() const { return SubExprs[BODY]; }
537
538  virtual SourceRange getSourceRange() const {
539    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
540  }
541  static bool classof(const Stmt *T) {
542    return T->getStmtClass() == ForStmtClass;
543  }
544  static bool classof(const ForStmt *) { return true; }
545
546  // Iterators
547  virtual child_iterator child_begin();
548  virtual child_iterator child_end();
549};
550
551/// GotoStmt - This represents a direct goto.
552///
553class GotoStmt : public Stmt {
554  LabelStmt *Label;
555  SourceLocation GotoLoc;
556  SourceLocation LabelLoc;
557public:
558  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
559    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
560
561  LabelStmt *getLabel() const { return Label; }
562
563  virtual SourceRange getSourceRange() const {
564    return SourceRange(GotoLoc, LabelLoc);
565  }
566  static bool classof(const Stmt *T) {
567    return T->getStmtClass() == GotoStmtClass;
568  }
569  static bool classof(const GotoStmt *) { return true; }
570
571  // Iterators
572  virtual child_iterator child_begin();
573  virtual child_iterator child_end();
574};
575
576/// IndirectGotoStmt - This represents an indirect goto.
577///
578class IndirectGotoStmt : public Stmt {
579  Expr *Target;
580public:
581  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){}
582
583  Expr *getTarget() { return Target; }
584  const Expr *getTarget() const { return Target; }
585
586  virtual SourceRange getSourceRange() const { return SourceRange(); }
587
588  static bool classof(const Stmt *T) {
589    return T->getStmtClass() == IndirectGotoStmtClass;
590  }
591  static bool classof(const IndirectGotoStmt *) { return true; }
592
593  // Iterators
594  virtual child_iterator child_begin();
595  virtual child_iterator child_end();
596};
597
598
599/// ContinueStmt - This represents a continue.
600///
601class ContinueStmt : public Stmt {
602  SourceLocation ContinueLoc;
603public:
604  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
605
606  virtual SourceRange getSourceRange() const {
607    return SourceRange(ContinueLoc);
608  }
609  static bool classof(const Stmt *T) {
610    return T->getStmtClass() == ContinueStmtClass;
611  }
612  static bool classof(const ContinueStmt *) { return true; }
613
614  // Iterators
615  virtual child_iterator child_begin();
616  virtual child_iterator child_end();
617};
618
619/// BreakStmt - This represents a break.
620///
621class BreakStmt : public Stmt {
622  SourceLocation BreakLoc;
623public:
624  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
625
626  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
627
628  static bool classof(const Stmt *T) {
629    return T->getStmtClass() == BreakStmtClass;
630  }
631  static bool classof(const BreakStmt *) { return true; }
632
633  // Iterators
634  virtual child_iterator child_begin();
635  virtual child_iterator child_end();
636};
637
638
639/// ReturnStmt - This represents a return, optionally of an expression.
640///
641class ReturnStmt : public Stmt {
642  Expr *RetExpr;
643  SourceLocation RetLoc;
644public:
645  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
646    RetExpr(E), RetLoc(RL) {}
647
648  const Expr *getRetValue() const { return RetExpr; }
649  Expr *getRetValue() { return RetExpr; }
650
651  virtual SourceRange getSourceRange() const;
652
653  static bool classof(const Stmt *T) {
654    return T->getStmtClass() == ReturnStmtClass;
655  }
656  static bool classof(const ReturnStmt *) { return true; }
657
658  // Iterators
659  virtual child_iterator child_begin();
660  virtual child_iterator child_end();
661};
662
663/// AsmStmt - This represents a GNU inline-assembly statement extension.
664///
665class AsmStmt : public Stmt {
666  SourceLocation AsmLoc, RParenLoc;
667  // FIXME: This doesn't capture most of the interesting pieces.
668public:
669  AsmStmt(SourceLocation asmloc, SourceLocation rparenloc)
670    : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {}
671
672  virtual SourceRange getSourceRange() const {
673    return SourceRange(AsmLoc, RParenLoc);
674  }
675
676  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
677  static bool classof(const AsmStmt *) { return true; }
678
679  virtual child_iterator child_begin();
680  virtual child_iterator child_end();
681};
682
683
684}  // end namespace clang
685
686//===----------------------------------------------------------------------===//
687// For Stmt serialization.
688//===----------------------------------------------------------------------===//
689
690namespace llvm {
691
692template<> struct SerializeTrait<clang::Stmt> {
693  static void Emit(Serializer& S, clang::Stmt& stmt);
694  static clang::Stmt* Materialize(Deserializer& D);
695};
696
697} // end namespace llvm
698
699#endif
700