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