Stmt.h revision 0632dd6fe068011af5710c0d6a745724021ff620
178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//                     The LLVM Compiler Infrastructure
478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// This file is distributed under the University of Illinois Open Source
678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// License. See LICENSE.TXT for details.
778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//===----------------------------------------------------------------------===//
978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
1078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//  This file defines the Stmt interface and subclasses.
1178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
1278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//===----------------------------------------------------------------------===//
1378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
1478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#ifndef LLVM_CLANG_AST_STMT_H
1578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#define LLVM_CLANG_AST_STMT_H
1678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
1778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/Support/Casting.h"
1878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/Support/raw_ostream.h"
1978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "clang/Basic/SourceLocation.h"
2078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "clang/AST/StmtIterator.h"
2178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "clang/AST/DeclGroup.h"
2278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/ADT/SmallVector.h"
2378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/ADT/iterator.h"
2478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/Bitcode/SerializationFwd.h"
2578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "clang/AST/ASTContext.h"
2678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include <string>
2778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochusing llvm::dyn_cast_or_null;
2878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
2978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochnamespace clang {
3078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class ASTContext;
3178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class Expr;
3278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class Decl;
3378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class ParmVarDecl;
3478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class QualType;
3578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class IdentifierInfo;
3678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class SourceManager;
3778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class StringLiteral;
3878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class SwitchStmt;
3978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class PrinterHelper;
4078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
4178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  //===----------------------------------------------------------------------===//
4278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
4378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
4478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  //  references to children (to be compatible with StmtIterator).
4578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  //===----------------------------------------------------------------------===//
4678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
4778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class Stmt;
4878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class Expr;
4978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
5078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class ExprIterator {
5178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    Stmt** I;
5278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  public:
5378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ExprIterator(Stmt** i) : I(i) {}
5478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ExprIterator() : I(0) {}
5578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ExprIterator& operator++() { ++I; return *this; }
5678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ExprIterator operator-(size_t i) { return I-i; }
5778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ExprIterator operator+(size_t i) { return I+i; }
5878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    Expr* operator[](size_t idx);
5978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    // FIXME: Verify that this will correctly return a signed distance.
6078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    signed operator-(const ExprIterator& R) const { return I - R.I; }
6178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    Expr* operator*() const;
6278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    Expr* operator->() const;
6378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool operator==(const ExprIterator& R) const { return I == R.I; }
6478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool operator!=(const ExprIterator& R) const { return I != R.I; }
6578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool operator>(const ExprIterator& R) const { return I > R.I; }
6678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
6778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  };
6878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
6978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  class ConstExprIterator {
7078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    Stmt* const * I;
7178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  public:
7278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ConstExprIterator(Stmt* const* i) : I(i) {}
7378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ConstExprIterator() : I(0) {}
7478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ConstExprIterator& operator++() { ++I; return *this; }
7578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ConstExprIterator operator+(size_t i) { return I+i; }
7678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ConstExprIterator operator-(size_t i) { return I-i; }
7778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    const Expr * operator[](size_t idx) const;
7878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
7978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    const Expr * operator*() const;
8078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    const Expr * operator->() const;
8178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
8278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
8378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
8478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
8578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  };
8678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
8778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//===----------------------------------------------------------------------===//
8878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// AST classes for statements.
8978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//===----------------------------------------------------------------------===//
9078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
9178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/// Stmt - This represents one statement.
9278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch///
9378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochclass Stmt {
9478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochpublic:
9578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  enum StmtClass {
9678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    NoStmtClass = 0,
9778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#define STMT(CLASS, PARENT) CLASS##Class,
9878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class,
9978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
10078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
10178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
10278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "clang/AST/StmtNodes.def"
10378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch};
10478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochprivate:
10578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  const StmtClass sClass;
10678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
10778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // Make vanilla 'new' and 'delete' illegal for Stmts.
10878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochprotected:
10978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void* operator new(size_t bytes) throw() {
11078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    assert(0 && "Stmts cannot be allocated with regular 'new'.");
11178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return 0;
11278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
11378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void operator delete(void* data) throw() {
11478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    assert(0 && "Stmts cannot be released with regular 'delete'.");
11578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
11678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
11778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochpublic:
11878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // Only allow allocation of Stmts using the allocator in ASTContext
11978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // or by doing a placement new.
12078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void* operator new(size_t bytes, ASTContext& C,
12178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch                     unsigned alignment = 16) throw() {
12278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return ::operator new(bytes, C, alignment);
12378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
12478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
12578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void* operator new(size_t bytes, ASTContext* C,
12678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch                     unsigned alignment = 16) throw() {
12778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return ::operator new(bytes, *C, alignment);
12878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
12978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
13078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void* operator new(size_t bytes, void* mem) throw() {
13178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return mem;
13278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
13378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
13478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void operator delete(void*, ASTContext& C) throw() { }
13578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void operator delete(void*, ASTContext& C, unsigned alignment) throw() { }
13678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void operator delete(void*, std::size_t) throw() { }
13778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
13878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochprotected:
13978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
14078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  ///  recursively release child AST nodes.
14178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void DestroyChildren(ASTContext& Ctx);
14278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
14378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochpublic:
14478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  Stmt(StmtClass SC) : sClass(SC) {
14578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
14678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
14778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual ~Stmt() {}
14878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
14978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual void Destroy(ASTContext &Ctx);
15078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
15178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  StmtClass getStmtClass() const { return sClass; }
15278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  const char *getStmtClassName() const;
15378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
15478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// SourceLocation tokens are not useful in isolation - they are low level
15578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// value objects created/interpreted by SourceManager. We assume AST
15678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// clients will have a pointer to the respective SourceManager.
15778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual SourceRange getSourceRange() const = 0;
15878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
15978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
16078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
16178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // global temp stats (until we have a per-module visitor)
16278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static void addStmtClass(const StmtClass s);
16378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static bool CollectingStats(bool enable=false);
16478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static void PrintStats();
16578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
16678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// dump - This does a local dump of the specified AST fragment.  It dumps the
16778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// specified node and a few nodes underneath it, but not the whole subtree.
16878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// This is useful in a debugger.
16978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void dump() const;
17078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void dump(SourceManager &SM) const;
17178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
17278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
17378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void dumpAll() const;
17478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void dumpAll(SourceManager &SM) const;
17578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
17678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
17778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// back to its original source language syntax.
17878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void dumpPretty() const;
17978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL, unsigned = 0,
18078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch                   bool NoIndent=false) const;
18178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
18278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
18378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
18478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void viewAST() const;
18578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
18678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // Implement isa<T> support.
18778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static bool classof(const Stmt *) { return true; }
18878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
18978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
19078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  ///  contain implicit control-flow in the order their subexpressions
19178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  ///  are evaluated.  This predicate returns true if this statement has
19278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  ///  such implicit control-flow.  Such statements are also specially handled
19378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  ///  within CFGs.
19478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  bool hasImplicitControlFlow() const;
19578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
19678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// Child Iterators: All subclasses must implement child_begin and child_end
19778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  ///  to permit easy iteration over the substatements/subexpessions of an
19878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  ///  AST node.  This permits easy iteration over all nodes in the AST.
19978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  typedef StmtIterator       child_iterator;
20078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  typedef ConstStmtIterator  const_child_iterator;
20178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
20278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual child_iterator child_begin() = 0;
20378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual child_iterator child_end()   = 0;
20478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
20578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  const_child_iterator child_begin() const {
20678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
20778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
20878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
20978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  const_child_iterator child_end() const {
21078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
21178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
21278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
21378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  void Emit(llvm::Serializer& S) const;
21478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static Stmt* Create(llvm::Deserializer& D, ASTContext& C);
21578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
21678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual void EmitImpl(llvm::Serializer& S) const {
21778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    // This method will eventually be a pure-virtual function.
21878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    assert (false && "Not implemented.");
21978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
22078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch};
22178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
22278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/// DeclStmt - Adaptor class for mixing declarations with statements and
22378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/// expressions. For example, CompoundStmt mixes statements, expressions
22478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/// and declarations (variables, types). Another example is ForStmt, where
22578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/// the first statement can be an expression or a declaration.
22678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch///
22778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochclass DeclStmt : public Stmt {
22878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochprotected:
22978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  DeclGroupRef DG;
23078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceLocation StartLoc, EndLoc;
23178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochpublic:
23278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
23378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
23478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch                                    StartLoc(startLoc), EndLoc(endLoc) {}
23578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
23678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual void Destroy(ASTContext& Ctx);
23778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
23878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// isSingleDecl - This method returns true if this DeclStmt refers
23978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  /// to a single Decl.
24078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  bool isSingleDecl() const {
24178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return DG.isSingleDecl();
24278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
24378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
24478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
24578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  Decl *getSingleDecl() { return DG.getSingleDecl(); }
24678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
24778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceLocation getStartLoc() const { return StartLoc; }
24878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceLocation getEndLoc() const { return EndLoc; }
24978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
25078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceRange getSourceRange() const {
25178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return SourceRange(StartLoc, EndLoc);
25278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
25378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
25478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static bool classof(const Stmt *T) {
25578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return T->getStmtClass() == DeclStmtClass;
25678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
25778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static bool classof(const DeclStmt *) { return true; }
25878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
25978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // Iterators over subexpressions.
26078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual child_iterator child_begin();
26178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual child_iterator child_end();
26278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
26378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  typedef DeclGroupRef::iterator decl_iterator;
26478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  typedef DeclGroupRef::const_iterator const_decl_iterator;
26578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
26678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  decl_iterator decl_begin() { return DG.begin(); }
26778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  decl_iterator decl_end() { return DG.end(); }
26878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  const_decl_iterator decl_begin() const { return DG.begin(); }
26978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  const_decl_iterator decl_end() const { return DG.end(); }
27078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
27178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // Serialization.
27278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual void EmitImpl(llvm::Serializer& S) const;
27378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static DeclStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
27478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch};
27578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
27678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/// NullStmt - This is the null statement ";": C99 6.8.3p3.
27778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch///
27878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochclass NullStmt : public Stmt {
27978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceLocation SemiLoc;
28078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochpublic:
28178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
28278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
28378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceLocation getSemiLoc() const { return SemiLoc; }
28478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
28578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
28678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
28778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static bool classof(const Stmt *T) {
28878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return T->getStmtClass() == NullStmtClass;
28978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
29078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static bool classof(const NullStmt *) { return true; }
29178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
29278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // Iterators
29378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual child_iterator child_begin();
29478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual child_iterator child_end();
29578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
29678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  virtual void EmitImpl(llvm::Serializer& S) const;
29778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  static NullStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
29878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch};
29978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
30078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch/// CompoundStmt - This represents a group of statements like { stmt stmt }.
30178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch///
30278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochclass CompoundStmt : public Stmt {
30378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  Stmt** Body;
30478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  unsigned NumStmts;
30578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SourceLocation LBracLoc, RBracLoc;
306public:
307  CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
308                             SourceLocation LB, SourceLocation RB)
309  : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
310    if (NumStmts == 0) {
311      Body = 0;
312      return;
313    }
314
315    Body = new (C) Stmt*[NumStmts];
316    memcpy(Body, StmtStart, numStmts * sizeof(*Body));
317  }
318
319  bool body_empty() const { return NumStmts == 0; }
320
321  typedef Stmt** body_iterator;
322  body_iterator body_begin() { return Body; }
323  body_iterator body_end() { return Body + NumStmts; }
324  Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
325
326  typedef Stmt* const * const_body_iterator;
327  const_body_iterator body_begin() const { return Body; }
328  const_body_iterator body_end() const { return Body + NumStmts; }
329  const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
330
331  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
332  reverse_body_iterator body_rbegin() {
333    return reverse_body_iterator(body_end());
334  }
335  reverse_body_iterator body_rend() {
336    return reverse_body_iterator(body_begin());
337  }
338
339  typedef std::reverse_iterator<const_body_iterator>
340          const_reverse_body_iterator;
341
342  const_reverse_body_iterator body_rbegin() const {
343    return const_reverse_body_iterator(body_end());
344  }
345
346  const_reverse_body_iterator body_rend() const {
347    return const_reverse_body_iterator(body_begin());
348  }
349
350  virtual SourceRange getSourceRange() const {
351    return SourceRange(LBracLoc, RBracLoc);
352  }
353
354  SourceLocation getLBracLoc() const { return LBracLoc; }
355  SourceLocation getRBracLoc() const { return RBracLoc; }
356
357  static bool classof(const Stmt *T) {
358    return T->getStmtClass() == CompoundStmtClass;
359  }
360  static bool classof(const CompoundStmt *) { return true; }
361
362  // Iterators
363  virtual child_iterator child_begin();
364  virtual child_iterator child_end();
365
366  virtual void EmitImpl(llvm::Serializer& S) const;
367  static CompoundStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
368};
369
370// SwitchCase is the base class for CaseStmt and DefaultStmt,
371class SwitchCase : public Stmt {
372protected:
373  // A pointer to the following CaseStmt or DefaultStmt class,
374  // used by SwitchStmt.
375  SwitchCase *NextSwitchCase;
376
377  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
378
379public:
380  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
381
382  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
383
384  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
385
386  Stmt *getSubStmt() { return v_getSubStmt(); }
387
388  virtual SourceRange getSourceRange() const { return SourceRange(); }
389
390  static bool classof(const Stmt *T) {
391    return T->getStmtClass() == CaseStmtClass ||
392    T->getStmtClass() == DefaultStmtClass;
393  }
394  static bool classof(const SwitchCase *) { return true; }
395protected:
396  virtual Stmt* v_getSubStmt() = 0;
397};
398
399class CaseStmt : public SwitchCase {
400  enum { SUBSTMT, LHS, RHS, END_EXPR };
401  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
402                             // GNU "case 1 ... 4" extension
403  SourceLocation CaseLoc;
404  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
405public:
406  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc)
407    : SwitchCase(CaseStmtClass) {
408    SubExprs[SUBSTMT] = 0;
409    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
410    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
411    CaseLoc = caseLoc;
412  }
413
414  SourceLocation getCaseLoc() const { return CaseLoc; }
415
416  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
417  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
418  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
419  const Expr *getLHS() const {
420    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
421  }
422  const Expr *getRHS() const {
423    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
424  }
425  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
426
427  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
428  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
429  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
430
431
432  virtual SourceRange getSourceRange() const {
433    // Handle deeply nested case statements with iteration instead of recursion.
434    const CaseStmt *CS = this;
435    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
436      CS = CS2;
437
438    return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
439  }
440  static bool classof(const Stmt *T) {
441    return T->getStmtClass() == CaseStmtClass;
442  }
443  static bool classof(const CaseStmt *) { return true; }
444
445  // Iterators
446  virtual child_iterator child_begin();
447  virtual child_iterator child_end();
448
449  virtual void EmitImpl(llvm::Serializer& S) const;
450  static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
451};
452
453class DefaultStmt : public SwitchCase {
454  Stmt* SubStmt;
455  SourceLocation DefaultLoc;
456  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
457public:
458  DefaultStmt(SourceLocation DL, Stmt *substmt) :
459    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
460
461  Stmt *getSubStmt() { return SubStmt; }
462  const Stmt *getSubStmt() const { return SubStmt; }
463
464  SourceLocation getDefaultLoc() const { return DefaultLoc; }
465
466  virtual SourceRange getSourceRange() const {
467    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
468  }
469  static bool classof(const Stmt *T) {
470    return T->getStmtClass() == DefaultStmtClass;
471  }
472  static bool classof(const DefaultStmt *) { return true; }
473
474  // Iterators
475  virtual child_iterator child_begin();
476  virtual child_iterator child_end();
477
478  virtual void EmitImpl(llvm::Serializer& S) const;
479  static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
480};
481
482class LabelStmt : public Stmt {
483  IdentifierInfo *Label;
484  Stmt *SubStmt;
485  SourceLocation IdentLoc;
486public:
487  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
488    : Stmt(LabelStmtClass), Label(label),
489      SubStmt(substmt), IdentLoc(IL) {}
490
491  SourceLocation getIdentLoc() const { return IdentLoc; }
492  IdentifierInfo *getID() const { return Label; }
493  const char *getName() const;
494  Stmt *getSubStmt() { return SubStmt; }
495  const Stmt *getSubStmt() const { return SubStmt; }
496
497  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
498  void setSubStmt(Stmt *SS) { SubStmt = SS; }
499
500  virtual SourceRange getSourceRange() const {
501    return SourceRange(IdentLoc, SubStmt->getLocEnd());
502  }
503  static bool classof(const Stmt *T) {
504    return T->getStmtClass() == LabelStmtClass;
505  }
506  static bool classof(const LabelStmt *) { return true; }
507
508  // Iterators
509  virtual child_iterator child_begin();
510  virtual child_iterator child_end();
511
512  virtual void EmitImpl(llvm::Serializer& S) const;
513  static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
514};
515
516
517/// IfStmt - This represents an if/then/else.
518///
519class IfStmt : public Stmt {
520  enum { COND, THEN, ELSE, END_EXPR };
521  Stmt* SubExprs[END_EXPR];
522  SourceLocation IfLoc;
523public:
524  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
525    : Stmt(IfStmtClass)  {
526    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
527    SubExprs[THEN] = then;
528    SubExprs[ELSE] = elsev;
529    IfLoc = IL;
530  }
531
532  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
533  const Stmt *getThen() const { return SubExprs[THEN]; }
534  const Stmt *getElse() const { return SubExprs[ELSE]; }
535
536  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
537  Stmt *getThen() { return SubExprs[THEN]; }
538  Stmt *getElse() { return SubExprs[ELSE]; }
539
540  virtual SourceRange getSourceRange() const {
541    if (SubExprs[ELSE])
542      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
543    else
544      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
545  }
546
547  static bool classof(const Stmt *T) {
548    return T->getStmtClass() == IfStmtClass;
549  }
550  static bool classof(const IfStmt *) { return true; }
551
552  // Iterators
553  virtual child_iterator child_begin();
554  virtual child_iterator child_end();
555
556  virtual void EmitImpl(llvm::Serializer& S) const;
557  static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
558};
559
560/// SwitchStmt - This represents a 'switch' stmt.
561///
562class SwitchStmt : public Stmt {
563  enum { COND, BODY, END_EXPR };
564  Stmt* SubExprs[END_EXPR];
565  // This points to a linked list of case and default statements.
566  SwitchCase *FirstCase;
567  SourceLocation SwitchLoc;
568public:
569  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
570      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
571      SubExprs[BODY] = NULL;
572    }
573
574  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
575  const Stmt *getBody() const { return SubExprs[BODY]; }
576  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
577
578  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
579  Stmt *getBody() { return SubExprs[BODY]; }
580  SwitchCase *getSwitchCaseList() { return FirstCase; }
581
582  void setBody(Stmt *S, SourceLocation SL) {
583    SubExprs[BODY] = S;
584    SwitchLoc = SL;
585  }
586  void addSwitchCase(SwitchCase *SC) {
587    if (FirstCase)
588      SC->setNextSwitchCase(FirstCase);
589
590    FirstCase = SC;
591  }
592  virtual SourceRange getSourceRange() const {
593    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
594  }
595  static bool classof(const Stmt *T) {
596    return T->getStmtClass() == SwitchStmtClass;
597  }
598  static bool classof(const SwitchStmt *) { return true; }
599
600  // Iterators
601  virtual child_iterator child_begin();
602  virtual child_iterator child_end();
603
604  virtual void EmitImpl(llvm::Serializer& S) const;
605  static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
606};
607
608
609/// WhileStmt - This represents a 'while' stmt.
610///
611class WhileStmt : public Stmt {
612  enum { COND, BODY, END_EXPR };
613  Stmt* SubExprs[END_EXPR];
614  SourceLocation WhileLoc;
615public:
616  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
617    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
618    SubExprs[BODY] = body;
619    WhileLoc = WL;
620  }
621
622  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
623  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
624  Stmt *getBody() { return SubExprs[BODY]; }
625  const Stmt *getBody() const { return SubExprs[BODY]; }
626
627  virtual SourceRange getSourceRange() const {
628    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
629  }
630  static bool classof(const Stmt *T) {
631    return T->getStmtClass() == WhileStmtClass;
632  }
633  static bool classof(const WhileStmt *) { return true; }
634
635  // Iterators
636  virtual child_iterator child_begin();
637  virtual child_iterator child_end();
638
639  virtual void EmitImpl(llvm::Serializer& S) const;
640  static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
641};
642
643/// DoStmt - This represents a 'do/while' stmt.
644///
645class DoStmt : public Stmt {
646  enum { COND, BODY, END_EXPR };
647  Stmt* SubExprs[END_EXPR];
648  SourceLocation DoLoc;
649public:
650  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
651    : Stmt(DoStmtClass), DoLoc(DL) {
652    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
653    SubExprs[BODY] = body;
654    DoLoc = DL;
655  }
656
657  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
658  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
659  Stmt *getBody() { return SubExprs[BODY]; }
660  const Stmt *getBody() const { return SubExprs[BODY]; }
661
662  virtual SourceRange getSourceRange() const {
663    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
664  }
665  static bool classof(const Stmt *T) {
666    return T->getStmtClass() == DoStmtClass;
667  }
668  static bool classof(const DoStmt *) { return true; }
669
670  // Iterators
671  virtual child_iterator child_begin();
672  virtual child_iterator child_end();
673
674  virtual void EmitImpl(llvm::Serializer& S) const;
675  static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
676};
677
678
679/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
680/// the init/cond/inc parts of the ForStmt will be null if they were not
681/// specified in the source.
682///
683class ForStmt : public Stmt {
684  enum { INIT, COND, INC, BODY, END_EXPR };
685  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
686  SourceLocation ForLoc;
687public:
688  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
689    : Stmt(ForStmtClass) {
690    SubExprs[INIT] = Init;
691    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
692    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
693    SubExprs[BODY] = Body;
694    ForLoc = FL;
695  }
696
697  Stmt *getInit() { return SubExprs[INIT]; }
698  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
699  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
700  Stmt *getBody() { return SubExprs[BODY]; }
701
702  const Stmt *getInit() const { return SubExprs[INIT]; }
703  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
704  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
705  const Stmt *getBody() const { return SubExprs[BODY]; }
706
707  virtual SourceRange getSourceRange() const {
708    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
709  }
710  static bool classof(const Stmt *T) {
711    return T->getStmtClass() == ForStmtClass;
712  }
713  static bool classof(const ForStmt *) { return true; }
714
715  // Iterators
716  virtual child_iterator child_begin();
717  virtual child_iterator child_end();
718
719  virtual void EmitImpl(llvm::Serializer& S) const;
720  static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
721};
722
723/// GotoStmt - This represents a direct goto.
724///
725class GotoStmt : public Stmt {
726  LabelStmt *Label;
727  SourceLocation GotoLoc;
728  SourceLocation LabelLoc;
729public:
730  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
731    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
732
733  LabelStmt *getLabel() const { return Label; }
734
735  virtual SourceRange getSourceRange() const {
736    return SourceRange(GotoLoc, LabelLoc);
737  }
738  static bool classof(const Stmt *T) {
739    return T->getStmtClass() == GotoStmtClass;
740  }
741  static bool classof(const GotoStmt *) { return true; }
742
743  // Iterators
744  virtual child_iterator child_begin();
745  virtual child_iterator child_end();
746
747  virtual void EmitImpl(llvm::Serializer& S) const;
748  static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
749};
750
751/// IndirectGotoStmt - This represents an indirect goto.
752///
753class IndirectGotoStmt : public Stmt {
754  Stmt *Target;
755  // FIXME: Add location information (e.g. SourceLocation objects).
756  //        When doing so, update the serialization routines.
757public:
758  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass),
759                                   Target((Stmt*)target){}
760
761  Expr *getTarget();
762  const Expr *getTarget() const;
763
764  virtual SourceRange getSourceRange() const { return SourceRange(); }
765
766  static bool classof(const Stmt *T) {
767    return T->getStmtClass() == IndirectGotoStmtClass;
768  }
769  static bool classof(const IndirectGotoStmt *) { return true; }
770
771  // Iterators
772  virtual child_iterator child_begin();
773  virtual child_iterator child_end();
774
775  virtual void EmitImpl(llvm::Serializer& S) const;
776  static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
777};
778
779
780/// ContinueStmt - This represents a continue.
781///
782class ContinueStmt : public Stmt {
783  SourceLocation ContinueLoc;
784public:
785  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
786
787  virtual SourceRange getSourceRange() const {
788    return SourceRange(ContinueLoc);
789  }
790  static bool classof(const Stmt *T) {
791    return T->getStmtClass() == ContinueStmtClass;
792  }
793  static bool classof(const ContinueStmt *) { return true; }
794
795  // Iterators
796  virtual child_iterator child_begin();
797  virtual child_iterator child_end();
798
799  virtual void EmitImpl(llvm::Serializer& S) const;
800  static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
801};
802
803/// BreakStmt - This represents a break.
804///
805class BreakStmt : public Stmt {
806  SourceLocation BreakLoc;
807public:
808  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
809
810  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
811
812  static bool classof(const Stmt *T) {
813    return T->getStmtClass() == BreakStmtClass;
814  }
815  static bool classof(const BreakStmt *) { return true; }
816
817  // Iterators
818  virtual child_iterator child_begin();
819  virtual child_iterator child_end();
820
821  virtual void EmitImpl(llvm::Serializer& S) const;
822  static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
823};
824
825
826/// ReturnStmt - This represents a return, optionally of an expression:
827///   return;
828///   return 4;
829///
830/// Note that GCC allows return with no argument in a function declared to
831/// return a value, and it allows returning a value in functions declared to
832/// return void.  We explicitly model this in the AST, which means you can't
833/// depend on the return type of the function and the presence of an argument.
834///
835class ReturnStmt : public Stmt {
836  Stmt *RetExpr;
837  SourceLocation RetLoc;
838public:
839  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
840    RetExpr((Stmt*) E), RetLoc(RL) {}
841
842  const Expr *getRetValue() const;
843  Expr *getRetValue();
844
845  virtual SourceRange getSourceRange() const;
846
847  static bool classof(const Stmt *T) {
848    return T->getStmtClass() == ReturnStmtClass;
849  }
850  static bool classof(const ReturnStmt *) { return true; }
851
852  // Iterators
853  virtual child_iterator child_begin();
854  virtual child_iterator child_end();
855
856  virtual void EmitImpl(llvm::Serializer& S) const;
857  static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
858};
859
860/// AsmStmt - This represents a GNU inline-assembly statement extension.
861///
862class AsmStmt : public Stmt {
863  SourceLocation AsmLoc, RParenLoc;
864  StringLiteral *AsmStr;
865
866  bool IsSimple;
867  bool IsVolatile;
868
869  unsigned NumOutputs;
870  unsigned NumInputs;
871
872  llvm::SmallVector<std::string, 4> Names;
873  llvm::SmallVector<StringLiteral*, 4> Constraints;
874  llvm::SmallVector<Stmt*, 4> Exprs;
875
876  llvm::SmallVector<StringLiteral*, 4> Clobbers;
877public:
878  AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
879          unsigned numoutputs, unsigned numinputs,
880          std::string *names, StringLiteral **constraints,
881          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
882          StringLiteral **clobbers, SourceLocation rparenloc);
883
884  bool isVolatile() const { return IsVolatile; }
885  bool isSimple() const { return IsSimple; }
886
887  //===--- Asm String Analysis ---===//
888
889  const StringLiteral *getAsmString() const { return AsmStr; }
890  StringLiteral *getAsmString() { return AsmStr; }
891
892  /// AsmStringPiece - this is part of a decomposed asm string specification
893  /// (for use with the AnalyzeAsmString function below).  An asm string is
894  /// considered to be a concatenation of these parts.
895  class AsmStringPiece {
896  public:
897    enum Kind {
898      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
899      Operand  // Operand reference, with optional modifier %c4.
900    };
901  private:
902    Kind MyKind;
903    std::string Str;
904    unsigned OperandNo;
905  public:
906    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
907    AsmStringPiece(unsigned OpNo, char Modifier)
908      : MyKind(Operand), Str(), OperandNo(OpNo) {
909      Str += Modifier;
910    }
911
912    bool isString() const { return MyKind == String; }
913    bool isOperand() const { return MyKind == Operand; }
914
915    const std::string &getString() const {
916      assert(isString());
917      return Str;
918    }
919
920    unsigned getOperandNo() const {
921      assert(isOperand());
922      return OperandNo;
923    }
924
925    /// getModifier - Get the modifier for this operand, if present.  This
926    /// returns '\0' if there was no modifier.
927    char getModifier() const {
928      assert(isOperand());
929      return Str[0];
930    }
931  };
932
933  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
934  /// it into pieces.  If the asm string is erroneous, emit errors and return
935  /// true, otherwise return false.  This handles canonicalization and
936  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
937  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
938  unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
939                            ASTContext &C, unsigned &DiagOffs) const;
940
941
942  //===--- Output operands ---===//
943
944  unsigned getNumOutputs() const { return NumOutputs; }
945
946  const std::string &getOutputName(unsigned i) const {
947    return Names[i];
948  }
949
950  /// getOutputConstraint - Return the constraint string for the specified
951  /// output operand.  All output constraints are known to be non-empty (either
952  /// '=' or '+').
953  std::string getOutputConstraint(unsigned i) const;
954
955  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
956    return Constraints[i];
957  }
958  StringLiteral *getOutputConstraintLiteral(unsigned i) {
959    return Constraints[i];
960  }
961
962
963  Expr *getOutputExpr(unsigned i);
964
965  const Expr *getOutputExpr(unsigned i) const {
966    return const_cast<AsmStmt*>(this)->getOutputExpr(i);
967  }
968
969  /// isOutputPlusConstraint - Return true if the specified output constraint
970  /// is a "+" constraint (which is both an input and an output) or false if it
971  /// is an "=" constraint (just an output).
972  bool isOutputPlusConstraint(unsigned i) const {
973    return getOutputConstraint(i)[0] == '+';
974  }
975
976  /// getNumPlusOperands - Return the number of output operands that have a "+"
977  /// constraint.
978  unsigned getNumPlusOperands() const;
979
980  //===--- Input operands ---===//
981
982  unsigned getNumInputs() const { return NumInputs; }
983
984  const std::string &getInputName(unsigned i) const {
985    return Names[i + NumOutputs];
986  }
987
988  /// getInputConstraint - Return the specified input constraint.  Unlike output
989  /// constraints, these can be empty.
990  std::string getInputConstraint(unsigned i) const;
991
992  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
993    return Constraints[i + NumOutputs];
994  }
995  StringLiteral *getInputConstraintLiteral(unsigned i) {
996    return Constraints[i + NumOutputs];
997  }
998
999
1000  Expr *getInputExpr(unsigned i);
1001
1002  const Expr *getInputExpr(unsigned i) const {
1003    return const_cast<AsmStmt*>(this)->getInputExpr(i);
1004  }
1005
1006  //===--- Other ---===//
1007
1008  /// getNamedOperand - Given a symbolic operand reference like %[foo],
1009  /// translate this into a numeric value needed to reference the same operand.
1010  /// This returns -1 if the operand name is invalid.
1011  int getNamedOperand(const std::string &SymbolicName) const;
1012
1013
1014
1015  unsigned getNumClobbers() const { return Clobbers.size(); }
1016  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
1017  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
1018
1019  virtual SourceRange getSourceRange() const {
1020    return SourceRange(AsmLoc, RParenLoc);
1021  }
1022
1023  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
1024  static bool classof(const AsmStmt *) { return true; }
1025
1026  // Input expr iterators.
1027
1028  typedef ExprIterator inputs_iterator;
1029  typedef ConstExprIterator const_inputs_iterator;
1030
1031  inputs_iterator begin_inputs() {
1032    return &Exprs[0] + NumOutputs;
1033  }
1034
1035  inputs_iterator end_inputs() {
1036    return  &Exprs[0] + NumOutputs + NumInputs;
1037  }
1038
1039  const_inputs_iterator begin_inputs() const {
1040    return &Exprs[0] + NumOutputs;
1041  }
1042
1043  const_inputs_iterator end_inputs() const {
1044    return  &Exprs[0] + NumOutputs + NumInputs;}
1045
1046  // Output expr iterators.
1047
1048  typedef ExprIterator outputs_iterator;
1049  typedef ConstExprIterator const_outputs_iterator;
1050
1051  outputs_iterator begin_outputs() { return &Exprs[0]; }
1052  outputs_iterator end_outputs() { return &Exprs[0] + NumOutputs; }
1053
1054  const_outputs_iterator begin_outputs() const { return &Exprs[0]; }
1055  const_outputs_iterator end_outputs() const { return &Exprs[0] + NumOutputs; }
1056
1057  // Input name iterator.
1058
1059  const std::string *begin_output_names() const {
1060    return &Names[0];
1061  }
1062
1063  const std::string *end_output_names() const {
1064    return &Names[0] + NumOutputs;
1065  }
1066
1067  // Child iterators
1068
1069  virtual child_iterator child_begin();
1070  virtual child_iterator child_end();
1071
1072  virtual void EmitImpl(llvm::Serializer& S) const;
1073  static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1074};
1075
1076/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
1077/// represented as 'for (element 'in' collection-expression)' stmt.
1078///
1079class ObjCForCollectionStmt : public Stmt {
1080  enum { ELEM, COLLECTION, BODY, END_EXPR };
1081  Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
1082  SourceLocation ForLoc;
1083  SourceLocation RParenLoc;
1084public:
1085  ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
1086                        SourceLocation FCL, SourceLocation RPL);
1087
1088  Stmt *getElement() { return SubExprs[ELEM]; }
1089  Expr *getCollection() {
1090    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
1091  }
1092  Stmt *getBody() { return SubExprs[BODY]; }
1093
1094  const Stmt *getElement() const { return SubExprs[ELEM]; }
1095  const Expr *getCollection() const {
1096    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
1097  }
1098  const Stmt *getBody() const { return SubExprs[BODY]; }
1099
1100  SourceLocation getRParenLoc() const { return RParenLoc; }
1101
1102  virtual SourceRange getSourceRange() const {
1103    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
1104  }
1105  static bool classof(const Stmt *T) {
1106    return T->getStmtClass() == ObjCForCollectionStmtClass;
1107  }
1108  static bool classof(const ObjCForCollectionStmt *) { return true; }
1109
1110  // Iterators
1111  virtual child_iterator child_begin();
1112  virtual child_iterator child_end();
1113
1114  virtual void EmitImpl(llvm::Serializer& S) const;
1115  static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1116};
1117
1118/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
1119class ObjCAtCatchStmt : public Stmt {
1120private:
1121  enum { BODY, NEXT_CATCH, END_EXPR };
1122  ParmVarDecl *ExceptionDecl;
1123  Stmt *SubExprs[END_EXPR];
1124  SourceLocation AtCatchLoc, RParenLoc;
1125
1126  // Used by deserialization.
1127  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc)
1128  : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {}
1129
1130public:
1131  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
1132                  ParmVarDecl *catchVarDecl,
1133                  Stmt *atCatchStmt, Stmt *atCatchList);
1134
1135  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
1136  Stmt *getCatchBody() { return SubExprs[BODY]; }
1137
1138  const ObjCAtCatchStmt *getNextCatchStmt() const {
1139    return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1140  }
1141  ObjCAtCatchStmt *getNextCatchStmt() {
1142    return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1143  }
1144
1145  const ParmVarDecl *getCatchParamDecl() const {
1146    return ExceptionDecl;
1147  }
1148  ParmVarDecl *getCatchParamDecl() {
1149    return ExceptionDecl;
1150  }
1151
1152  SourceLocation getRParenLoc() const { return RParenLoc; }
1153
1154  virtual SourceRange getSourceRange() const {
1155    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
1156  }
1157
1158  bool hasEllipsis() const { return getCatchParamDecl() == 0; }
1159
1160  static bool classof(const Stmt *T) {
1161    return T->getStmtClass() == ObjCAtCatchStmtClass;
1162  }
1163  static bool classof(const ObjCAtCatchStmt *) { return true; }
1164
1165  virtual child_iterator child_begin();
1166  virtual child_iterator child_end();
1167
1168  virtual void EmitImpl(llvm::Serializer& S) const;
1169  static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1170};
1171
1172/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
1173class ObjCAtFinallyStmt : public Stmt {
1174  Stmt *AtFinallyStmt;
1175  SourceLocation AtFinallyLoc;
1176public:
1177  ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
1178  : Stmt(ObjCAtFinallyStmtClass),
1179    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
1180
1181  const Stmt *getFinallyBody () const { return AtFinallyStmt; }
1182  Stmt *getFinallyBody () { return AtFinallyStmt; }
1183
1184  virtual SourceRange getSourceRange() const {
1185    return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
1186  }
1187
1188  static bool classof(const Stmt *T) {
1189    return T->getStmtClass() == ObjCAtFinallyStmtClass;
1190  }
1191  static bool classof(const ObjCAtFinallyStmt *) { return true; }
1192
1193  virtual child_iterator child_begin();
1194  virtual child_iterator child_end();
1195
1196  virtual void EmitImpl(llvm::Serializer& S) const;
1197  static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1198};
1199
1200/// ObjCAtTryStmt - This represent objective-c's over-all
1201/// @try ... @catch ... @finally statement.
1202class ObjCAtTryStmt : public Stmt {
1203private:
1204  enum { TRY, CATCH, FINALLY, END_EXPR };
1205  Stmt* SubStmts[END_EXPR];
1206
1207  SourceLocation AtTryLoc;
1208public:
1209  ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
1210                Stmt *atCatchStmt,
1211                Stmt *atFinallyStmt)
1212  : Stmt(ObjCAtTryStmtClass) {
1213      SubStmts[TRY] = atTryStmt;
1214      SubStmts[CATCH] = atCatchStmt;
1215      SubStmts[FINALLY] = atFinallyStmt;
1216      AtTryLoc = atTryLoc;
1217    }
1218
1219  const Stmt *getTryBody() const { return SubStmts[TRY]; }
1220  Stmt *getTryBody() { return SubStmts[TRY]; }
1221  const ObjCAtCatchStmt *getCatchStmts() const {
1222    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1223  }
1224  ObjCAtCatchStmt *getCatchStmts() {
1225    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1226  }
1227  const ObjCAtFinallyStmt *getFinallyStmt() const {
1228    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1229  }
1230  ObjCAtFinallyStmt *getFinallyStmt() {
1231    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1232  }
1233  virtual SourceRange getSourceRange() const {
1234    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
1235  }
1236
1237  static bool classof(const Stmt *T) {
1238    return T->getStmtClass() == ObjCAtTryStmtClass;
1239  }
1240  static bool classof(const ObjCAtTryStmt *) { return true; }
1241
1242  virtual child_iterator child_begin();
1243  virtual child_iterator child_end();
1244
1245  virtual void EmitImpl(llvm::Serializer& S) const;
1246  static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1247};
1248
1249/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
1250/// Example: @synchronized (sem) {
1251///             do-something;
1252///          }
1253///
1254class ObjCAtSynchronizedStmt : public Stmt {
1255private:
1256  enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
1257  Stmt* SubStmts[END_EXPR];
1258  SourceLocation AtSynchronizedLoc;
1259
1260public:
1261  ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
1262                         Stmt *synchBody)
1263  : Stmt(ObjCAtSynchronizedStmtClass) {
1264      SubStmts[SYNC_EXPR] = synchExpr;
1265      SubStmts[SYNC_BODY] = synchBody;
1266      AtSynchronizedLoc = atSynchronizedLoc;
1267    }
1268
1269  const CompoundStmt *getSynchBody() const {
1270    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1271  }
1272  CompoundStmt *getSynchBody() {
1273    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1274  }
1275
1276  const Expr *getSynchExpr() const {
1277    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1278  }
1279  Expr *getSynchExpr() {
1280    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1281  }
1282
1283  virtual SourceRange getSourceRange() const {
1284    return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
1285  }
1286
1287  static bool classof(const Stmt *T) {
1288    return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
1289  }
1290  static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
1291
1292  virtual child_iterator child_begin();
1293  virtual child_iterator child_end();
1294
1295  virtual void EmitImpl(llvm::Serializer& S) const;
1296  static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D,
1297                                            ASTContext& C);
1298};
1299
1300/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
1301class ObjCAtThrowStmt : public Stmt {
1302  Stmt *Throw;
1303  SourceLocation AtThrowLoc;
1304public:
1305  ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
1306  : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
1307    AtThrowLoc = atThrowLoc;
1308  }
1309
1310  const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
1311  Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
1312
1313  virtual SourceRange getSourceRange() const {
1314    if (Throw)
1315      return SourceRange(AtThrowLoc, Throw->getLocEnd());
1316    else
1317      return SourceRange(AtThrowLoc);
1318  }
1319
1320  static bool classof(const Stmt *T) {
1321    return T->getStmtClass() == ObjCAtThrowStmtClass;
1322  }
1323  static bool classof(const ObjCAtThrowStmt *) { return true; }
1324
1325  virtual child_iterator child_begin();
1326  virtual child_iterator child_end();
1327
1328  virtual void EmitImpl(llvm::Serializer& S) const;
1329  static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1330};
1331
1332/// CXXCatchStmt - This represents a C++ catch block.
1333class CXXCatchStmt : public Stmt {
1334  SourceLocation CatchLoc;
1335  /// The exception-declaration of the type.
1336  Decl *ExceptionDecl;
1337  /// The handler block.
1338  Stmt *HandlerBlock;
1339
1340public:
1341  CXXCatchStmt(SourceLocation catchLoc, Decl *exDecl, Stmt *handlerBlock)
1342  : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
1343    HandlerBlock(handlerBlock) {}
1344
1345  virtual void Destroy(ASTContext& Ctx);
1346
1347  virtual SourceRange getSourceRange() const {
1348    return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
1349  }
1350
1351  Decl *getExceptionDecl() { return ExceptionDecl; }
1352  QualType getCaughtType();
1353  Stmt *getHandlerBlock() { return HandlerBlock; }
1354
1355  static bool classof(const Stmt *T) {
1356    return T->getStmtClass() == CXXCatchStmtClass;
1357  }
1358  static bool classof(const CXXCatchStmt *) { return true; }
1359
1360  virtual child_iterator child_begin();
1361  virtual child_iterator child_end();
1362
1363  virtual void EmitImpl(llvm::Serializer& S) const;
1364  static CXXCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1365};
1366
1367/// CXXTryStmt - A C++ try block, including all handlers.
1368class CXXTryStmt : public Stmt {
1369  SourceLocation TryLoc;
1370  // First place is the guarded CompoundStatement. Subsequent are the handlers.
1371  // More than three handlers should be rare.
1372  llvm::SmallVector<Stmt*, 4> Stmts;
1373
1374public:
1375  CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
1376             Stmt **handlers, unsigned numHandlers);
1377
1378  virtual SourceRange getSourceRange() const {
1379    return SourceRange(TryLoc, Stmts.back()->getLocEnd());
1380  }
1381
1382  CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); }
1383  const CompoundStmt *getTryBlock() const {
1384    return llvm::cast<CompoundStmt>(Stmts[0]);
1385  }
1386
1387  unsigned getNumHandlers() const { return Stmts.size() - 1; }
1388  CXXCatchStmt *getHandler(unsigned i) {
1389    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
1390  }
1391  const CXXCatchStmt *getHandler(unsigned i) const {
1392    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
1393  }
1394
1395  static bool classof(const Stmt *T) {
1396    return T->getStmtClass() == CXXTryStmtClass;
1397  }
1398  static bool classof(const CXXTryStmt *) { return true; }
1399
1400  virtual child_iterator child_begin();
1401  virtual child_iterator child_end();
1402
1403  virtual void EmitImpl(llvm::Serializer& S) const;
1404  static CXXTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1405};
1406
1407}  // end namespace clang
1408
1409#endif
1410