Stmt.h revision 25a0fe2a99aaf2d1bf5bdfdae7ab11e2a5e7622f
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
55f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file is distributed under the University of Illinois Open Source
65f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file defines the Stmt interface and subclasses.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_AST_STMT_H
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_AST_STMT_H
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/Casting.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/Support/raw_ostream.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/SourceLocation.h"
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/PrettyPrinter.h"
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/StmtIterator.h"
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/DeclGroup.h"
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/FullExpr.h"
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/SmallVector.h"
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/ASTContext.h"
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <string>
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing llvm::dyn_cast_or_null;
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace llvm {
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class FoldingSetNodeID;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class ASTContext;
353acb13805673d47be95829bd5a4b1707952c0b6fChris Lattner  class Expr;
36251dcaf8616c6f04051e214f35cadb7de42aef7eBill Wendling  class Decl;
373acb13805673d47be95829bd5a4b1707952c0b6fChris Lattner  class ParmVarDecl;
38700204c74b455746752e851b25565ebf932f5340Steve Naroff  class QualType;
39dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  class IdentifierInfo;
407064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  class SourceManager;
417064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  class StringLiteral;
427064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  class SwitchStmt;
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===----------------------------------------------------------------------===//
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //  references to children (to be compatible with StmtIterator).
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===----------------------------------------------------------------------===//
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class Stmt;
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class Expr;
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class ExprIterator {
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Stmt** I;
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  public:
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ExprIterator(Stmt** i) : I(i) {}
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ExprIterator() : I(0) {}
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ExprIterator& operator++() { ++I; return *this; }
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ExprIterator operator-(size_t i) { return I-i; }
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ExprIterator operator+(size_t i) { return I+i; }
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Expr* operator[](size_t idx);
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FIXME: Verify that this will correctly return a signed distance.
635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    signed operator-(const ExprIterator& R) const { return I - R.I; }
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Expr* operator*() const;
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Expr* operator->() const;
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator==(const ExprIterator& R) const { return I == R.I; }
675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator!=(const ExprIterator& R) const { return I != R.I; }
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator>(const ExprIterator& R) const { return I > R.I; }
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class ConstExprIterator {
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const Stmt * const *I;
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  public:
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConstExprIterator(const Stmt * const *i) : I(i) {}
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConstExprIterator() : I(0) {}
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConstExprIterator& operator++() { ++I; return *this; }
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConstExprIterator operator+(size_t i) const { return I+i; }
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConstExprIterator operator-(size_t i) const { return I-i; }
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const Expr * operator[](size_t idx) const;
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const Expr * operator*() const;
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const Expr * operator->() const;
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// AST classes for statements.
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Stmt - This represents one statement.
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass Stmt {
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum StmtClass {
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NoStmtClass = 0,
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define STMT(CLASS, PARENT) CLASS##Class,
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define STMT_RANGE(BASE, FIRST, LAST) \
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        first##BASE##Constant = FIRST##Class, \
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        last##BASE##Constant = LAST##Class,
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        first##BASE##Constant = FIRST##Class, \
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        last##BASE##Constant = LAST##Class
1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define ABSTRACT_STMT(STMT)
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/StmtNodes.inc"
1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief The statement class.
1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const unsigned sClass : 8;
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief The reference count for this statement.
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned RefCount : 24;
1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Make vanilla 'new' and 'delete' illegal for Stmts.
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void* operator new(size_t bytes) throw() {
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(0 && "Stmts cannot be allocated with regular 'new'.");
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return 0;
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void operator delete(void* data) throw() {
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(0 && "Stmts cannot be released with regular 'delete'.");
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Only allow allocation of Stmts using the allocator in ASTContext
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // or by doing a placement new.
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void* operator new(size_t bytes, ASTContext& C,
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                     unsigned alignment = 8) throw() {
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ::operator new(bytes, C, alignment);
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void* operator new(size_t bytes, ASTContext* C,
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                     unsigned alignment = 8) throw() {
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ::operator new(bytes, *C, alignment);
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void* operator new(size_t bytes, void* mem) throw() {
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return mem;
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void operator delete(void*, ASTContext&, unsigned) throw() { }
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void operator delete(void*, ASTContext*, unsigned) throw() { }
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void operator delete(void*, std::size_t) throw() { }
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void operator delete(void*, void*) throw() { }
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief A placeholder type used to construct an empty shell of a
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// type, that will be filled in later (e.g., by some
1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// de-serialization).
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  struct EmptyShell { };
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///  recursively release child AST nodes.
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void DestroyChildren(ASTContext& Ctx);
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Construct an empty statement.
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC), RefCount(1) {
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Virtual method that performs the actual destruction of
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// this statement.
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Subclasses should override this method (not Destroy()) to
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// provide class-specific destruction.
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void DoDestroy(ASTContext &Ctx);
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt(StmtClass SC) : sClass(SC), RefCount(1) {
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual ~Stmt() {}
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef NDEBUG
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief True if this statement's refcount is in a valid state.
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Should be used only in assertions.
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isRetained() const {
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return (RefCount >= 1);
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Destroy the current statement and its children.
1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Destroy(ASTContext &Ctx) {
1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(RefCount >= 1);
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (--RefCount == 0)
19073322924127c873c13101b705dd823f5539ffa5fSteve Naroff      DoDestroy(Ctx);
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Increases the reference count for this statement.
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Invoke the Retain() operation when this statement or expression
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// is being shared by another owner.
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt *Retain() {
1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(RefCount >= 1);
1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ++RefCount;
2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return this;
2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtClass getStmtClass() const {
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(RefCount >= 1 && "Referencing already-destroyed statement!");
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return (StmtClass)sClass;
2068b9023ba35a86838789e2c9034a6128728c547aaChris Lattner  }
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const char *getStmtClassName() const;
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SourceLocation tokens are not useful in isolation - they are low level
2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// value objects created/interpreted by SourceManager. We assume AST
2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// clients will have a pointer to the respective SourceManager.
2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual SourceRange getSourceRange() const = 0;
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // global temp stats (until we have a per-module visitor)
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void addStmtClass(const StmtClass s);
2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool CollectingStats(bool Enable = false);
2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static void PrintStats();
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// dump - This does a local dump of the specified AST fragment.  It dumps the
2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// specified node and a few nodes underneath it, but not the whole subtree.
2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// This is useful in a debugger.
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void dump() const;
2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void dump(SourceManager &SM) const;
2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void dumpAll() const;
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void dumpAll(SourceManager &SM) const;
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// back to its original source language syntax.
2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void dumpPretty(ASTContext& Context) const;
2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper,
2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   const PrintingPolicy &Policy,
2367a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner                   unsigned Indentation = 0) const {
2377064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff    printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation);
2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2397064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  void printPretty(llvm::raw_ostream &OS, ASTContext &Context,
2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                   PrinterHelper *Helper,
2417064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff                   const PrintingPolicy &Policy,
2427a2e047c602d6ba28d6c434c990d4b9f7ef8c694Chris Lattner                   unsigned Indentation = 0) const;
243251dcaf8616c6f04051e214f35cadb7de42aef7eBill Wendling
244700204c74b455746752e851b25565ebf932f5340Steve Naroff  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
245dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
2467064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  void viewAST() const;
2477064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff
2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Implement isa<T> support.
2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Stmt *) { return true; }
2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///  contain implicit control-flow in the order their subexpressions
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///  are evaluated.  This predicate returns true if this statement has
2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///  such implicit control-flow.  Such statements are also specially handled
2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///  within CFGs.
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool hasImplicitControlFlow() const;
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Child Iterators: All subclasses must implement child_begin and child_end
2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///  to permit easy iteration over the substatements/subexpessions of an
2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///  AST node.  This permits easy iteration over all nodes in the AST.
2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef StmtIterator       child_iterator;
2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef ConstStmtIterator  const_child_iterator;
2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_begin() = 0;
2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_end()   = 0;
2665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const_child_iterator child_begin() const {
268590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const_child_iterator child_end() const {
2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Produce a unique representation of the given statement.
2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief ID once the profiling operation is complete, will contain
2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// the unique representation of the given statement.
2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Context the AST context in which the statement resides
2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Canonical whether the profile should be based on the canonical
2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// representation of this statement (e.g., where non-type template
2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// parameters are identified by index/level rather than their
2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// declaration pointers) or the exact representation of the statement as
2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// written in the source.
2875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer               bool Canonical);
2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
2905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// DeclStmt - Adaptor class for mixing declarations with statements and
2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// expressions. For example, CompoundStmt mixes statements, expressions
2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// and declarations (variables, types). Another example is ForStmt, where
2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the first statement can be an expression or a declaration.
2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass DeclStmt : public Stmt {
2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DeclGroupRef DG;
2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation StartLoc, EndLoc;
2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void DoDestroy(ASTContext &Ctx);
3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                    StartLoc(startLoc), EndLoc(endLoc) {}
3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Build an empty declaration statement.
3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isSingleDecl - This method returns true if this DeclStmt refers
3125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// to a single Decl.
3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isSingleDecl() const {
3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return DG.isSingleDecl();
3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Decl *getSingleDecl() { return DG.getSingleDecl(); }
3195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const DeclGroupRef getDeclGroup() const { return DG; }
3215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DeclGroupRef getDeclGroup() { return DG; }
3225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getStartLoc() const { return StartLoc; }
3255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setStartLoc(SourceLocation L) { StartLoc = L; }
3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getEndLoc() const { return EndLoc; }
3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setEndLoc(SourceLocation L) { EndLoc = L; }
3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceRange getSourceRange() const {
3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return SourceRange(StartLoc, EndLoc);
3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Stmt *T) {
3345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getStmtClass() == DeclStmtClass;
3355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const DeclStmt *) { return true; }
3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Iterators over subexpressions.
3395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_begin();
3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_end();
3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef DeclGroupRef::iterator decl_iterator;
3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef DeclGroupRef::const_iterator const_decl_iterator;
3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  decl_iterator decl_begin() { return DG.begin(); }
3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  decl_iterator decl_end() { return DG.end(); }
3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const_decl_iterator decl_begin() const { return DG.begin(); }
3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const_decl_iterator decl_end() const { return DG.end(); }
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// NullStmt - This is the null statement ";": C99 6.8.3p3.
3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass NullStmt : public Stmt {
3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation SemiLoc;
3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Build an empty null statement.
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { }
3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getSemiLoc() const { return SemiLoc; }
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setSemiLoc(SourceLocation L) { SemiLoc = L; }
3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Stmt *T) {
3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getStmtClass() == NullStmtClass;
3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const NullStmt *) { return true; }
3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Iterators
3725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_begin();
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_end();
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// CompoundStmt - This represents a group of statements like { stmt stmt }.
3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass CompoundStmt : public Stmt {
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt** Body;
3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned NumStmts;
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation LBracLoc, RBracLoc;
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                             SourceLocation LB, SourceLocation RB)
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (NumStmts == 0) {
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Body = 0;
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return;
3895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Body = new (C) Stmt*[NumStmts];
3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    memcpy(Body, StmtStart, numStmts * sizeof(*Body));
3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // \brief Build an empty compound statement.
3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit CompoundStmt(EmptyShell Empty)
3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : Stmt(CompoundStmtClass, Empty), Body(0), NumStmts(0) { }
3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts);
4005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool body_empty() const { return NumStmts == 0; }
4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned size() const { return NumStmts; }
4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef Stmt** body_iterator;
4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  body_iterator body_begin() { return Body; }
4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  body_iterator body_end() { return Body + NumStmts; }
4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef Stmt* const * const_body_iterator;
4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const_body_iterator body_begin() const { return Body; }
4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const_body_iterator body_end() const { return Body + NumStmts; }
4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
4155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  reverse_body_iterator body_rbegin() {
4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return reverse_body_iterator(body_end());
4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  reverse_body_iterator body_rend() {
4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return reverse_body_iterator(body_begin());
4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef std::reverse_iterator<const_body_iterator>
4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          const_reverse_body_iterator;
4245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const_reverse_body_iterator body_rbegin() const {
4265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return const_reverse_body_iterator(body_end());
4275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const_reverse_body_iterator body_rend() const {
4305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return const_reverse_body_iterator(body_begin());
4315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual SourceRange getSourceRange() const {
4345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return SourceRange(LBracLoc, RBracLoc);
4355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4368b9023ba35a86838789e2c9034a6128728c547aaChris Lattner
4375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getLBracLoc() const { return LBracLoc; }
4385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setLBracLoc(SourceLocation L) { LBracLoc = L; }
4395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getRBracLoc() const { return RBracLoc; }
4405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setRBracLoc(SourceLocation L) { RBracLoc = L; }
4415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4428b9023ba35a86838789e2c9034a6128728c547aaChris Lattner  static bool classof(const Stmt *T) {
4435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getStmtClass() == CompoundStmtClass;
4445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const CompoundStmt *) { return true; }
4465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Iterators
4485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_begin();
4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_end();
4505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
4515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// SwitchCase is the base class for CaseStmt and DefaultStmt,
4535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass SwitchCase : public Stmt {
4545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
4555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // A pointer to the following CaseStmt or DefaultStmt class,
4565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // used by SwitchStmt.
4575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SwitchCase *NextSwitchCase;
45873322924127c873c13101b705dd823f5539ffa5fSteve Naroff
45973322924127c873c13101b705dd823f5539ffa5fSteve Naroff  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
46073322924127c873c13101b705dd823f5539ffa5fSteve Naroff
46173322924127c873c13101b705dd823f5539ffa5fSteve Naroffpublic:
4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
46373322924127c873c13101b705dd823f5539ffa5fSteve Naroff
4645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
4655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt *getSubStmt() { return v_getSubStmt(); }
4695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
47073322924127c873c13101b705dd823f5539ffa5fSteve Naroff  virtual SourceRange getSourceRange() const { return SourceRange(); }
47173322924127c873c13101b705dd823f5539ffa5fSteve Naroff
47273322924127c873c13101b705dd823f5539ffa5fSteve Naroff  static bool classof(const Stmt *T) {
47373322924127c873c13101b705dd823f5539ffa5fSteve Naroff    return T->getStmtClass() == CaseStmtClass ||
47473322924127c873c13101b705dd823f5539ffa5fSteve Naroff    T->getStmtClass() == DefaultStmtClass;
4755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const SwitchCase *) { return true; }
4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual Stmt* v_getSubStmt() = 0;
4795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
4805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass CaseStmt : public SwitchCase {
4825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum { SUBSTMT, LHS, RHS, END_EXPR };
4835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
48473322924127c873c13101b705dd823f5539ffa5fSteve Naroff                             // GNU "case 1 ... 4" extension
4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation CaseLoc;
48673322924127c873c13101b705dd823f5539ffa5fSteve Naroff  SourceLocation EllipsisLoc;
48773322924127c873c13101b705dd823f5539ffa5fSteve Naroff  SourceLocation ColonLoc;
4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
4895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
49073322924127c873c13101b705dd823f5539ffa5fSteve Naroffpublic:
49173322924127c873c13101b705dd823f5539ffa5fSteve Naroff  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
49273322924127c873c13101b705dd823f5539ffa5fSteve Naroff           SourceLocation ellipsisLoc, SourceLocation colonLoc)
49373322924127c873c13101b705dd823f5539ffa5fSteve Naroff    : SwitchCase(CaseStmtClass) {
4945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SubExprs[SUBSTMT] = 0;
4955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
4965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
4975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CaseLoc = caseLoc;
49873322924127c873c13101b705dd823f5539ffa5fSteve Naroff    EllipsisLoc = ellipsisLoc;
49973322924127c873c13101b705dd823f5539ffa5fSteve Naroff    ColonLoc = colonLoc;
50073322924127c873c13101b705dd823f5539ffa5fSteve Naroff  }
50173322924127c873c13101b705dd823f5539ffa5fSteve Naroff
50273322924127c873c13101b705dd823f5539ffa5fSteve Naroff  /// \brief Build an empty switch case statement.
50373322924127c873c13101b705dd823f5539ffa5fSteve Naroff  explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { }
50473322924127c873c13101b705dd823f5539ffa5fSteve Naroff
50573322924127c873c13101b705dd823f5539ffa5fSteve Naroff  SourceLocation getCaseLoc() const { return CaseLoc; }
50673322924127c873c13101b705dd823f5539ffa5fSteve Naroff  void setCaseLoc(SourceLocation L) { CaseLoc = L; }
507e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
508e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
509e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  SourceLocation getColonLoc() const { return ColonLoc; }
510e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  void setColonLoc(SourceLocation L) { ColonLoc = L; }
511e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff
512e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
513e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
514e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
515e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff
516e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  const Expr *getLHS() const {
517e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
518e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  }
519e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  const Expr *getRHS() const {
520e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
521e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  }
522e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
523e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff
524e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
525e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
526e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
527e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff
528e1b31fedbc006e6e4071bbb4f74c6116b56cfa9fSteve Naroff
5297064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff  virtual SourceRange getSourceRange() const {
5307064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff    // Handle deeply nested case statements with iteration instead of recursion.
5317064f5c95bbdb17680d0ea658d4090898c2592d3Steve Naroff    const CaseStmt *CS = this;
53273322924127c873c13101b705dd823f5539ffa5fSteve Naroff    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
53373322924127c873c13101b705dd823f5539ffa5fSteve Naroff      CS = CS2;
53473322924127c873c13101b705dd823f5539ffa5fSteve Naroff
53573322924127c873c13101b705dd823f5539ffa5fSteve Naroff    return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
53673322924127c873c13101b705dd823f5539ffa5fSteve Naroff  }
53773322924127c873c13101b705dd823f5539ffa5fSteve Naroff  static bool classof(const Stmt *T) {
5385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getStmtClass() == CaseStmtClass;
5395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const CaseStmt *) { return true; }
5415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Iterators
5435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_begin();
5445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_end();
5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
5465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass DefaultStmt : public SwitchCase {
5485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt* SubStmt;
5495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation DefaultLoc;
5505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ColonLoc;
5515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
5525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
5535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
5545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL),
5555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ColonLoc(CL) {}
5565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Build an empty default statement.
5585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { }
5595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt *getSubStmt() { return SubStmt; }
5615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const Stmt *getSubStmt() const { return SubStmt; }
5625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setSubStmt(Stmt *S) { SubStmt = S; }
5635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getDefaultLoc() const { return DefaultLoc; }
5655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setDefaultLoc(SourceLocation L) { DefaultLoc = L; }
5665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getColonLoc() const { return ColonLoc; }
5675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setColonLoc(SourceLocation L) { ColonLoc = L; }
5685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual SourceRange getSourceRange() const {
5705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
5715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Stmt *T) {
5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getStmtClass() == DefaultStmtClass;
5745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const DefaultStmt *) { return true; }
5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Iterators
5785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_begin();
5795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_end();
5805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
5815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass LabelStmt : public Stmt {
5835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo *Label;
5845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt *SubStmt;
5855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation IdentLoc;
5865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
5875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : Stmt(LabelStmtClass), Label(label),
5895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SubStmt(substmt), IdentLoc(IL) {}
5905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // \brief Build an empty label statement.
5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getIdentLoc() const { return IdentLoc; }
5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IdentifierInfo *getID() const { return Label; }
596942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  void setID(IdentifierInfo *II) { Label = II; }
597942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  const char *getName() const;
5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt *getSubStmt() { return SubStmt; }
5995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const Stmt *getSubStmt() const { return SubStmt; }
6005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
6015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setSubStmt(Stmt *SS) { SubStmt = SS; }
6025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual SourceRange getSourceRange() const {
6045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return SourceRange(IdentLoc, SubStmt->getLocEnd());
605942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  }
606942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  static bool classof(const Stmt *T) {
6075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getStmtClass() == LabelStmtClass;
6085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const LabelStmt *) { return true; }
6105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Iterators
612942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  virtual child_iterator child_begin();
6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_end();
6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
6155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// IfStmt - This represents an if/then/else.
618942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner///
619942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattnerclass IfStmt : public Stmt {
620942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  enum { COND, THEN, ELSE, END_EXPR };
621942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner  Stmt* SubExprs[END_EXPR];
6225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief If non-NULL, the declaration in the "if" statement.
6245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  VarDecl *Var;
6255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation IfLoc;
6275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ElseLoc;
6285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  IfStmt(SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then,
6315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         SourceLocation EL = SourceLocation(), Stmt *elsev = 0)
632942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    : Stmt(IfStmtClass), Var(var), IfLoc(IL), ElseLoc(EL)  {
633942cfd37297528918616d06cd6e4e8bd6e4915a2Chris Lattner    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
6345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SubExprs[THEN] = then;
6355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SubExprs[ELSE] = elsev;
6365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Build an empty if/then/else statement
6395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
6405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Retrieve the variable declared in this "if" statement, if any.
6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// In the following example, "x" is the condition variable.
6445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \code
6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// if (int x = foo()) {
646a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  ///   printf("x is %d", x);
647a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// }
648a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  /// \endcode
649a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  VarDecl *getConditionVariable() const { return Var; }
650a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  void setConditionVariable(VarDecl *V) { Var = V; }
651a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner
652a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
653a2c7767ce7d8feb10253f4b650826a20f3324c6fChris Lattner  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const Stmt *getThen() const { return SubExprs[THEN]; }
6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setThen(Stmt *S) { SubExprs[THEN] = S; }
6565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const Stmt *getElse() const { return SubExprs[ELSE]; }
6575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setElse(Stmt *S) { SubExprs[ELSE] = S; }
6585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
6605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt *getThen() { return SubExprs[THEN]; }
6615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt *getElse() { return SubExprs[ELSE]; }
6625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getIfLoc() const { return IfLoc; }
6645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setIfLoc(SourceLocation L) { IfLoc = L; }
6655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation getElseLoc() const { return ElseLoc; }
6665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void setElseLoc(SourceLocation L) { ElseLoc = L; }
6675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual SourceRange getSourceRange() const {
6695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (SubExprs[ELSE])
6705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
6715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else
6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
6735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Stmt *T) {
6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return T->getStmtClass() == IfStmtClass;
6775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const IfStmt *) { return true; }
6795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Iterators over subexpressions.  The iterators will include iterating
6815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // over the initialization expression referenced by the condition variable.
682dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroff  virtual child_iterator child_begin();
6835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual child_iterator child_end();
6845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
685dfa6aae5a119a527e537c35566ba3272fd8c5d74Steve Naroffprotected:
6865d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  virtual void DoDestroy(ASTContext &Ctx);
6875d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner};
6885d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner
6895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// SwitchStmt - This represents a 'switch' stmt.
6905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
6915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass SwitchStmt : public Stmt {
6925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum { COND, BODY, END_EXPR };
6935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Stmt* SubExprs[END_EXPR];
6945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  VarDecl *Var;
6955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // This points to a linked list of case and default statements.
6965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SwitchCase *FirstCase;
6975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation SwitchLoc;
6985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
7005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  virtual void DoDestroy(ASTContext &Ctx);
7015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
7035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SwitchStmt(VarDecl *Var, Expr *cond)
7045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : Stmt(SwitchStmtClass), Var(Var), FirstCase(0)
7055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  {
7065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
7075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SubExprs[BODY] = NULL;
7085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
7095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Build a empty switch statement.
7115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
7125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \brief Retrieve the variable declared in this "switch" statement, if any.
7145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
7155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// In the following example, "x" is the condition variable.
7165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// \code
7175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// switch (int x = foo()) {
718  ///   case 0: break;
719  ///   // ...
720  /// }
721  /// \endcode
722  VarDecl *getConditionVariable() const { return Var; }
723  void setConditionVariable(VarDecl *V) { Var = V; }
724
725  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
726  const Stmt *getBody() const { return SubExprs[BODY]; }
727  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
728
729  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
730  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
731  Stmt *getBody() { return SubExprs[BODY]; }
732  void setBody(Stmt *S) { SubExprs[BODY] = S; }
733  SwitchCase *getSwitchCaseList() { return FirstCase; }
734
735  /// \brief Set the case list for this switch statement.
736  ///
737  /// The caller is responsible for incrementing the retain counts on
738  /// all of the SwitchCase statements in this list.
739  void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
740
741  SourceLocation getSwitchLoc() const { return SwitchLoc; }
742  void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
743
744  void setBody(Stmt *S, SourceLocation SL) {
745    SubExprs[BODY] = S;
746    SwitchLoc = SL;
747  }
748  void addSwitchCase(SwitchCase *SC) {
749    assert(!SC->getNextSwitchCase() && "case/default already added to a switch");
750    SC->Retain();
751    SC->setNextSwitchCase(FirstCase);
752    FirstCase = SC;
753  }
754  virtual SourceRange getSourceRange() const {
755    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
756  }
757  static bool classof(const Stmt *T) {
758    return T->getStmtClass() == SwitchStmtClass;
759  }
760  static bool classof(const SwitchStmt *) { return true; }
761
762  // Iterators
763  virtual child_iterator child_begin();
764  virtual child_iterator child_end();
765};
766
767
768/// WhileStmt - This represents a 'while' stmt.
769///
770class WhileStmt : public Stmt {
771  enum { COND, BODY, END_EXPR };
772  VarDecl *Var;
773  Stmt* SubExprs[END_EXPR];
774  SourceLocation WhileLoc;
775public:
776  WhileStmt(VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL)
777    : Stmt(WhileStmtClass), Var(Var)
778  {
779    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
780    SubExprs[BODY] = body;
781    WhileLoc = WL;
782  }
783
784  /// \brief Build an empty while statement.
785  explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
786
787  /// \brief Retrieve the variable declared in this "while" statement, if any.
788  ///
789  /// In the following example, "x" is the condition variable.
790  /// \code
791  /// while (int x = random()) {
792  ///   // ...
793  /// }
794  /// \endcode
795  VarDecl *getConditionVariable() const { return Var; }
796  void setConditionVariable(VarDecl *V) { Var = V; }
797
798  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
799  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
800  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
801  Stmt *getBody() { return SubExprs[BODY]; }
802  const Stmt *getBody() const { return SubExprs[BODY]; }
803  void setBody(Stmt *S) { SubExprs[BODY] = S; }
804
805  SourceLocation getWhileLoc() const { return WhileLoc; }
806  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
807
808  virtual SourceRange getSourceRange() const {
809    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
810  }
811  static bool classof(const Stmt *T) {
812    return T->getStmtClass() == WhileStmtClass;
813  }
814  static bool classof(const WhileStmt *) { return true; }
815
816  // Iterators
817  virtual child_iterator child_begin();
818  virtual child_iterator child_end();
819
820protected:
821  virtual void DoDestroy(ASTContext &Ctx);
822};
823
824/// DoStmt - This represents a 'do/while' stmt.
825///
826class DoStmt : public Stmt {
827  enum { COND, BODY, END_EXPR };
828  Stmt* SubExprs[END_EXPR];
829  SourceLocation DoLoc;
830  SourceLocation WhileLoc;
831  SourceLocation RParenLoc;  // Location of final ')' in do stmt condition.
832
833public:
834  DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
835         SourceLocation RP)
836    : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
837    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
838    SubExprs[BODY] = body;
839  }
840
841  /// \brief Build an empty do-while statement.
842  explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
843
844  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
845  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
846  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
847  Stmt *getBody() { return SubExprs[BODY]; }
848  const Stmt *getBody() const { return SubExprs[BODY]; }
849  void setBody(Stmt *S) { SubExprs[BODY] = S; }
850
851  SourceLocation getDoLoc() const { return DoLoc; }
852  void setDoLoc(SourceLocation L) { DoLoc = L; }
853  SourceLocation getWhileLoc() const { return WhileLoc; }
854  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
855
856  SourceLocation getRParenLoc() const { return RParenLoc; }
857  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
858
859  virtual SourceRange getSourceRange() const {
860    return SourceRange(DoLoc, RParenLoc);
861  }
862  static bool classof(const Stmt *T) {
863    return T->getStmtClass() == DoStmtClass;
864  }
865  static bool classof(const DoStmt *) { return true; }
866
867  // Iterators
868  virtual child_iterator child_begin();
869  virtual child_iterator child_end();
870};
871
872
873/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
874/// the init/cond/inc parts of the ForStmt will be null if they were not
875/// specified in the source.
876///
877class ForStmt : public Stmt {
878  enum { INIT, COND, INC, BODY, END_EXPR };
879  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
880  VarDecl *CondVar;
881  SourceLocation ForLoc;
882  SourceLocation LParenLoc, RParenLoc;
883
884public:
885  ForStmt(Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body,
886          SourceLocation FL, SourceLocation LP, SourceLocation RP)
887    : Stmt(ForStmtClass), CondVar(condVar), ForLoc(FL), LParenLoc(LP),
888      RParenLoc(RP)
889  {
890    SubExprs[INIT] = Init;
891    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
892    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
893    SubExprs[BODY] = Body;
894  }
895
896  /// \brief Build an empty for statement.
897  explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
898
899  Stmt *getInit() { return SubExprs[INIT]; }
900
901  /// \brief Retrieve the variable declared in this "for" statement, if any.
902  ///
903  /// In the following example, "y" is the condition variable.
904  /// \code
905  /// for (int x = random(); int y = mangle(x); ++x) {
906  ///   // ...
907  /// }
908  /// \endcode
909  VarDecl *getConditionVariable() const { return CondVar; }
910  void setConditionVariable(VarDecl *V) { CondVar = V; }
911
912  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
913  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
914  Stmt *getBody() { return SubExprs[BODY]; }
915
916  const Stmt *getInit() const { return SubExprs[INIT]; }
917  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
918  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
919  const Stmt *getBody() const { return SubExprs[BODY]; }
920
921  void setInit(Stmt *S) { SubExprs[INIT] = S; }
922  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
923  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
924  void setBody(Stmt *S) { SubExprs[BODY] = S; }
925
926  SourceLocation getForLoc() const { return ForLoc; }
927  void setForLoc(SourceLocation L) { ForLoc = L; }
928  SourceLocation getLParenLoc() const { return LParenLoc; }
929  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
930  SourceLocation getRParenLoc() const { return RParenLoc; }
931  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
932
933  virtual SourceRange getSourceRange() const {
934    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
935  }
936  static bool classof(const Stmt *T) {
937    return T->getStmtClass() == ForStmtClass;
938  }
939  static bool classof(const ForStmt *) { return true; }
940
941  // Iterators
942  virtual child_iterator child_begin();
943  virtual child_iterator child_end();
944
945protected:
946  virtual void DoDestroy(ASTContext &Ctx);
947};
948
949/// GotoStmt - This represents a direct goto.
950///
951class GotoStmt : public Stmt {
952  LabelStmt *Label;
953  SourceLocation GotoLoc;
954  SourceLocation LabelLoc;
955public:
956  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
957    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
958
959  /// \brief Build an empty goto statement.
960  explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
961
962  LabelStmt *getLabel() const { return Label; }
963  void setLabel(LabelStmt *S) { Label = S; }
964
965  SourceLocation getGotoLoc() const { return GotoLoc; }
966  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
967  SourceLocation getLabelLoc() const { return LabelLoc; }
968  void setLabelLoc(SourceLocation L) { LabelLoc = L; }
969
970  virtual SourceRange getSourceRange() const {
971    return SourceRange(GotoLoc, LabelLoc);
972  }
973  static bool classof(const Stmt *T) {
974    return T->getStmtClass() == GotoStmtClass;
975  }
976  static bool classof(const GotoStmt *) { return true; }
977
978  // Iterators
979  virtual child_iterator child_begin();
980  virtual child_iterator child_end();
981};
982
983/// IndirectGotoStmt - This represents an indirect goto.
984///
985class IndirectGotoStmt : public Stmt {
986  SourceLocation GotoLoc;
987  SourceLocation StarLoc;
988  Stmt *Target;
989public:
990  IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
991                   Expr *target)
992    : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
993      Target((Stmt*)target) {}
994
995  /// \brief Build an empty indirect goto statement.
996  explicit IndirectGotoStmt(EmptyShell Empty)
997    : Stmt(IndirectGotoStmtClass, Empty) { }
998
999  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
1000  SourceLocation getGotoLoc() const { return GotoLoc; }
1001  void setStarLoc(SourceLocation L) { StarLoc = L; }
1002  SourceLocation getStarLoc() const { return StarLoc; }
1003
1004  Expr *getTarget();
1005  const Expr *getTarget() const;
1006  void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
1007
1008  virtual SourceRange getSourceRange() const {
1009    return SourceRange(GotoLoc, Target->getLocEnd());
1010  }
1011
1012  static bool classof(const Stmt *T) {
1013    return T->getStmtClass() == IndirectGotoStmtClass;
1014  }
1015  static bool classof(const IndirectGotoStmt *) { return true; }
1016
1017  // Iterators
1018  virtual child_iterator child_begin();
1019  virtual child_iterator child_end();
1020};
1021
1022
1023/// ContinueStmt - This represents a continue.
1024///
1025class ContinueStmt : public Stmt {
1026  SourceLocation ContinueLoc;
1027public:
1028  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
1029
1030  /// \brief Build an empty continue statement.
1031  explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
1032
1033  SourceLocation getContinueLoc() const { return ContinueLoc; }
1034  void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
1035
1036  virtual SourceRange getSourceRange() const {
1037    return SourceRange(ContinueLoc);
1038  }
1039
1040  static bool classof(const Stmt *T) {
1041    return T->getStmtClass() == ContinueStmtClass;
1042  }
1043  static bool classof(const ContinueStmt *) { return true; }
1044
1045  // Iterators
1046  virtual child_iterator child_begin();
1047  virtual child_iterator child_end();
1048};
1049
1050/// BreakStmt - This represents a break.
1051///
1052class BreakStmt : public Stmt {
1053  SourceLocation BreakLoc;
1054public:
1055  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
1056
1057  /// \brief Build an empty break statement.
1058  explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
1059
1060  SourceLocation getBreakLoc() const { return BreakLoc; }
1061  void setBreakLoc(SourceLocation L) { BreakLoc = L; }
1062
1063  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
1064
1065  static bool classof(const Stmt *T) {
1066    return T->getStmtClass() == BreakStmtClass;
1067  }
1068  static bool classof(const BreakStmt *) { return true; }
1069
1070  // Iterators
1071  virtual child_iterator child_begin();
1072  virtual child_iterator child_end();
1073};
1074
1075
1076/// ReturnStmt - This represents a return, optionally of an expression:
1077///   return;
1078///   return 4;
1079///
1080/// Note that GCC allows return with no argument in a function declared to
1081/// return a value, and it allows returning a value in functions declared to
1082/// return void.  We explicitly model this in the AST, which means you can't
1083/// depend on the return type of the function and the presence of an argument.
1084///
1085class ReturnStmt : public Stmt {
1086  Stmt *RetExpr;
1087  SourceLocation RetLoc;
1088  const VarDecl *NRVOCandidate;
1089
1090public:
1091  ReturnStmt(SourceLocation RL)
1092    : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
1093
1094  ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
1095    : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
1096      NRVOCandidate(NRVOCandidate) {}
1097
1098  /// \brief Build an empty return expression.
1099  explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
1100
1101  const Expr *getRetValue() const;
1102  Expr *getRetValue();
1103  void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
1104
1105  SourceLocation getReturnLoc() const { return RetLoc; }
1106  void setReturnLoc(SourceLocation L) { RetLoc = L; }
1107
1108  /// \brief Retrieve the variable that might be used for the named return
1109  /// value optimization.
1110  ///
1111  /// The optimization itself can only be performed if the variable is
1112  /// also marked as an NRVO object.
1113  const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
1114  void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
1115
1116  virtual SourceRange getSourceRange() const;
1117
1118  static bool classof(const Stmt *T) {
1119    return T->getStmtClass() == ReturnStmtClass;
1120  }
1121  static bool classof(const ReturnStmt *) { return true; }
1122
1123  // Iterators
1124  virtual child_iterator child_begin();
1125  virtual child_iterator child_end();
1126};
1127
1128/// AsmStmt - This represents a GNU inline-assembly statement extension.
1129///
1130class AsmStmt : public Stmt {
1131  SourceLocation AsmLoc, RParenLoc;
1132  StringLiteral *AsmStr;
1133
1134  bool IsSimple;
1135  bool IsVolatile;
1136  bool MSAsm;
1137
1138  unsigned NumOutputs;
1139  unsigned NumInputs;
1140  unsigned NumClobbers;
1141
1142  // FIXME: If we wanted to, we could allocate all of these in one big array.
1143  IdentifierInfo **Names;
1144  StringLiteral **Constraints;
1145  Stmt **Exprs;
1146  StringLiteral **Clobbers;
1147
1148protected:
1149  virtual void DoDestroy(ASTContext &Ctx);
1150
1151public:
1152  AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
1153          bool msasm, unsigned numoutputs, unsigned numinputs,
1154          IdentifierInfo **names, StringLiteral **constraints,
1155          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
1156          StringLiteral **clobbers, SourceLocation rparenloc);
1157
1158  /// \brief Build an empty inline-assembly statement.
1159  explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
1160    Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
1161
1162  SourceLocation getAsmLoc() const { return AsmLoc; }
1163  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
1164  SourceLocation getRParenLoc() const { return RParenLoc; }
1165  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1166
1167  bool isVolatile() const { return IsVolatile; }
1168  void setVolatile(bool V) { IsVolatile = V; }
1169  bool isSimple() const { return IsSimple; }
1170  void setSimple(bool V) { IsSimple = V; }
1171  bool isMSAsm() const { return MSAsm; }
1172  void setMSAsm(bool V) { MSAsm = V; }
1173
1174  //===--- Asm String Analysis ---===//
1175
1176  const StringLiteral *getAsmString() const { return AsmStr; }
1177  StringLiteral *getAsmString() { return AsmStr; }
1178  void setAsmString(StringLiteral *E) { AsmStr = E; }
1179
1180  /// AsmStringPiece - this is part of a decomposed asm string specification
1181  /// (for use with the AnalyzeAsmString function below).  An asm string is
1182  /// considered to be a concatenation of these parts.
1183  class AsmStringPiece {
1184  public:
1185    enum Kind {
1186      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
1187      Operand  // Operand reference, with optional modifier %c4.
1188    };
1189  private:
1190    Kind MyKind;
1191    std::string Str;
1192    unsigned OperandNo;
1193  public:
1194    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
1195    AsmStringPiece(unsigned OpNo, char Modifier)
1196      : MyKind(Operand), Str(), OperandNo(OpNo) {
1197      Str += Modifier;
1198    }
1199
1200    bool isString() const { return MyKind == String; }
1201    bool isOperand() const { return MyKind == Operand; }
1202
1203    const std::string &getString() const {
1204      assert(isString());
1205      return Str;
1206    }
1207
1208    unsigned getOperandNo() const {
1209      assert(isOperand());
1210      return OperandNo;
1211    }
1212
1213    /// getModifier - Get the modifier for this operand, if present.  This
1214    /// returns '\0' if there was no modifier.
1215    char getModifier() const {
1216      assert(isOperand());
1217      return Str[0];
1218    }
1219  };
1220
1221  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
1222  /// it into pieces.  If the asm string is erroneous, emit errors and return
1223  /// true, otherwise return false.  This handles canonicalization and
1224  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
1225  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
1226  unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
1227                            ASTContext &C, unsigned &DiagOffs) const;
1228
1229
1230  //===--- Output operands ---===//
1231
1232  unsigned getNumOutputs() const { return NumOutputs; }
1233
1234  IdentifierInfo *getOutputIdentifier(unsigned i) const {
1235    return Names[i];
1236  }
1237
1238  llvm::StringRef getOutputName(unsigned i) const {
1239    if (IdentifierInfo *II = getOutputIdentifier(i))
1240      return II->getName();
1241
1242    return llvm::StringRef();
1243  }
1244
1245  /// getOutputConstraint - Return the constraint string for the specified
1246  /// output operand.  All output constraints are known to be non-empty (either
1247  /// '=' or '+').
1248  llvm::StringRef getOutputConstraint(unsigned i) const;
1249
1250  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
1251    return Constraints[i];
1252  }
1253  StringLiteral *getOutputConstraintLiteral(unsigned i) {
1254    return Constraints[i];
1255  }
1256
1257  Expr *getOutputExpr(unsigned i);
1258
1259  const Expr *getOutputExpr(unsigned i) const {
1260    return const_cast<AsmStmt*>(this)->getOutputExpr(i);
1261  }
1262
1263  /// isOutputPlusConstraint - Return true if the specified output constraint
1264  /// is a "+" constraint (which is both an input and an output) or false if it
1265  /// is an "=" constraint (just an output).
1266  bool isOutputPlusConstraint(unsigned i) const {
1267    return getOutputConstraint(i)[0] == '+';
1268  }
1269
1270  /// getNumPlusOperands - Return the number of output operands that have a "+"
1271  /// constraint.
1272  unsigned getNumPlusOperands() const;
1273
1274  //===--- Input operands ---===//
1275
1276  unsigned getNumInputs() const { return NumInputs; }
1277
1278  IdentifierInfo *getInputIdentifier(unsigned i) const {
1279    return Names[i + NumOutputs];
1280  }
1281
1282  llvm::StringRef getInputName(unsigned i) const {
1283    if (IdentifierInfo *II = getInputIdentifier(i))
1284      return II->getName();
1285
1286    return llvm::StringRef();
1287  }
1288
1289  /// getInputConstraint - Return the specified input constraint.  Unlike output
1290  /// constraints, these can be empty.
1291  llvm::StringRef getInputConstraint(unsigned i) const;
1292
1293  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
1294    return Constraints[i + NumOutputs];
1295  }
1296  StringLiteral *getInputConstraintLiteral(unsigned i) {
1297    return Constraints[i + NumOutputs];
1298  }
1299
1300  Expr *getInputExpr(unsigned i);
1301
1302  const Expr *getInputExpr(unsigned i) const {
1303    return const_cast<AsmStmt*>(this)->getInputExpr(i);
1304  }
1305
1306  void setOutputsAndInputsAndClobbers(ASTContext &C,
1307                                      IdentifierInfo **Names,
1308                                      StringLiteral **Constraints,
1309                                      Stmt **Exprs,
1310                                      unsigned NumOutputs,
1311                                      unsigned NumInputs,
1312                                      StringLiteral **Clobbers,
1313                                      unsigned NumClobbers);
1314
1315  //===--- Other ---===//
1316
1317  /// getNamedOperand - Given a symbolic operand reference like %[foo],
1318  /// translate this into a numeric value needed to reference the same operand.
1319  /// This returns -1 if the operand name is invalid.
1320  int getNamedOperand(llvm::StringRef SymbolicName) const;
1321
1322  unsigned getNumClobbers() const { return NumClobbers; }
1323  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
1324  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
1325
1326  virtual SourceRange getSourceRange() const {
1327    return SourceRange(AsmLoc, RParenLoc);
1328  }
1329
1330  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
1331  static bool classof(const AsmStmt *) { return true; }
1332
1333  // Input expr iterators.
1334
1335  typedef ExprIterator inputs_iterator;
1336  typedef ConstExprIterator const_inputs_iterator;
1337
1338  inputs_iterator begin_inputs() {
1339    return &Exprs[0] + NumOutputs;
1340  }
1341
1342  inputs_iterator end_inputs() {
1343    return &Exprs[0] + NumOutputs + NumInputs;
1344  }
1345
1346  const_inputs_iterator begin_inputs() const {
1347    return &Exprs[0] + NumOutputs;
1348  }
1349
1350  const_inputs_iterator end_inputs() const {
1351    return &Exprs[0] + NumOutputs + NumInputs;
1352  }
1353
1354  // Output expr iterators.
1355
1356  typedef ExprIterator outputs_iterator;
1357  typedef ConstExprIterator const_outputs_iterator;
1358
1359  outputs_iterator begin_outputs() {
1360    return &Exprs[0];
1361  }
1362  outputs_iterator end_outputs() {
1363    return &Exprs[0] + NumOutputs;
1364  }
1365
1366  const_outputs_iterator begin_outputs() const {
1367    return &Exprs[0];
1368  }
1369  const_outputs_iterator end_outputs() const {
1370    return &Exprs[0] + NumOutputs;
1371  }
1372
1373  // Child iterators
1374
1375  virtual child_iterator child_begin();
1376  virtual child_iterator child_end();
1377};
1378
1379}  // end namespace clang
1380
1381#endif
1382