Stmt.h revision e66a8cf9117e5fb95a05ff76ec06615e63dd5ade
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//===----------------------------------------------------------------------===//
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  This file defines the Stmt interface and subclasses.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch//===----------------------------------------------------------------------===//
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_CLANG_AST_STMT_H
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_CLANG_AST_STMT_H
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/Casting.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "llvm/Support/raw_ostream.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "clang/Basic/SourceLocation.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "clang/AST/StmtIterator.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "clang/AST/DeclGroup.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/ADT/SmallVector.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/ADT/iterator.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Bitcode/SerializationFwd.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/AST/ASTContext.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using llvm::dyn_cast_or_null;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace clang {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class ASTContext;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Expr;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Decl;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class ParmVarDecl;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class QualType;
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  class IdentifierInfo;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class SourceManager;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class StringLiteral;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class SwitchStmt;
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  class PrinterHelper;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //===----------------------------------------------------------------------===//
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  references to children (to be compatible with StmtIterator).
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //===----------------------------------------------------------------------===//
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  class Stmt;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Expr;
490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  class ExprIterator {
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Stmt** I;
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  public:
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ExprIterator(Stmt** i) : I(i) {}
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ExprIterator() : I(0) {}
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ExprIterator& operator++() { ++I; return *this; }
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ExprIterator operator-(size_t i) { return I-i; }
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ExprIterator operator+(size_t i) { return I+i; }
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Expr* operator[](size_t idx);
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // FIXME: Verify that this will correctly return a signed distance.
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    signed operator-(const ExprIterator& R) const { return I - R.I; }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Expr* operator*() const;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Expr* operator->() const;
633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    bool operator==(const ExprIterator& R) const { return I == R.I; }
643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    bool operator!=(const ExprIterator& R) const { return I != R.I; }
653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    bool operator>(const ExprIterator& R) const { return I > R.I; }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class ConstExprIterator {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Stmt* const * I;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConstExprIterator(Stmt* const* i) : I(i) {}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConstExprIterator() : I(0) {}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConstExprIterator& operator++() { ++I; return *this; }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConstExprIterator operator+(size_t i) { return I+i; }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConstExprIterator operator-(size_t i) { return I-i; }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Expr * operator[](size_t idx) const;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Expr * operator*() const;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Expr * operator->() const;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===//
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// AST classes for statements.
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===//
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/// Stmt - This represents one statement.
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)///
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Stmt {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum StmtClass {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NoStmtClass = 0,
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define STMT(CLASS, PARENT) CLASS##Class,
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/AST/StmtNodes.def"
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private:
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const StmtClass sClass;
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Make vanilla 'new' and 'delete' illegal for Stmts.
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)protected:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* operator new(size_t bytes) throw() {
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    assert(0 && "Stmts cannot be allocated with regular 'new'.");
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return 0;
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void operator delete(void* data) throw() {
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    assert(0 && "Stmts cannot be released with regular 'delete'.");
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochpublic:
118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Only allow allocation of Stmts using the allocator in ASTContext
119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // or by doing a placement new.
120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void* operator new(size_t bytes, ASTContext& C,
121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                     unsigned alignment = 16) throw() {
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return ::operator new(bytes, C, alignment);
123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void* operator new(size_t bytes, ASTContext* C,
126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                     unsigned alignment = 16) throw() {
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return ::operator new(bytes, *C, alignment);
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void* operator new(size_t bytes, void* mem) throw() {
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return mem;
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void operator delete(void*, ASTContext& C) throw() { }
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void operator delete(void*, ASTContext& C, unsigned alignment) throw() { }
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void operator delete(void*, std::size_t) throw() { }
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)protected:
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ///  recursively release child AST nodes.
141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void DestroyChildren(ASTContext& Ctx);
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)public:
144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Stmt(StmtClass SC) : sClass(SC) {
145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual ~Stmt() {}
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Destroy(ASTContext &Ctx);
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  StmtClass getStmtClass() const { return sClass; }
152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const char *getStmtClassName() const;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// SourceLocation tokens are not useful in isolation - they are low level
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// value objects created/interpreted by SourceManager. We assume AST
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// clients will have a pointer to the respective SourceManager.
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual SourceRange getSourceRange() const = 0;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // global temp stats (until we have a per-module visitor)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void addStmtClass(const StmtClass s);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool CollectingStats(bool enable=false);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void PrintStats();
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// dump - This does a local dump of the specified AST fragment.  It dumps the
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  /// specified node and a few nodes underneath it, but not the whole subtree.
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// This is useful in a debugger.
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void dump() const;
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void dump(SourceManager &SM) const;
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void dumpAll() const;
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void dumpAll(SourceManager &SM) const;
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// back to its original source language syntax.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void dumpPretty() const;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL, unsigned = 0,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   bool NoIndent=false) const;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void viewAST() const;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implement isa<T> support.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool classof(const Stmt *) { return true; }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ///  contain implicit control-flow in the order their subexpressions
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ///  are evaluated.  This predicate returns true if this statement has
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///  such implicit control-flow.  Such statements are also specially handled
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ///  within CFGs.
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool hasImplicitControlFlow() const;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// Child Iterators: All subclasses must implement child_begin and child_end
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  to permit easy iteration over the substatements/subexpessions of an
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  AST node.  This permits easy iteration over all nodes in the AST.
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  typedef StmtIterator       child_iterator;
200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  typedef ConstStmtIterator  const_child_iterator;
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual child_iterator child_begin() = 0;
203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual child_iterator child_end()   = 0;
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const_child_iterator child_begin() const {
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const_child_iterator child_end() const {
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void Emit(llvm::Serializer& S) const;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static Stmt* Create(llvm::Deserializer& D, ASTContext& C);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EmitImpl(llvm::Serializer& S) const {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This method will eventually be a pure-virtual function.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert (false && "Not implemented.");
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// DeclStmt - Adaptor class for mixing declarations with statements and
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// expressions. For example, CompoundStmt mixes statements, expressions
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// and declarations (variables, types). Another example is ForStmt, where
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// the first statement can be an expression or a declaration.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeclStmt : public Stmt {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeclGroupRef DG;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SourceLocation StartLoc, EndLoc;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    StartLoc(startLoc), EndLoc(endLoc) {}
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void Destroy(ASTContext& Ctx);
2365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// isSingleDecl - This method returns true if this DeclStmt refers
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  /// to a single Decl.
239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool isSingleDecl() const {
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return DG.isSingleDecl();
241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Decl *getSingleDecl() { return DG.getSingleDecl(); }
245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DeclGroupRef getDeclGroup() const { return DG; }
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeclGroupRef getDeclGroup() { return DG; }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SourceLocation getStartLoc() const { return StartLoc; }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SourceLocation getEndLoc() const { return EndLoc; }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SourceRange getSourceRange() const {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SourceRange(StartLoc, EndLoc);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  static bool classof(const Stmt *T) {
2575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return T->getStmtClass() == DeclStmtClass;
2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  static bool classof(const DeclStmt *) { return true; }
2605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Iterators over subexpressions.
2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual child_iterator child_begin();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual child_iterator child_end();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef DeclGroupRef::iterator decl_iterator;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef DeclGroupRef::const_iterator const_decl_iterator;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decl_iterator decl_begin() { return DG.begin(); }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decl_iterator decl_end() { return DG.end(); }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const_decl_iterator decl_begin() const { return DG.begin(); }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const_decl_iterator decl_end() const { return DG.end(); }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Serialization.
2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void EmitImpl(llvm::Serializer& S) const;
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static DeclStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// NullStmt - This is the null statement ";": C99 6.8.3p3.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NullStmt : public Stmt {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SourceLocation SemiLoc;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SourceLocation getSemiLoc() const { return SemiLoc; }
286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
288effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static bool classof(const Stmt *T) {
290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return T->getStmtClass() == NullStmtClass;
291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static bool classof(const NullStmt *) { return true; }
293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
294effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Iterators
295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual child_iterator child_begin();
296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual child_iterator child_end();
297effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
298effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void EmitImpl(llvm::Serializer& S) const;
299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static NullStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
300effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
301effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// CompoundStmt - This represents a group of statements like { stmt stmt }.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CompoundStmt : public Stmt {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stmt** Body;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned NumStmts;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SourceLocation LBracLoc, RBracLoc;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             SourceLocation LB, SourceLocation RB)
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (NumStmts == 0) {
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Body = 0;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Body = new (C) Stmt*[NumStmts];
318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    memcpy(Body, StmtStart, numStmts * sizeof(*Body));
319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool body_empty() const { return NumStmts == 0; }
322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  typedef Stmt** body_iterator;
324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  body_iterator body_begin() { return Body; }
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  body_iterator body_end() { return Body + NumStmts; }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef Stmt* const * const_body_iterator;
3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const_body_iterator body_begin() const { return Body; }
3305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const_body_iterator body_end() const { return Body + NumStmts; }
3315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reverse_body_iterator body_rbegin() {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reverse_body_iterator(body_end());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  reverse_body_iterator body_rend() {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reverse_body_iterator(body_begin());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
340
341  typedef std::reverse_iterator<const_body_iterator>
342          const_reverse_body_iterator;
343
344  const_reverse_body_iterator body_rbegin() const {
345    return const_reverse_body_iterator(body_end());
346  }
347
348  const_reverse_body_iterator body_rend() const {
349    return const_reverse_body_iterator(body_begin());
350  }
351
352  virtual SourceRange getSourceRange() const {
353    return SourceRange(LBracLoc, RBracLoc);
354  }
355
356  SourceLocation getLBracLoc() const { return LBracLoc; }
357  SourceLocation getRBracLoc() const { return RBracLoc; }
358
359  static bool classof(const Stmt *T) {
360    return T->getStmtClass() == CompoundStmtClass;
361  }
362  static bool classof(const CompoundStmt *) { return true; }
363
364  // Iterators
365  virtual child_iterator child_begin();
366  virtual child_iterator child_end();
367
368  virtual void EmitImpl(llvm::Serializer& S) const;
369  static CompoundStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
370};
371
372// SwitchCase is the base class for CaseStmt and DefaultStmt,
373class SwitchCase : public Stmt {
374protected:
375  // A pointer to the following CaseStmt or DefaultStmt class,
376  // used by SwitchStmt.
377  SwitchCase *NextSwitchCase;
378
379  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
380
381public:
382  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
383
384  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
385
386  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
387
388  Stmt *getSubStmt() { return v_getSubStmt(); }
389
390  virtual SourceRange getSourceRange() const { return SourceRange(); }
391
392  static bool classof(const Stmt *T) {
393    return T->getStmtClass() == CaseStmtClass ||
394    T->getStmtClass() == DefaultStmtClass;
395  }
396  static bool classof(const SwitchCase *) { return true; }
397protected:
398  virtual Stmt* v_getSubStmt() = 0;
399};
400
401class CaseStmt : public SwitchCase {
402  enum { SUBSTMT, LHS, RHS, END_EXPR };
403  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
404                             // GNU "case 1 ... 4" extension
405  SourceLocation CaseLoc;
406  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
407public:
408  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc)
409    : SwitchCase(CaseStmtClass) {
410    SubExprs[SUBSTMT] = 0;
411    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
412    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
413    CaseLoc = caseLoc;
414  }
415
416  SourceLocation getCaseLoc() const { return CaseLoc; }
417
418  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
419  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
420  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
421  const Expr *getLHS() const {
422    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
423  }
424  const Expr *getRHS() const {
425    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
426  }
427  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
428
429  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
430  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
431  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
432
433
434  virtual SourceRange getSourceRange() const {
435    // Handle deeply nested case statements with iteration instead of recursion.
436    const CaseStmt *CS = this;
437    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
438      CS = CS2;
439
440    return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
441  }
442  static bool classof(const Stmt *T) {
443    return T->getStmtClass() == CaseStmtClass;
444  }
445  static bool classof(const CaseStmt *) { return true; }
446
447  // Iterators
448  virtual child_iterator child_begin();
449  virtual child_iterator child_end();
450
451  virtual void EmitImpl(llvm::Serializer& S) const;
452  static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
453};
454
455class DefaultStmt : public SwitchCase {
456  Stmt* SubStmt;
457  SourceLocation DefaultLoc;
458  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
459public:
460  DefaultStmt(SourceLocation DL, Stmt *substmt) :
461    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
462
463  Stmt *getSubStmt() { return SubStmt; }
464  const Stmt *getSubStmt() const { return SubStmt; }
465
466  SourceLocation getDefaultLoc() const { return DefaultLoc; }
467
468  virtual SourceRange getSourceRange() const {
469    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
470  }
471  static bool classof(const Stmt *T) {
472    return T->getStmtClass() == DefaultStmtClass;
473  }
474  static bool classof(const DefaultStmt *) { return true; }
475
476  // Iterators
477  virtual child_iterator child_begin();
478  virtual child_iterator child_end();
479
480  virtual void EmitImpl(llvm::Serializer& S) const;
481  static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
482};
483
484class LabelStmt : public Stmt {
485  IdentifierInfo *Label;
486  Stmt *SubStmt;
487  SourceLocation IdentLoc;
488public:
489  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
490    : Stmt(LabelStmtClass), Label(label),
491      SubStmt(substmt), IdentLoc(IL) {}
492
493  SourceLocation getIdentLoc() const { return IdentLoc; }
494  IdentifierInfo *getID() const { return Label; }
495  const char *getName() const;
496  Stmt *getSubStmt() { return SubStmt; }
497  const Stmt *getSubStmt() const { return SubStmt; }
498
499  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
500  void setSubStmt(Stmt *SS) { SubStmt = SS; }
501
502  virtual SourceRange getSourceRange() const {
503    return SourceRange(IdentLoc, SubStmt->getLocEnd());
504  }
505  static bool classof(const Stmt *T) {
506    return T->getStmtClass() == LabelStmtClass;
507  }
508  static bool classof(const LabelStmt *) { return true; }
509
510  // Iterators
511  virtual child_iterator child_begin();
512  virtual child_iterator child_end();
513
514  virtual void EmitImpl(llvm::Serializer& S) const;
515  static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
516};
517
518
519/// IfStmt - This represents an if/then/else.
520///
521class IfStmt : public Stmt {
522  enum { COND, THEN, ELSE, END_EXPR };
523  Stmt* SubExprs[END_EXPR];
524  SourceLocation IfLoc;
525public:
526  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
527    : Stmt(IfStmtClass)  {
528    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
529    SubExprs[THEN] = then;
530    SubExprs[ELSE] = elsev;
531    IfLoc = IL;
532  }
533
534  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
535  const Stmt *getThen() const { return SubExprs[THEN]; }
536  const Stmt *getElse() const { return SubExprs[ELSE]; }
537
538  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
539  Stmt *getThen() { return SubExprs[THEN]; }
540  Stmt *getElse() { return SubExprs[ELSE]; }
541
542  virtual SourceRange getSourceRange() const {
543    if (SubExprs[ELSE])
544      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
545    else
546      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
547  }
548
549  static bool classof(const Stmt *T) {
550    return T->getStmtClass() == IfStmtClass;
551  }
552  static bool classof(const IfStmt *) { return true; }
553
554  // Iterators
555  virtual child_iterator child_begin();
556  virtual child_iterator child_end();
557
558  virtual void EmitImpl(llvm::Serializer& S) const;
559  static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
560};
561
562/// SwitchStmt - This represents a 'switch' stmt.
563///
564class SwitchStmt : public Stmt {
565  enum { COND, BODY, END_EXPR };
566  Stmt* SubExprs[END_EXPR];
567  // This points to a linked list of case and default statements.
568  SwitchCase *FirstCase;
569  SourceLocation SwitchLoc;
570public:
571  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
572      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
573      SubExprs[BODY] = NULL;
574    }
575
576  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
577  const Stmt *getBody() const { return SubExprs[BODY]; }
578  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
579
580  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
581  Stmt *getBody() { return SubExprs[BODY]; }
582  SwitchCase *getSwitchCaseList() { return FirstCase; }
583
584  void setBody(Stmt *S, SourceLocation SL) {
585    SubExprs[BODY] = S;
586    SwitchLoc = SL;
587  }
588  void addSwitchCase(SwitchCase *SC) {
589    if (FirstCase)
590      SC->setNextSwitchCase(FirstCase);
591
592    FirstCase = SC;
593  }
594  virtual SourceRange getSourceRange() const {
595    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
596  }
597  static bool classof(const Stmt *T) {
598    return T->getStmtClass() == SwitchStmtClass;
599  }
600  static bool classof(const SwitchStmt *) { return true; }
601
602  // Iterators
603  virtual child_iterator child_begin();
604  virtual child_iterator child_end();
605
606  virtual void EmitImpl(llvm::Serializer& S) const;
607  static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
608};
609
610
611/// WhileStmt - This represents a 'while' stmt.
612///
613class WhileStmt : public Stmt {
614  enum { COND, BODY, END_EXPR };
615  Stmt* SubExprs[END_EXPR];
616  SourceLocation WhileLoc;
617public:
618  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
619    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
620    SubExprs[BODY] = body;
621    WhileLoc = WL;
622  }
623
624  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
625  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
626  Stmt *getBody() { return SubExprs[BODY]; }
627  const Stmt *getBody() const { return SubExprs[BODY]; }
628
629  virtual SourceRange getSourceRange() const {
630    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
631  }
632  static bool classof(const Stmt *T) {
633    return T->getStmtClass() == WhileStmtClass;
634  }
635  static bool classof(const WhileStmt *) { return true; }
636
637  // Iterators
638  virtual child_iterator child_begin();
639  virtual child_iterator child_end();
640
641  virtual void EmitImpl(llvm::Serializer& S) const;
642  static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
643};
644
645/// DoStmt - This represents a 'do/while' stmt.
646///
647class DoStmt : public Stmt {
648  enum { COND, BODY, END_EXPR };
649  Stmt* SubExprs[END_EXPR];
650  SourceLocation DoLoc;
651public:
652  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
653    : Stmt(DoStmtClass), DoLoc(DL) {
654    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
655    SubExprs[BODY] = body;
656    DoLoc = DL;
657  }
658
659  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
660  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
661  Stmt *getBody() { return SubExprs[BODY]; }
662  const Stmt *getBody() const { return SubExprs[BODY]; }
663
664  virtual SourceRange getSourceRange() const {
665    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
666  }
667  static bool classof(const Stmt *T) {
668    return T->getStmtClass() == DoStmtClass;
669  }
670  static bool classof(const DoStmt *) { return true; }
671
672  // Iterators
673  virtual child_iterator child_begin();
674  virtual child_iterator child_end();
675
676  virtual void EmitImpl(llvm::Serializer& S) const;
677  static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
678};
679
680
681/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
682/// the init/cond/inc parts of the ForStmt will be null if they were not
683/// specified in the source.
684///
685class ForStmt : public Stmt {
686  enum { INIT, COND, INC, BODY, END_EXPR };
687  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
688  SourceLocation ForLoc;
689public:
690  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
691    : Stmt(ForStmtClass) {
692    SubExprs[INIT] = Init;
693    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
694    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
695    SubExprs[BODY] = Body;
696    ForLoc = FL;
697  }
698
699  Stmt *getInit() { return SubExprs[INIT]; }
700  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
701  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
702  Stmt *getBody() { return SubExprs[BODY]; }
703
704  const Stmt *getInit() const { return SubExprs[INIT]; }
705  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
706  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
707  const Stmt *getBody() const { return SubExprs[BODY]; }
708
709  virtual SourceRange getSourceRange() const {
710    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
711  }
712  static bool classof(const Stmt *T) {
713    return T->getStmtClass() == ForStmtClass;
714  }
715  static bool classof(const ForStmt *) { return true; }
716
717  // Iterators
718  virtual child_iterator child_begin();
719  virtual child_iterator child_end();
720
721  virtual void EmitImpl(llvm::Serializer& S) const;
722  static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
723};
724
725/// GotoStmt - This represents a direct goto.
726///
727class GotoStmt : public Stmt {
728  LabelStmt *Label;
729  SourceLocation GotoLoc;
730  SourceLocation LabelLoc;
731public:
732  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
733    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
734
735  LabelStmt *getLabel() const { return Label; }
736
737  virtual SourceRange getSourceRange() const {
738    return SourceRange(GotoLoc, LabelLoc);
739  }
740  static bool classof(const Stmt *T) {
741    return T->getStmtClass() == GotoStmtClass;
742  }
743  static bool classof(const GotoStmt *) { return true; }
744
745  // Iterators
746  virtual child_iterator child_begin();
747  virtual child_iterator child_end();
748
749  virtual void EmitImpl(llvm::Serializer& S) const;
750  static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
751};
752
753/// IndirectGotoStmt - This represents an indirect goto.
754///
755class IndirectGotoStmt : public Stmt {
756  Stmt *Target;
757  // FIXME: Add location information (e.g. SourceLocation objects).
758  //        When doing so, update the serialization routines.
759public:
760  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass),
761                                   Target((Stmt*)target){}
762
763  Expr *getTarget();
764  const Expr *getTarget() const;
765
766  virtual SourceRange getSourceRange() const { return SourceRange(); }
767
768  static bool classof(const Stmt *T) {
769    return T->getStmtClass() == IndirectGotoStmtClass;
770  }
771  static bool classof(const IndirectGotoStmt *) { return true; }
772
773  // Iterators
774  virtual child_iterator child_begin();
775  virtual child_iterator child_end();
776
777  virtual void EmitImpl(llvm::Serializer& S) const;
778  static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
779};
780
781
782/// ContinueStmt - This represents a continue.
783///
784class ContinueStmt : public Stmt {
785  SourceLocation ContinueLoc;
786public:
787  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
788
789  virtual SourceRange getSourceRange() const {
790    return SourceRange(ContinueLoc);
791  }
792  static bool classof(const Stmt *T) {
793    return T->getStmtClass() == ContinueStmtClass;
794  }
795  static bool classof(const ContinueStmt *) { return true; }
796
797  // Iterators
798  virtual child_iterator child_begin();
799  virtual child_iterator child_end();
800
801  virtual void EmitImpl(llvm::Serializer& S) const;
802  static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
803};
804
805/// BreakStmt - This represents a break.
806///
807class BreakStmt : public Stmt {
808  SourceLocation BreakLoc;
809public:
810  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
811
812  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
813
814  static bool classof(const Stmt *T) {
815    return T->getStmtClass() == BreakStmtClass;
816  }
817  static bool classof(const BreakStmt *) { return true; }
818
819  // Iterators
820  virtual child_iterator child_begin();
821  virtual child_iterator child_end();
822
823  virtual void EmitImpl(llvm::Serializer& S) const;
824  static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
825};
826
827
828/// ReturnStmt - This represents a return, optionally of an expression:
829///   return;
830///   return 4;
831///
832/// Note that GCC allows return with no argument in a function declared to
833/// return a value, and it allows returning a value in functions declared to
834/// return void.  We explicitly model this in the AST, which means you can't
835/// depend on the return type of the function and the presence of an argument.
836///
837class ReturnStmt : public Stmt {
838  Stmt *RetExpr;
839  SourceLocation RetLoc;
840public:
841  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
842    RetExpr((Stmt*) E), RetLoc(RL) {}
843
844  const Expr *getRetValue() const;
845  Expr *getRetValue();
846
847  virtual SourceRange getSourceRange() const;
848
849  static bool classof(const Stmt *T) {
850    return T->getStmtClass() == ReturnStmtClass;
851  }
852  static bool classof(const ReturnStmt *) { return true; }
853
854  // Iterators
855  virtual child_iterator child_begin();
856  virtual child_iterator child_end();
857
858  virtual void EmitImpl(llvm::Serializer& S) const;
859  static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
860};
861
862/// AsmStmt - This represents a GNU inline-assembly statement extension.
863///
864class AsmStmt : public Stmt {
865  SourceLocation AsmLoc, RParenLoc;
866  StringLiteral *AsmStr;
867
868  bool IsSimple;
869  bool IsVolatile;
870
871  unsigned NumOutputs;
872  unsigned NumInputs;
873
874  llvm::SmallVector<std::string, 4> Names;
875  llvm::SmallVector<StringLiteral*, 4> Constraints;
876  llvm::SmallVector<Stmt*, 4> Exprs;
877
878  llvm::SmallVector<StringLiteral*, 4> Clobbers;
879public:
880  AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
881          unsigned numoutputs, unsigned numinputs,
882          std::string *names, StringLiteral **constraints,
883          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
884          StringLiteral **clobbers, SourceLocation rparenloc);
885
886  bool isVolatile() const { return IsVolatile; }
887  bool isSimple() const { return IsSimple; }
888
889  //===--- Asm String Analysis ---===//
890
891  const StringLiteral *getAsmString() const { return AsmStr; }
892  StringLiteral *getAsmString() { return AsmStr; }
893
894  /// AsmStringPiece - this is part of a decomposed asm string specification
895  /// (for use with the AnalyzeAsmString function below).  An asm string is
896  /// considered to be a concatenation of these parts.
897  class AsmStringPiece {
898  public:
899    enum Kind {
900      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
901      Operand  // Operand reference, with optional modifier %c4.
902    };
903  private:
904    Kind MyKind;
905    std::string Str;
906    unsigned OperandNo;
907  public:
908    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
909    AsmStringPiece(unsigned OpNo, char Modifier)
910      : MyKind(Operand), Str(), OperandNo(OpNo) {
911      Str += Modifier;
912    }
913
914    bool isString() const { return MyKind == String; }
915    bool isOperand() const { return MyKind == Operand; }
916
917    const std::string &getString() const {
918      assert(isString());
919      return Str;
920    }
921
922    unsigned getOperandNo() const {
923      assert(isOperand());
924      return OperandNo;
925    }
926
927    /// getModifier - Get the modifier for this operand, if present.  This
928    /// returns '\0' if there was no modifier.
929    char getModifier() const {
930      assert(isOperand());
931      return Str[0];
932    }
933  };
934
935  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
936  /// it into pieces.  If the asm string is erroneous, emit errors and return
937  /// true, otherwise return false.  This handles canonicalization and
938  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
939  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
940  unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
941                            ASTContext &C, unsigned &DiagOffs) const;
942
943
944  //===--- Output operands ---===//
945
946  unsigned getNumOutputs() const { return NumOutputs; }
947
948  const std::string &getOutputName(unsigned i) const {
949    return Names[i];
950  }
951
952  /// getOutputConstraint - Return the constraint string for the specified
953  /// output operand.  All output constraints are known to be non-empty (either
954  /// '=' or '+').
955  std::string getOutputConstraint(unsigned i) const;
956
957  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
958    return Constraints[i];
959  }
960  StringLiteral *getOutputConstraintLiteral(unsigned i) {
961    return Constraints[i];
962  }
963
964
965  Expr *getOutputExpr(unsigned i);
966
967  const Expr *getOutputExpr(unsigned i) const {
968    return const_cast<AsmStmt*>(this)->getOutputExpr(i);
969  }
970
971  /// isOutputPlusConstraint - Return true if the specified output constraint
972  /// is a "+" constraint (which is both an input and an output) or false if it
973  /// is an "=" constraint (just an output).
974  bool isOutputPlusConstraint(unsigned i) const {
975    return getOutputConstraint(i)[0] == '+';
976  }
977
978  /// getNumPlusOperands - Return the number of output operands that have a "+"
979  /// constraint.
980  unsigned getNumPlusOperands() const;
981
982  //===--- Input operands ---===//
983
984  unsigned getNumInputs() const { return NumInputs; }
985
986  const std::string &getInputName(unsigned i) const {
987    return Names[i + NumOutputs];
988  }
989
990  /// getInputConstraint - Return the specified input constraint.  Unlike output
991  /// constraints, these can be empty.
992  std::string getInputConstraint(unsigned i) const;
993
994  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
995    return Constraints[i + NumOutputs];
996  }
997  StringLiteral *getInputConstraintLiteral(unsigned i) {
998    return Constraints[i + NumOutputs];
999  }
1000
1001
1002  Expr *getInputExpr(unsigned i);
1003
1004  const Expr *getInputExpr(unsigned i) const {
1005    return const_cast<AsmStmt*>(this)->getInputExpr(i);
1006  }
1007
1008  //===--- Other ---===//
1009
1010  /// getNamedOperand - Given a symbolic operand reference like %[foo],
1011  /// translate this into a numeric value needed to reference the same operand.
1012  /// This returns -1 if the operand name is invalid.
1013  int getNamedOperand(const std::string &SymbolicName) const;
1014
1015
1016
1017  unsigned getNumClobbers() const { return Clobbers.size(); }
1018  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
1019  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
1020
1021  virtual SourceRange getSourceRange() const {
1022    return SourceRange(AsmLoc, RParenLoc);
1023  }
1024
1025  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
1026  static bool classof(const AsmStmt *) { return true; }
1027
1028  // Input expr iterators.
1029
1030  typedef ExprIterator inputs_iterator;
1031  typedef ConstExprIterator const_inputs_iterator;
1032
1033  inputs_iterator begin_inputs() {
1034    return &Exprs[0] + NumOutputs;
1035  }
1036
1037  inputs_iterator end_inputs() {
1038    return  &Exprs[0] + NumOutputs + NumInputs;
1039  }
1040
1041  const_inputs_iterator begin_inputs() const {
1042    return &Exprs[0] + NumOutputs;
1043  }
1044
1045  const_inputs_iterator end_inputs() const {
1046    return  &Exprs[0] + NumOutputs + NumInputs;}
1047
1048  // Output expr iterators.
1049
1050  typedef ExprIterator outputs_iterator;
1051  typedef ConstExprIterator const_outputs_iterator;
1052
1053  outputs_iterator begin_outputs() { return &Exprs[0]; }
1054  outputs_iterator end_outputs() { return &Exprs[0] + NumOutputs; }
1055
1056  const_outputs_iterator begin_outputs() const { return &Exprs[0]; }
1057  const_outputs_iterator end_outputs() const { return &Exprs[0] + NumOutputs; }
1058
1059  // Input name iterator.
1060
1061  const std::string *begin_output_names() const {
1062    return &Names[0];
1063  }
1064
1065  const std::string *end_output_names() const {
1066    return &Names[0] + NumOutputs;
1067  }
1068
1069  // Child iterators
1070
1071  virtual child_iterator child_begin();
1072  virtual child_iterator child_end();
1073
1074  virtual void EmitImpl(llvm::Serializer& S) const;
1075  static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1076};
1077
1078/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
1079/// represented as 'for (element 'in' collection-expression)' stmt.
1080///
1081class ObjCForCollectionStmt : public Stmt {
1082  enum { ELEM, COLLECTION, BODY, END_EXPR };
1083  Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
1084  SourceLocation ForLoc;
1085  SourceLocation RParenLoc;
1086public:
1087  ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
1088                        SourceLocation FCL, SourceLocation RPL);
1089
1090  Stmt *getElement() { return SubExprs[ELEM]; }
1091  Expr *getCollection() {
1092    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
1093  }
1094  Stmt *getBody() { return SubExprs[BODY]; }
1095
1096  const Stmt *getElement() const { return SubExprs[ELEM]; }
1097  const Expr *getCollection() const {
1098    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
1099  }
1100  const Stmt *getBody() const { return SubExprs[BODY]; }
1101
1102  SourceLocation getRParenLoc() const { return RParenLoc; }
1103
1104  virtual SourceRange getSourceRange() const {
1105    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
1106  }
1107  static bool classof(const Stmt *T) {
1108    return T->getStmtClass() == ObjCForCollectionStmtClass;
1109  }
1110  static bool classof(const ObjCForCollectionStmt *) { return true; }
1111
1112  // Iterators
1113  virtual child_iterator child_begin();
1114  virtual child_iterator child_end();
1115
1116  virtual void EmitImpl(llvm::Serializer& S) const;
1117  static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1118};
1119
1120/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
1121class ObjCAtCatchStmt : public Stmt {
1122private:
1123  enum { BODY, NEXT_CATCH, END_EXPR };
1124  ParmVarDecl *ExceptionDecl;
1125  Stmt *SubExprs[END_EXPR];
1126  SourceLocation AtCatchLoc, RParenLoc;
1127
1128  // Used by deserialization.
1129  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc)
1130  : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {}
1131
1132public:
1133  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
1134                  ParmVarDecl *catchVarDecl,
1135                  Stmt *atCatchStmt, Stmt *atCatchList);
1136
1137  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
1138  Stmt *getCatchBody() { return SubExprs[BODY]; }
1139
1140  const ObjCAtCatchStmt *getNextCatchStmt() const {
1141    return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1142  }
1143  ObjCAtCatchStmt *getNextCatchStmt() {
1144    return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1145  }
1146
1147  const ParmVarDecl *getCatchParamDecl() const {
1148    return ExceptionDecl;
1149  }
1150  ParmVarDecl *getCatchParamDecl() {
1151    return ExceptionDecl;
1152  }
1153
1154  SourceLocation getRParenLoc() const { return RParenLoc; }
1155
1156  virtual SourceRange getSourceRange() const {
1157    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
1158  }
1159
1160  bool hasEllipsis() const { return getCatchParamDecl() == 0; }
1161
1162  static bool classof(const Stmt *T) {
1163    return T->getStmtClass() == ObjCAtCatchStmtClass;
1164  }
1165  static bool classof(const ObjCAtCatchStmt *) { return true; }
1166
1167  virtual child_iterator child_begin();
1168  virtual child_iterator child_end();
1169
1170  virtual void EmitImpl(llvm::Serializer& S) const;
1171  static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1172};
1173
1174/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
1175class ObjCAtFinallyStmt : public Stmt {
1176  Stmt *AtFinallyStmt;
1177  SourceLocation AtFinallyLoc;
1178public:
1179  ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
1180  : Stmt(ObjCAtFinallyStmtClass),
1181    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
1182
1183  const Stmt *getFinallyBody () const { return AtFinallyStmt; }
1184  Stmt *getFinallyBody () { return AtFinallyStmt; }
1185
1186  virtual SourceRange getSourceRange() const {
1187    return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
1188  }
1189
1190  static bool classof(const Stmt *T) {
1191    return T->getStmtClass() == ObjCAtFinallyStmtClass;
1192  }
1193  static bool classof(const ObjCAtFinallyStmt *) { return true; }
1194
1195  virtual child_iterator child_begin();
1196  virtual child_iterator child_end();
1197
1198  virtual void EmitImpl(llvm::Serializer& S) const;
1199  static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1200};
1201
1202/// ObjCAtTryStmt - This represent objective-c's over-all
1203/// @try ... @catch ... @finally statement.
1204class ObjCAtTryStmt : public Stmt {
1205private:
1206  enum { TRY, CATCH, FINALLY, END_EXPR };
1207  Stmt* SubStmts[END_EXPR];
1208
1209  SourceLocation AtTryLoc;
1210public:
1211  ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
1212                Stmt *atCatchStmt,
1213                Stmt *atFinallyStmt)
1214  : Stmt(ObjCAtTryStmtClass) {
1215      SubStmts[TRY] = atTryStmt;
1216      SubStmts[CATCH] = atCatchStmt;
1217      SubStmts[FINALLY] = atFinallyStmt;
1218      AtTryLoc = atTryLoc;
1219    }
1220
1221  const Stmt *getTryBody() const { return SubStmts[TRY]; }
1222  Stmt *getTryBody() { return SubStmts[TRY]; }
1223  const ObjCAtCatchStmt *getCatchStmts() const {
1224    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1225  }
1226  ObjCAtCatchStmt *getCatchStmts() {
1227    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1228  }
1229  const ObjCAtFinallyStmt *getFinallyStmt() const {
1230    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1231  }
1232  ObjCAtFinallyStmt *getFinallyStmt() {
1233    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1234  }
1235  virtual SourceRange getSourceRange() const {
1236    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
1237  }
1238
1239  static bool classof(const Stmt *T) {
1240    return T->getStmtClass() == ObjCAtTryStmtClass;
1241  }
1242  static bool classof(const ObjCAtTryStmt *) { return true; }
1243
1244  virtual child_iterator child_begin();
1245  virtual child_iterator child_end();
1246
1247  virtual void EmitImpl(llvm::Serializer& S) const;
1248  static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1249};
1250
1251/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
1252/// Example: @synchronized (sem) {
1253///             do-something;
1254///          }
1255///
1256class ObjCAtSynchronizedStmt : public Stmt {
1257private:
1258  enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
1259  Stmt* SubStmts[END_EXPR];
1260  SourceLocation AtSynchronizedLoc;
1261
1262public:
1263  ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
1264                         Stmt *synchBody)
1265  : Stmt(ObjCAtSynchronizedStmtClass) {
1266      SubStmts[SYNC_EXPR] = synchExpr;
1267      SubStmts[SYNC_BODY] = synchBody;
1268      AtSynchronizedLoc = atSynchronizedLoc;
1269    }
1270
1271  const CompoundStmt *getSynchBody() const {
1272    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1273  }
1274  CompoundStmt *getSynchBody() {
1275    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1276  }
1277
1278  const Expr *getSynchExpr() const {
1279    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1280  }
1281  Expr *getSynchExpr() {
1282    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1283  }
1284
1285  virtual SourceRange getSourceRange() const {
1286    return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
1287  }
1288
1289  static bool classof(const Stmt *T) {
1290    return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
1291  }
1292  static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
1293
1294  virtual child_iterator child_begin();
1295  virtual child_iterator child_end();
1296
1297  virtual void EmitImpl(llvm::Serializer& S) const;
1298  static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D,
1299                                            ASTContext& C);
1300};
1301
1302/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
1303class ObjCAtThrowStmt : public Stmt {
1304  Stmt *Throw;
1305  SourceLocation AtThrowLoc;
1306public:
1307  ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
1308  : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
1309    AtThrowLoc = atThrowLoc;
1310  }
1311
1312  const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
1313  Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
1314
1315  virtual SourceRange getSourceRange() const {
1316    if (Throw)
1317      return SourceRange(AtThrowLoc, Throw->getLocEnd());
1318    else
1319      return SourceRange(AtThrowLoc);
1320  }
1321
1322  static bool classof(const Stmt *T) {
1323    return T->getStmtClass() == ObjCAtThrowStmtClass;
1324  }
1325  static bool classof(const ObjCAtThrowStmt *) { return true; }
1326
1327  virtual child_iterator child_begin();
1328  virtual child_iterator child_end();
1329
1330  virtual void EmitImpl(llvm::Serializer& S) const;
1331  static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1332};
1333
1334/// CXXCatchStmt - This represents a C++ catch block.
1335class CXXCatchStmt : public Stmt {
1336  SourceLocation CatchLoc;
1337  /// The exception-declaration of the type.
1338  Decl *ExceptionDecl;
1339  /// The handler block.
1340  Stmt *HandlerBlock;
1341
1342public:
1343  CXXCatchStmt(SourceLocation catchLoc, Decl *exDecl, Stmt *handlerBlock)
1344  : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
1345    HandlerBlock(handlerBlock) {}
1346
1347  virtual void Destroy(ASTContext& Ctx);
1348
1349  virtual SourceRange getSourceRange() const {
1350    return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
1351  }
1352
1353  Decl *getExceptionDecl() { return ExceptionDecl; }
1354  QualType getCaughtType();
1355  Stmt *getHandlerBlock() { return HandlerBlock; }
1356
1357  static bool classof(const Stmt *T) {
1358    return T->getStmtClass() == CXXCatchStmtClass;
1359  }
1360  static bool classof(const CXXCatchStmt *) { return true; }
1361
1362  virtual child_iterator child_begin();
1363  virtual child_iterator child_end();
1364
1365  virtual void EmitImpl(llvm::Serializer& S) const;
1366  static CXXCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1367};
1368
1369/// CXXTryStmt - A C++ try block, including all handlers.
1370class CXXTryStmt : public Stmt {
1371  SourceLocation TryLoc;
1372  // First place is the guarded CompoundStatement. Subsequent are the handlers.
1373  // More than three handlers should be rare.
1374  llvm::SmallVector<Stmt*, 4> Stmts;
1375
1376public:
1377  CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
1378             Stmt **handlers, unsigned numHandlers);
1379
1380  virtual SourceRange getSourceRange() const {
1381    return SourceRange(TryLoc, Stmts.back()->getLocEnd());
1382  }
1383
1384  CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); }
1385  const CompoundStmt *getTryBlock() const {
1386    return llvm::cast<CompoundStmt>(Stmts[0]);
1387  }
1388
1389  unsigned getNumHandlers() const { return Stmts.size() - 1; }
1390  CXXCatchStmt *getHandler(unsigned i) {
1391    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
1392  }
1393  const CXXCatchStmt *getHandler(unsigned i) const {
1394    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
1395  }
1396
1397  static bool classof(const Stmt *T) {
1398    return T->getStmtClass() == CXXTryStmtClass;
1399  }
1400  static bool classof(const CXXTryStmt *) { return true; }
1401
1402  virtual child_iterator child_begin();
1403  virtual child_iterator child_end();
1404
1405  virtual void EmitImpl(llvm::Serializer& S) const;
1406  static CXXTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1407};
1408
1409}  // end namespace clang
1410
1411#endif
1412