Stmt.h revision 93b2bdb866d49e3dab4623a822db281042e87382
1//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the Stmt interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_STMT_H
15#define LLVM_CLANG_AST_STMT_H
16
17#include "llvm/Support/Casting.h"
18#include "llvm/Support/raw_ostream.h"
19#include "clang/Basic/SourceLocation.h"
20#include "clang/AST/StmtIterator.h"
21#include "clang/AST/DeclGroup.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/iterator.h"
24#include "llvm/Bitcode/SerializationFwd.h"
25#include "clang/AST/ASTContext.h"
26#include <string>
27
28using llvm::dyn_cast_or_null;
29
30namespace clang {
31  class ASTContext;
32  class Expr;
33  class Decl;
34  class QualType;
35  class IdentifierInfo;
36  class SourceManager;
37  class StringLiteral;
38  class SwitchStmt;
39  class PrinterHelper;
40
41  //===----------------------------------------------------------------------===//
42  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
43  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
44  //  references to children (to be compatible with StmtIterator).
45  //===----------------------------------------------------------------------===//
46
47  class Stmt;
48  class Expr;
49
50  class ExprIterator {
51    Stmt** I;
52  public:
53    ExprIterator(Stmt** i) : I(i) {}
54    ExprIterator() : I(0) {}
55    ExprIterator& operator++() { ++I; return *this; }
56    ExprIterator operator-(size_t i) { return I-i; }
57    ExprIterator operator+(size_t i) { return I+i; }
58    Expr* operator[](size_t idx);
59    // FIXME: Verify that this will correctly return a signed distance.
60    signed operator-(const ExprIterator& R) const { return I - R.I; }
61    Expr* operator*() const;
62    Expr* operator->() const;
63    bool operator==(const ExprIterator& R) const { return I == R.I; }
64    bool operator!=(const ExprIterator& R) const { return I != R.I; }
65    bool operator>(const ExprIterator& R) const { return I > R.I; }
66    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
67  };
68
69  class ConstExprIterator {
70    Stmt* const * I;
71  public:
72    ConstExprIterator(Stmt* const* i) : I(i) {}
73    ConstExprIterator() : I(0) {}
74    ConstExprIterator& operator++() { ++I; return *this; }
75    ConstExprIterator operator+(size_t i) { return I+i; }
76    ConstExprIterator operator-(size_t i) { return I-i; }
77    const Expr * operator[](size_t idx) const;
78    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
79    const Expr * operator*() const;
80    const Expr * operator->() const;
81    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
82    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
83    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
84    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
85  };
86
87//===----------------------------------------------------------------------===//
88// AST classes for statements.
89//===----------------------------------------------------------------------===//
90
91/// Stmt - This represents one statement.
92///
93class Stmt {
94public:
95  enum StmtClass {
96    NoStmtClass = 0,
97#define STMT(CLASS, PARENT) CLASS##Class,
98#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class,
99#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
100#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
101#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
102#include "clang/AST/StmtNodes.def"
103};
104private:
105  const StmtClass sClass;
106
107  // Make vanilla 'new' and 'delete' illegal for Stmts.
108protected:
109  void* operator new(size_t bytes) throw() {
110    assert(0 && "Stmts cannot be allocated with regular 'new'.");
111    return 0;
112  }
113  void operator delete(void* data) throw() {
114    assert(0 && "Stmts cannot be released with regular 'delete'.");
115  }
116
117public:
118  // Only allow allocation of Stmts using the allocator in ASTContext
119  // or by doing a placement new.
120  void* operator new(size_t bytes, ASTContext& C,
121                     unsigned alignment = 16) throw() {
122    return ::operator new(bytes, C, alignment);
123  }
124
125  void* operator new(size_t bytes, ASTContext* C,
126                     unsigned alignment = 16) throw() {
127    return ::operator new(bytes, *C, alignment);
128  }
129
130  void* operator new(size_t bytes, void* mem) throw() {
131    return mem;
132  }
133
134  void operator delete(void*, ASTContext& C) throw() { }
135  void operator delete(void*, ASTContext& C, unsigned alignment) throw() { }
136  void operator delete(void*, std::size_t) throw() { }
137
138protected:
139  /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
140  ///  recursively release child AST nodes.
141  void DestroyChildren(ASTContext& Ctx);
142
143public:
144  Stmt(StmtClass SC) : sClass(SC) {
145    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
146  }
147  virtual ~Stmt() {}
148
149  virtual void Destroy(ASTContext& Ctx);
150
151  StmtClass getStmtClass() const { return sClass; }
152  const char *getStmtClassName() const;
153
154  /// SourceLocation tokens are not useful in isolation - they are low level
155  /// value objects created/interpreted by SourceManager. We assume AST
156  /// clients will have a pointer to the respective SourceManager.
157  virtual SourceRange getSourceRange() const = 0;
158  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
159  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
160
161  // global temp stats (until we have a per-module visitor)
162  static void addStmtClass(const StmtClass s);
163  static bool CollectingStats(bool enable=false);
164  static void PrintStats();
165
166  /// dump - This does a local dump of the specified AST fragment.  It dumps the
167  /// specified node and a few nodes underneath it, but not the whole subtree.
168  /// This is useful in a debugger.
169  void dump() const;
170  void dump(SourceManager &SM) const;
171
172  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
173  void dumpAll() const;
174  void dumpAll(SourceManager &SM) const;
175
176  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
177  /// back to its original source language syntax.
178  void dumpPretty() const;
179  void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL, unsigned = 0,
180                   bool NoIndent=false) const;
181
182  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
183  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
184  void viewAST() const;
185
186  // Implement isa<T> support.
187  static bool classof(const Stmt *) { return true; }
188
189  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
190  ///  contain implicit control-flow in the order their subexpressions
191  ///  are evaluated.  This predicate returns true if this statement has
192  ///  such implicit control-flow.  Such statements are also specially handled
193  ///  within CFGs.
194  bool hasImplicitControlFlow() const;
195
196  /// Child Iterators: All subclasses must implement child_begin and child_end
197  ///  to permit easy iteration over the substatements/subexpessions of an
198  ///  AST node.  This permits easy iteration over all nodes in the AST.
199  typedef StmtIterator       child_iterator;
200  typedef ConstStmtIterator  const_child_iterator;
201
202  virtual child_iterator child_begin() = 0;
203  virtual child_iterator child_end()   = 0;
204
205  const_child_iterator child_begin() const {
206    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
207  }
208
209  const_child_iterator child_end() const {
210    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
211  }
212
213  void Emit(llvm::Serializer& S) const;
214  static Stmt* Create(llvm::Deserializer& D, ASTContext& C);
215
216  virtual void EmitImpl(llvm::Serializer& S) const {
217    // This method will eventually be a pure-virtual function.
218    assert (false && "Not implemented.");
219  }
220};
221
222/// DeclStmt - Adaptor class for mixing declarations with statements and
223/// expressions. For example, CompoundStmt mixes statements, expressions
224/// and declarations (variables, types). Another example is ForStmt, where
225/// the first statement can be an expression or a declaration.
226///
227class DeclStmt : public Stmt {
228protected:
229  DeclGroupRef DG;
230  SourceLocation StartLoc, EndLoc;
231public:
232  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
233           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
234                                    StartLoc(startLoc), EndLoc(endLoc) {}
235
236  virtual void Destroy(ASTContext& Ctx);
237
238  // hasSolitaryDecl - This method returns true if this DeclStmt refers
239  // to a single Decl.
240  bool hasSolitaryDecl() const {
241    return DG.hasSolitaryDecl();
242  }
243
244  const Decl* getSolitaryDecl() const {
245    assert (hasSolitaryDecl() &&
246            "Caller assumes this DeclStmt points to one Decl*");
247    return *DG.begin();
248  }
249
250  Decl* getSolitaryDecl() {
251    assert (hasSolitaryDecl() &&
252            "Caller assumes this DeclStmt points to one Decl*");
253    return *DG.begin();
254  }
255
256  SourceLocation getStartLoc() const { return StartLoc; }
257  SourceLocation getEndLoc() const { return EndLoc; }
258
259  SourceRange getSourceRange() const {
260    return SourceRange(StartLoc, EndLoc);
261  }
262
263  static bool classof(const Stmt *T) {
264    return T->getStmtClass() == DeclStmtClass;
265  }
266  static bool classof(const DeclStmt *) { return true; }
267
268  // Iterators over subexpressions.
269  virtual child_iterator child_begin();
270  virtual child_iterator child_end();
271
272  class decl_iterator {
273    DeclGroupRef::iterator I;
274  public:
275    decl_iterator(DeclGroupRef::iterator i) : I(i) {}
276    decl_iterator& operator++() { ++I; return *this; }
277    bool operator==(const decl_iterator& R) const {
278      return R.I == I;
279    }
280    bool operator!=(const decl_iterator& R) const {
281      return R.I != I;
282    }
283    Decl* operator*() const {
284      return *I;
285    }
286  };
287
288  class const_decl_iterator {
289    DeclGroupRef::const_iterator I;
290  public:
291    const_decl_iterator(DeclGroupRef::const_iterator i) : I(i) {}
292    const_decl_iterator& operator++() { ++I; return *this; }
293    bool operator==(const const_decl_iterator& R) const {
294      return R.I == I;
295    }
296    bool operator!=(const const_decl_iterator& R) const {
297      return R.I != I;
298    }
299    Decl* operator*() const {
300      return *I;
301    }
302  };
303
304  decl_iterator decl_begin() { return DG.begin(); }
305  decl_iterator decl_end() { return DG.end(); }
306  const_decl_iterator decl_begin() const { return DG.begin(); }
307  const_decl_iterator decl_end() const { return DG.end(); }
308
309  // Serialization.
310  virtual void EmitImpl(llvm::Serializer& S) const;
311  static DeclStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
312};
313
314/// NullStmt - This is the null statement ";": C99 6.8.3p3.
315///
316class NullStmt : public Stmt {
317  SourceLocation SemiLoc;
318public:
319  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
320
321  SourceLocation getSemiLoc() const { return SemiLoc; }
322
323  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
324
325  static bool classof(const Stmt *T) {
326    return T->getStmtClass() == NullStmtClass;
327  }
328  static bool classof(const NullStmt *) { return true; }
329
330  // Iterators
331  virtual child_iterator child_begin();
332  virtual child_iterator child_end();
333
334  virtual void EmitImpl(llvm::Serializer& S) const;
335  static NullStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
336};
337
338/// CompoundStmt - This represents a group of statements like { stmt stmt }.
339///
340class CompoundStmt : public Stmt {
341  Stmt** Body;
342  unsigned NumStmts;
343  SourceLocation LBracLoc, RBracLoc;
344public:
345  CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
346                             SourceLocation LB, SourceLocation RB)
347  : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
348    if (NumStmts == 0) {
349      Body = 0;
350      return;
351    }
352
353    Body = new (C) Stmt*[NumStmts];
354    memcpy(Body, StmtStart, numStmts * sizeof(*Body));
355  }
356
357  bool body_empty() const { return NumStmts == 0; }
358
359  typedef Stmt** body_iterator;
360  body_iterator body_begin() { return Body; }
361  body_iterator body_end() { return Body + NumStmts; }
362  Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
363
364  typedef Stmt* const * const_body_iterator;
365  const_body_iterator body_begin() const { return Body; }
366  const_body_iterator body_end() const { return Body + NumStmts; }
367  const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
368
369  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
370  reverse_body_iterator body_rbegin() {
371    return reverse_body_iterator(body_end());
372  }
373  reverse_body_iterator body_rend() {
374    return reverse_body_iterator(body_begin());
375  }
376
377  typedef std::reverse_iterator<const_body_iterator>
378          const_reverse_body_iterator;
379
380  const_reverse_body_iterator body_rbegin() const {
381    return const_reverse_body_iterator(body_end());
382  }
383
384  const_reverse_body_iterator body_rend() const {
385    return const_reverse_body_iterator(body_begin());
386  }
387
388  virtual SourceRange getSourceRange() const {
389    return SourceRange(LBracLoc, RBracLoc);
390  }
391
392  SourceLocation getLBracLoc() const { return LBracLoc; }
393  SourceLocation getRBracLoc() const { return RBracLoc; }
394
395  static bool classof(const Stmt *T) {
396    return T->getStmtClass() == CompoundStmtClass;
397  }
398  static bool classof(const CompoundStmt *) { return true; }
399
400  // Iterators
401  virtual child_iterator child_begin();
402  virtual child_iterator child_end();
403
404  virtual void EmitImpl(llvm::Serializer& S) const;
405  static CompoundStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
406};
407
408// SwitchCase is the base class for CaseStmt and DefaultStmt,
409class SwitchCase : public Stmt {
410protected:
411  // A pointer to the following CaseStmt or DefaultStmt class,
412  // used by SwitchStmt.
413  SwitchCase *NextSwitchCase;
414
415  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
416
417public:
418  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
419
420  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
421
422  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
423
424  virtual Stmt* v_getSubStmt() = 0;
425  Stmt *getSubStmt() { return v_getSubStmt(); }
426
427  virtual SourceRange getSourceRange() const { return SourceRange(); }
428
429  static bool classof(const Stmt *T) {
430    return T->getStmtClass() == CaseStmtClass ||
431    T->getStmtClass() == DefaultStmtClass;
432  }
433  static bool classof(const SwitchCase *) { return true; }
434};
435
436class CaseStmt : public SwitchCase {
437  enum { SUBSTMT, LHS, RHS, END_EXPR };
438  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
439                             // GNU "case 1 ... 4" extension
440  SourceLocation CaseLoc;
441public:
442  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc)
443    : SwitchCase(CaseStmtClass) {
444    SubExprs[SUBSTMT] = substmt;
445    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
446    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
447    CaseLoc = caseLoc;
448  }
449
450  SourceLocation getCaseLoc() const { return CaseLoc; }
451
452  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
453  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
454  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
455  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
456  const Expr *getLHS() const {
457    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
458  }
459  const Expr *getRHS() const {
460    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
461  }
462  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
463
464  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
465  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
466  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
467
468
469  virtual SourceRange getSourceRange() const {
470    return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd());
471  }
472  static bool classof(const Stmt *T) {
473    return T->getStmtClass() == CaseStmtClass;
474  }
475  static bool classof(const CaseStmt *) { return true; }
476
477  // Iterators
478  virtual child_iterator child_begin();
479  virtual child_iterator child_end();
480
481  virtual void EmitImpl(llvm::Serializer& S) const;
482  static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
483};
484
485class DefaultStmt : public SwitchCase {
486  Stmt* SubStmt;
487  SourceLocation DefaultLoc;
488public:
489  DefaultStmt(SourceLocation DL, Stmt *substmt) :
490    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
491
492  Stmt *getSubStmt() { return SubStmt; }
493  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
494  const Stmt *getSubStmt() const { return SubStmt; }
495
496  SourceLocation getDefaultLoc() const { return DefaultLoc; }
497
498  virtual SourceRange getSourceRange() const {
499    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
500  }
501  static bool classof(const Stmt *T) {
502    return T->getStmtClass() == DefaultStmtClass;
503  }
504  static bool classof(const DefaultStmt *) { return true; }
505
506  // Iterators
507  virtual child_iterator child_begin();
508  virtual child_iterator child_end();
509
510  virtual void EmitImpl(llvm::Serializer& S) const;
511  static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
512};
513
514class LabelStmt : public Stmt {
515  IdentifierInfo *Label;
516  Stmt *SubStmt;
517  SourceLocation IdentLoc;
518public:
519  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
520    : Stmt(LabelStmtClass), Label(label),
521      SubStmt(substmt), IdentLoc(IL) {}
522
523  SourceLocation getIdentLoc() const { return IdentLoc; }
524  IdentifierInfo *getID() const { return Label; }
525  const char *getName() const;
526  Stmt *getSubStmt() { return SubStmt; }
527  const Stmt *getSubStmt() const { return SubStmt; }
528
529  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
530  void setSubStmt(Stmt *SS) { SubStmt = SS; }
531
532  virtual SourceRange getSourceRange() const {
533    return SourceRange(IdentLoc, SubStmt->getLocEnd());
534  }
535  static bool classof(const Stmt *T) {
536    return T->getStmtClass() == LabelStmtClass;
537  }
538  static bool classof(const LabelStmt *) { return true; }
539
540  // Iterators
541  virtual child_iterator child_begin();
542  virtual child_iterator child_end();
543
544  virtual void EmitImpl(llvm::Serializer& S) const;
545  static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
546};
547
548
549/// IfStmt - This represents an if/then/else.
550///
551class IfStmt : public Stmt {
552  enum { COND, THEN, ELSE, END_EXPR };
553  Stmt* SubExprs[END_EXPR];
554  SourceLocation IfLoc;
555public:
556  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
557    : Stmt(IfStmtClass)  {
558    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
559    SubExprs[THEN] = then;
560    SubExprs[ELSE] = elsev;
561    IfLoc = IL;
562  }
563
564  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
565  const Stmt *getThen() const { return SubExprs[THEN]; }
566  const Stmt *getElse() const { return SubExprs[ELSE]; }
567
568  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
569  Stmt *getThen() { return SubExprs[THEN]; }
570  Stmt *getElse() { return SubExprs[ELSE]; }
571
572  virtual SourceRange getSourceRange() const {
573    if (SubExprs[ELSE])
574      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
575    else
576      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
577  }
578
579  static bool classof(const Stmt *T) {
580    return T->getStmtClass() == IfStmtClass;
581  }
582  static bool classof(const IfStmt *) { return true; }
583
584  // Iterators
585  virtual child_iterator child_begin();
586  virtual child_iterator child_end();
587
588  virtual void EmitImpl(llvm::Serializer& S) const;
589  static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
590};
591
592/// SwitchStmt - This represents a 'switch' stmt.
593///
594class SwitchStmt : public Stmt {
595  enum { COND, BODY, END_EXPR };
596  Stmt* SubExprs[END_EXPR];
597  // This points to a linked list of case and default statements.
598  SwitchCase *FirstCase;
599  SourceLocation SwitchLoc;
600public:
601  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
602      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
603      SubExprs[BODY] = NULL;
604    }
605
606  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
607  const Stmt *getBody() const { return SubExprs[BODY]; }
608  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
609
610  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
611  Stmt *getBody() { return SubExprs[BODY]; }
612  SwitchCase *getSwitchCaseList() { return FirstCase; }
613
614  void setBody(Stmt *S, SourceLocation SL) {
615    SubExprs[BODY] = S;
616    SwitchLoc = SL;
617  }
618  void addSwitchCase(SwitchCase *SC) {
619    if (FirstCase)
620      SC->setNextSwitchCase(FirstCase);
621
622    FirstCase = SC;
623  }
624  virtual SourceRange getSourceRange() const {
625    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
626  }
627  static bool classof(const Stmt *T) {
628    return T->getStmtClass() == SwitchStmtClass;
629  }
630  static bool classof(const SwitchStmt *) { return true; }
631
632  // Iterators
633  virtual child_iterator child_begin();
634  virtual child_iterator child_end();
635
636  virtual void EmitImpl(llvm::Serializer& S) const;
637  static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
638};
639
640
641/// WhileStmt - This represents a 'while' stmt.
642///
643class WhileStmt : public Stmt {
644  enum { COND, BODY, END_EXPR };
645  Stmt* SubExprs[END_EXPR];
646  SourceLocation WhileLoc;
647public:
648  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
649    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
650    SubExprs[BODY] = body;
651    WhileLoc = WL;
652  }
653
654  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
655  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
656  Stmt *getBody() { return SubExprs[BODY]; }
657  const Stmt *getBody() const { return SubExprs[BODY]; }
658
659  virtual SourceRange getSourceRange() const {
660    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
661  }
662  static bool classof(const Stmt *T) {
663    return T->getStmtClass() == WhileStmtClass;
664  }
665  static bool classof(const WhileStmt *) { return true; }
666
667  // Iterators
668  virtual child_iterator child_begin();
669  virtual child_iterator child_end();
670
671  virtual void EmitImpl(llvm::Serializer& S) const;
672  static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
673};
674
675/// DoStmt - This represents a 'do/while' stmt.
676///
677class DoStmt : public Stmt {
678  enum { COND, BODY, END_EXPR };
679  Stmt* SubExprs[END_EXPR];
680  SourceLocation DoLoc;
681public:
682  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
683    : Stmt(DoStmtClass), DoLoc(DL) {
684    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
685    SubExprs[BODY] = body;
686    DoLoc = DL;
687  }
688
689  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
690  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
691  Stmt *getBody() { return SubExprs[BODY]; }
692  const Stmt *getBody() const { return SubExprs[BODY]; }
693
694  virtual SourceRange getSourceRange() const {
695    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
696  }
697  static bool classof(const Stmt *T) {
698    return T->getStmtClass() == DoStmtClass;
699  }
700  static bool classof(const DoStmt *) { return true; }
701
702  // Iterators
703  virtual child_iterator child_begin();
704  virtual child_iterator child_end();
705
706  virtual void EmitImpl(llvm::Serializer& S) const;
707  static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
708};
709
710
711/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
712/// the init/cond/inc parts of the ForStmt will be null if they were not
713/// specified in the source.
714///
715class ForStmt : public Stmt {
716  enum { INIT, COND, INC, BODY, END_EXPR };
717  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
718  SourceLocation ForLoc;
719public:
720  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
721    : Stmt(ForStmtClass) {
722    SubExprs[INIT] = Init;
723    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
724    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
725    SubExprs[BODY] = Body;
726    ForLoc = FL;
727  }
728
729  Stmt *getInit() { return SubExprs[INIT]; }
730  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
731  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
732  Stmt *getBody() { return SubExprs[BODY]; }
733
734  const Stmt *getInit() const { return SubExprs[INIT]; }
735  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
736  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
737  const Stmt *getBody() const { return SubExprs[BODY]; }
738
739  virtual SourceRange getSourceRange() const {
740    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
741  }
742  static bool classof(const Stmt *T) {
743    return T->getStmtClass() == ForStmtClass;
744  }
745  static bool classof(const ForStmt *) { return true; }
746
747  // Iterators
748  virtual child_iterator child_begin();
749  virtual child_iterator child_end();
750
751  virtual void EmitImpl(llvm::Serializer& S) const;
752  static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
753};
754
755/// GotoStmt - This represents a direct goto.
756///
757class GotoStmt : public Stmt {
758  LabelStmt *Label;
759  SourceLocation GotoLoc;
760  SourceLocation LabelLoc;
761public:
762  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
763    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
764
765  LabelStmt *getLabel() const { return Label; }
766
767  virtual SourceRange getSourceRange() const {
768    return SourceRange(GotoLoc, LabelLoc);
769  }
770  static bool classof(const Stmt *T) {
771    return T->getStmtClass() == GotoStmtClass;
772  }
773  static bool classof(const GotoStmt *) { return true; }
774
775  // Iterators
776  virtual child_iterator child_begin();
777  virtual child_iterator child_end();
778
779  virtual void EmitImpl(llvm::Serializer& S) const;
780  static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
781};
782
783/// IndirectGotoStmt - This represents an indirect goto.
784///
785class IndirectGotoStmt : public Stmt {
786  Stmt *Target;
787  // FIXME: Add location information (e.g. SourceLocation objects).
788  //        When doing so, update the serialization routines.
789public:
790  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass),
791                                   Target((Stmt*)target){}
792
793  Expr *getTarget();
794  const Expr *getTarget() const;
795
796  virtual SourceRange getSourceRange() const { return SourceRange(); }
797
798  static bool classof(const Stmt *T) {
799    return T->getStmtClass() == IndirectGotoStmtClass;
800  }
801  static bool classof(const IndirectGotoStmt *) { return true; }
802
803  // Iterators
804  virtual child_iterator child_begin();
805  virtual child_iterator child_end();
806
807  virtual void EmitImpl(llvm::Serializer& S) const;
808  static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
809};
810
811
812/// ContinueStmt - This represents a continue.
813///
814class ContinueStmt : public Stmt {
815  SourceLocation ContinueLoc;
816public:
817  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
818
819  virtual SourceRange getSourceRange() const {
820    return SourceRange(ContinueLoc);
821  }
822  static bool classof(const Stmt *T) {
823    return T->getStmtClass() == ContinueStmtClass;
824  }
825  static bool classof(const ContinueStmt *) { return true; }
826
827  // Iterators
828  virtual child_iterator child_begin();
829  virtual child_iterator child_end();
830
831  virtual void EmitImpl(llvm::Serializer& S) const;
832  static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
833};
834
835/// BreakStmt - This represents a break.
836///
837class BreakStmt : public Stmt {
838  SourceLocation BreakLoc;
839public:
840  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
841
842  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
843
844  static bool classof(const Stmt *T) {
845    return T->getStmtClass() == BreakStmtClass;
846  }
847  static bool classof(const BreakStmt *) { return true; }
848
849  // Iterators
850  virtual child_iterator child_begin();
851  virtual child_iterator child_end();
852
853  virtual void EmitImpl(llvm::Serializer& S) const;
854  static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
855};
856
857
858/// ReturnStmt - This represents a return, optionally of an expression:
859///   return;
860///   return 4;
861///
862/// Note that GCC allows return with no argument in a function declared to
863/// return a value, and it allows returning a value in functions declared to
864/// return void.  We explicitly model this in the AST, which means you can't
865/// depend on the return type of the function and the presence of an argument.
866///
867class ReturnStmt : public Stmt {
868  Stmt *RetExpr;
869  SourceLocation RetLoc;
870public:
871  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
872    RetExpr((Stmt*) E), RetLoc(RL) {}
873
874  const Expr *getRetValue() const;
875  Expr *getRetValue();
876
877  virtual SourceRange getSourceRange() const;
878
879  static bool classof(const Stmt *T) {
880    return T->getStmtClass() == ReturnStmtClass;
881  }
882  static bool classof(const ReturnStmt *) { return true; }
883
884  // Iterators
885  virtual child_iterator child_begin();
886  virtual child_iterator child_end();
887
888  virtual void EmitImpl(llvm::Serializer& S) const;
889  static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
890};
891
892/// AsmStmt - This represents a GNU inline-assembly statement extension.
893///
894class AsmStmt : public Stmt {
895  SourceLocation AsmLoc, RParenLoc;
896  StringLiteral *AsmStr;
897
898  bool IsSimple;
899  bool IsVolatile;
900
901  unsigned NumOutputs;
902  unsigned NumInputs;
903
904  llvm::SmallVector<std::string, 4> Names;
905  llvm::SmallVector<StringLiteral*, 4> Constraints;
906  llvm::SmallVector<Stmt*, 4> Exprs;
907
908  llvm::SmallVector<StringLiteral*, 4> Clobbers;
909public:
910  AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
911          unsigned numoutputs, unsigned numinputs,
912          std::string *names, StringLiteral **constraints,
913          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
914          StringLiteral **clobbers, SourceLocation rparenloc);
915
916  bool isVolatile() const { return IsVolatile; }
917  bool isSimple() const { return IsSimple; }
918
919  unsigned getNumOutputs() const { return NumOutputs; }
920
921  const std::string &getOutputName(unsigned i) const {
922    return Names[i];
923  }
924
925  const StringLiteral *getOutputConstraint(unsigned i) const {
926    return Constraints[i];
927  }
928
929  StringLiteral *getOutputConstraint(unsigned i)
930    { return Constraints[i]; }
931
932  const Expr *getOutputExpr(unsigned i) const;
933  Expr *getOutputExpr(unsigned i);
934
935  unsigned getNumInputs() const { return NumInputs; }
936
937  const std::string &getInputName(unsigned i) const {
938    return Names[i + NumOutputs];
939  }
940  StringLiteral *getInputConstraint(unsigned i) {
941    return Constraints[i + NumOutputs];
942  }
943  const StringLiteral *getInputConstraint(unsigned i) const {
944    return Constraints[i + NumOutputs];
945  }
946
947  Expr *getInputExpr(unsigned i);
948  const Expr *getInputExpr(unsigned i) const;
949
950  const StringLiteral *getAsmString() const { return AsmStr; }
951  StringLiteral *getAsmString() { return AsmStr; }
952
953  unsigned getNumClobbers() const { return Clobbers.size(); }
954  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
955  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
956
957  virtual SourceRange getSourceRange() const {
958    return SourceRange(AsmLoc, RParenLoc);
959  }
960
961  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
962  static bool classof(const AsmStmt *) { return true; }
963
964  // Input expr iterators.
965
966  typedef ExprIterator inputs_iterator;
967  typedef ConstExprIterator const_inputs_iterator;
968
969  inputs_iterator begin_inputs() {
970    return &Exprs[0] + NumOutputs;
971  }
972
973  inputs_iterator end_inputs() {
974    return  &Exprs[0] + NumOutputs + NumInputs;
975  }
976
977  const_inputs_iterator begin_inputs() const {
978    return &Exprs[0] + NumOutputs;
979  }
980
981  const_inputs_iterator end_inputs() const {
982    return  &Exprs[0] + NumOutputs + NumInputs;}
983
984  // Output expr iterators.
985
986  typedef ExprIterator outputs_iterator;
987  typedef ConstExprIterator const_outputs_iterator;
988
989  outputs_iterator begin_outputs() { return &Exprs[0]; }
990  outputs_iterator end_outputs() { return &Exprs[0] + NumOutputs; }
991
992  const_outputs_iterator begin_outputs() const { return &Exprs[0]; }
993  const_outputs_iterator end_outputs() const { return &Exprs[0] + NumOutputs; }
994
995  // Input name iterator.
996
997  const std::string *begin_output_names() const {
998    return &Names[0];
999  }
1000
1001  const std::string *end_output_names() const {
1002    return &Names[0] + NumOutputs;
1003  }
1004
1005  // Child iterators
1006
1007  virtual child_iterator child_begin();
1008  virtual child_iterator child_end();
1009
1010  virtual void EmitImpl(llvm::Serializer& S) const;
1011  static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1012};
1013
1014/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
1015/// represented as 'for (element 'in' collection-expression)' stmt.
1016///
1017class ObjCForCollectionStmt : public Stmt {
1018  enum { ELEM, COLLECTION, BODY, END_EXPR };
1019  Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
1020  SourceLocation ForLoc;
1021  SourceLocation RParenLoc;
1022public:
1023  ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
1024                        SourceLocation FCL, SourceLocation RPL);
1025
1026  Stmt *getElement() { return SubExprs[ELEM]; }
1027  Expr *getCollection() {
1028    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
1029  }
1030  Stmt *getBody() { return SubExprs[BODY]; }
1031
1032  const Stmt *getElement() const { return SubExprs[ELEM]; }
1033  const Expr *getCollection() const {
1034    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
1035  }
1036  const Stmt *getBody() const { return SubExprs[BODY]; }
1037
1038  SourceLocation getRParenLoc() const { return RParenLoc; }
1039
1040  virtual SourceRange getSourceRange() const {
1041    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
1042  }
1043  static bool classof(const Stmt *T) {
1044    return T->getStmtClass() == ObjCForCollectionStmtClass;
1045  }
1046  static bool classof(const ObjCForCollectionStmt *) { return true; }
1047
1048  // Iterators
1049  virtual child_iterator child_begin();
1050  virtual child_iterator child_end();
1051
1052  virtual void EmitImpl(llvm::Serializer& S) const;
1053  static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1054};
1055
1056/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
1057class ObjCAtCatchStmt : public Stmt {
1058private:
1059  enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR };
1060  Stmt *SubExprs[END_EXPR];
1061  SourceLocation AtCatchLoc, RParenLoc;
1062
1063  // Used by deserialization.
1064  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc)
1065  : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {}
1066
1067public:
1068  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
1069                  DeclStmt *catchVarStmtDecl,
1070                  Stmt *atCatchStmt, Stmt *atCatchList);
1071
1072  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
1073  Stmt *getCatchBody() { return SubExprs[BODY]; }
1074
1075  const ObjCAtCatchStmt *getNextCatchStmt() const {
1076    return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1077  }
1078  ObjCAtCatchStmt *getNextCatchStmt() {
1079    return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1080  }
1081
1082  const DeclStmt *getCatchParamStmt() const {
1083    return static_cast<const DeclStmt*>(SubExprs[SELECTOR]); }
1084  DeclStmt *getCatchParamStmt() {
1085    return static_cast<DeclStmt*>(SubExprs[SELECTOR]);
1086  }
1087
1088  SourceLocation getRParenLoc() const { return RParenLoc; }
1089
1090  virtual SourceRange getSourceRange() const {
1091    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
1092  }
1093
1094  bool hasEllipsis() const { return getCatchParamStmt() == 0; }
1095
1096  static bool classof(const Stmt *T) {
1097    return T->getStmtClass() == ObjCAtCatchStmtClass;
1098  }
1099  static bool classof(const ObjCAtCatchStmt *) { return true; }
1100
1101  virtual child_iterator child_begin();
1102  virtual child_iterator child_end();
1103
1104  virtual void EmitImpl(llvm::Serializer& S) const;
1105  static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1106};
1107
1108/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
1109class ObjCAtFinallyStmt : public Stmt {
1110  Stmt *AtFinallyStmt;
1111  SourceLocation AtFinallyLoc;
1112public:
1113  ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
1114  : Stmt(ObjCAtFinallyStmtClass),
1115    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
1116
1117  const Stmt *getFinallyBody () const { return AtFinallyStmt; }
1118  Stmt *getFinallyBody () { return AtFinallyStmt; }
1119
1120  virtual SourceRange getSourceRange() const {
1121    return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
1122  }
1123
1124  static bool classof(const Stmt *T) {
1125    return T->getStmtClass() == ObjCAtFinallyStmtClass;
1126  }
1127  static bool classof(const ObjCAtFinallyStmt *) { return true; }
1128
1129  virtual child_iterator child_begin();
1130  virtual child_iterator child_end();
1131
1132  virtual void EmitImpl(llvm::Serializer& S) const;
1133  static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1134};
1135
1136/// ObjCAtTryStmt - This represent objective-c's over-all
1137/// @try ... @catch ... @finally statement.
1138class ObjCAtTryStmt : public Stmt {
1139private:
1140  enum { TRY, CATCH, FINALLY, END_EXPR };
1141  Stmt* SubStmts[END_EXPR];
1142
1143  SourceLocation AtTryLoc;
1144public:
1145  ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
1146                Stmt *atCatchStmt,
1147                Stmt *atFinallyStmt)
1148  : Stmt(ObjCAtTryStmtClass) {
1149      SubStmts[TRY] = atTryStmt;
1150      SubStmts[CATCH] = atCatchStmt;
1151      SubStmts[FINALLY] = atFinallyStmt;
1152      AtTryLoc = atTryLoc;
1153    }
1154
1155  const Stmt *getTryBody() const { return SubStmts[TRY]; }
1156  Stmt *getTryBody() { return SubStmts[TRY]; }
1157  const ObjCAtCatchStmt *getCatchStmts() const {
1158    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1159  }
1160  ObjCAtCatchStmt *getCatchStmts() {
1161    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1162  }
1163  const ObjCAtFinallyStmt *getFinallyStmt() const {
1164    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1165  }
1166  ObjCAtFinallyStmt *getFinallyStmt() {
1167    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1168  }
1169  virtual SourceRange getSourceRange() const {
1170    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
1171  }
1172
1173  static bool classof(const Stmt *T) {
1174    return T->getStmtClass() == ObjCAtTryStmtClass;
1175  }
1176  static bool classof(const ObjCAtTryStmt *) { return true; }
1177
1178  virtual child_iterator child_begin();
1179  virtual child_iterator child_end();
1180
1181  virtual void EmitImpl(llvm::Serializer& S) const;
1182  static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1183};
1184
1185/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
1186/// Example: @synchronized (sem) {
1187///             do-something;
1188///          }
1189///
1190class ObjCAtSynchronizedStmt : public Stmt {
1191private:
1192  enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
1193  Stmt* SubStmts[END_EXPR];
1194  SourceLocation AtSynchronizedLoc;
1195
1196public:
1197  ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
1198                         Stmt *synchBody)
1199  : Stmt(ObjCAtSynchronizedStmtClass) {
1200      SubStmts[SYNC_EXPR] = synchExpr;
1201      SubStmts[SYNC_BODY] = synchBody;
1202      AtSynchronizedLoc = atSynchronizedLoc;
1203    }
1204
1205  const CompoundStmt *getSynchBody() const {
1206    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1207  }
1208  CompoundStmt *getSynchBody() {
1209    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1210  }
1211
1212  const Expr *getSynchExpr() const {
1213    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1214  }
1215  Expr *getSynchExpr() {
1216    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1217  }
1218
1219  virtual SourceRange getSourceRange() const {
1220    return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
1221  }
1222
1223  static bool classof(const Stmt *T) {
1224    return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
1225  }
1226  static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
1227
1228  virtual child_iterator child_begin();
1229  virtual child_iterator child_end();
1230
1231  virtual void EmitImpl(llvm::Serializer& S) const;
1232  static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D,
1233                                            ASTContext& C);
1234};
1235
1236/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
1237class ObjCAtThrowStmt : public Stmt {
1238  Stmt *Throw;
1239  SourceLocation AtThrowLoc;
1240public:
1241  ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
1242  : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
1243    AtThrowLoc = atThrowLoc;
1244  }
1245
1246  const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
1247  Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
1248
1249  virtual SourceRange getSourceRange() const {
1250    if (Throw)
1251      return SourceRange(AtThrowLoc, Throw->getLocEnd());
1252    else
1253      return SourceRange(AtThrowLoc);
1254  }
1255
1256  static bool classof(const Stmt *T) {
1257    return T->getStmtClass() == ObjCAtThrowStmtClass;
1258  }
1259  static bool classof(const ObjCAtThrowStmt *) { return true; }
1260
1261  virtual child_iterator child_begin();
1262  virtual child_iterator child_end();
1263
1264  virtual void EmitImpl(llvm::Serializer& S) const;
1265  static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1266};
1267
1268/// CXXCatchStmt - This represents a C++ catch block.
1269class CXXCatchStmt : public Stmt {
1270  SourceLocation CatchLoc;
1271  /// The exception-declaration of the type.
1272  Decl *ExceptionDecl;
1273  /// The handler block.
1274  Stmt *HandlerBlock;
1275
1276public:
1277  CXXCatchStmt(SourceLocation catchLoc, Decl *exDecl, Stmt *handlerBlock)
1278  : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
1279    HandlerBlock(handlerBlock) {}
1280
1281  virtual void Destroy(ASTContext& Ctx);
1282
1283  virtual SourceRange getSourceRange() const {
1284    return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
1285  }
1286
1287  Decl *getExceptionDecl() { return ExceptionDecl; }
1288  QualType getCaughtType();
1289  Stmt *getHandlerBlock() { return HandlerBlock; }
1290
1291  static bool classof(const Stmt *T) {
1292    return T->getStmtClass() == CXXCatchStmtClass;
1293  }
1294  static bool classof(const CXXCatchStmt *) { return true; }
1295
1296  virtual child_iterator child_begin();
1297  virtual child_iterator child_end();
1298
1299  virtual void EmitImpl(llvm::Serializer& S) const;
1300  static CXXCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1301};
1302
1303/// CXXTryStmt - A C++ try block, including all handlers.
1304class CXXTryStmt : public Stmt {
1305  SourceLocation TryLoc;
1306  // First place is the guarded CompoundStatement. Subsequent are the handlers.
1307  // More than three handlers should be rare.
1308  llvm::SmallVector<Stmt*, 4> Stmts;
1309
1310public:
1311  CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
1312             Stmt **handlers, unsigned numHandlers);
1313
1314  virtual SourceRange getSourceRange() const {
1315    return SourceRange(TryLoc, Stmts.back()->getLocEnd());
1316  }
1317
1318  CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); }
1319  const CompoundStmt *getTryBlock() const {
1320    return llvm::cast<CompoundStmt>(Stmts[0]);
1321  }
1322
1323  unsigned getNumHandlers() const { return Stmts.size() - 1; }
1324  CXXCatchStmt *getHandler(unsigned i) {
1325    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
1326  }
1327  const CXXCatchStmt *getHandler(unsigned i) const {
1328    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
1329  }
1330
1331  static bool classof(const Stmt *T) {
1332    return T->getStmtClass() == CXXTryStmtClass;
1333  }
1334  static bool classof(const CXXTryStmt *) { return true; }
1335
1336  virtual child_iterator child_begin();
1337  virtual child_iterator child_end();
1338
1339  virtual void EmitImpl(llvm::Serializer& S) const;
1340  static CXXTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1341};
1342
1343}  // end namespace clang
1344
1345#endif
1346