Stmt.h revision 458cd9c8a79b25b87dcea43c9d97a4c59f194799
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>
27using llvm::dyn_cast_or_null;
28
29namespace clang {
30  class ASTContext;
31  class Expr;
32  class Decl;
33  class ParmVarDecl;
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  Stmt *getSubStmt() { return v_getSubStmt(); }
425
426  virtual SourceRange getSourceRange() const { return SourceRange(); }
427
428  static bool classof(const Stmt *T) {
429    return T->getStmtClass() == CaseStmtClass ||
430    T->getStmtClass() == DefaultStmtClass;
431  }
432  static bool classof(const SwitchCase *) { return true; }
433protected:
434  virtual Stmt* v_getSubStmt() = 0;
435};
436
437class CaseStmt : public SwitchCase {
438  enum { SUBSTMT, LHS, RHS, END_EXPR };
439  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
440                             // GNU "case 1 ... 4" extension
441  SourceLocation CaseLoc;
442  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
443public:
444  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc)
445    : SwitchCase(CaseStmtClass) {
446    SubExprs[SUBSTMT] = 0;
447    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
448    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
449    CaseLoc = caseLoc;
450  }
451
452  SourceLocation getCaseLoc() const { return CaseLoc; }
453
454  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
455  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
456  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
457  const Expr *getLHS() const {
458    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
459  }
460  const Expr *getRHS() const {
461    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
462  }
463  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
464
465  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
466  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
467  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
468
469
470  virtual SourceRange getSourceRange() const {
471    // Handle deeply nested case statements with iteration instead of recursion.
472    const CaseStmt *CS = this;
473    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
474      CS = CS2;
475
476    return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
477  }
478  static bool classof(const Stmt *T) {
479    return T->getStmtClass() == CaseStmtClass;
480  }
481  static bool classof(const CaseStmt *) { return true; }
482
483  // Iterators
484  virtual child_iterator child_begin();
485  virtual child_iterator child_end();
486
487  virtual void EmitImpl(llvm::Serializer& S) const;
488  static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
489};
490
491class DefaultStmt : public SwitchCase {
492  Stmt* SubStmt;
493  SourceLocation DefaultLoc;
494  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
495public:
496  DefaultStmt(SourceLocation DL, Stmt *substmt) :
497    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
498
499  Stmt *getSubStmt() { return SubStmt; }
500  const Stmt *getSubStmt() const { return SubStmt; }
501
502  SourceLocation getDefaultLoc() const { return DefaultLoc; }
503
504  virtual SourceRange getSourceRange() const {
505    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
506  }
507  static bool classof(const Stmt *T) {
508    return T->getStmtClass() == DefaultStmtClass;
509  }
510  static bool classof(const DefaultStmt *) { return true; }
511
512  // Iterators
513  virtual child_iterator child_begin();
514  virtual child_iterator child_end();
515
516  virtual void EmitImpl(llvm::Serializer& S) const;
517  static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
518};
519
520class LabelStmt : public Stmt {
521  IdentifierInfo *Label;
522  Stmt *SubStmt;
523  SourceLocation IdentLoc;
524public:
525  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
526    : Stmt(LabelStmtClass), Label(label),
527      SubStmt(substmt), IdentLoc(IL) {}
528
529  SourceLocation getIdentLoc() const { return IdentLoc; }
530  IdentifierInfo *getID() const { return Label; }
531  const char *getName() const;
532  Stmt *getSubStmt() { return SubStmt; }
533  const Stmt *getSubStmt() const { return SubStmt; }
534
535  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
536  void setSubStmt(Stmt *SS) { SubStmt = SS; }
537
538  virtual SourceRange getSourceRange() const {
539    return SourceRange(IdentLoc, SubStmt->getLocEnd());
540  }
541  static bool classof(const Stmt *T) {
542    return T->getStmtClass() == LabelStmtClass;
543  }
544  static bool classof(const LabelStmt *) { return true; }
545
546  // Iterators
547  virtual child_iterator child_begin();
548  virtual child_iterator child_end();
549
550  virtual void EmitImpl(llvm::Serializer& S) const;
551  static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
552};
553
554
555/// IfStmt - This represents an if/then/else.
556///
557class IfStmt : public Stmt {
558  enum { COND, THEN, ELSE, END_EXPR };
559  Stmt* SubExprs[END_EXPR];
560  SourceLocation IfLoc;
561public:
562  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
563    : Stmt(IfStmtClass)  {
564    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
565    SubExprs[THEN] = then;
566    SubExprs[ELSE] = elsev;
567    IfLoc = IL;
568  }
569
570  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
571  const Stmt *getThen() const { return SubExprs[THEN]; }
572  const Stmt *getElse() const { return SubExprs[ELSE]; }
573
574  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
575  Stmt *getThen() { return SubExprs[THEN]; }
576  Stmt *getElse() { return SubExprs[ELSE]; }
577
578  virtual SourceRange getSourceRange() const {
579    if (SubExprs[ELSE])
580      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
581    else
582      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
583  }
584
585  static bool classof(const Stmt *T) {
586    return T->getStmtClass() == IfStmtClass;
587  }
588  static bool classof(const IfStmt *) { return true; }
589
590  // Iterators
591  virtual child_iterator child_begin();
592  virtual child_iterator child_end();
593
594  virtual void EmitImpl(llvm::Serializer& S) const;
595  static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
596};
597
598/// SwitchStmt - This represents a 'switch' stmt.
599///
600class SwitchStmt : public Stmt {
601  enum { COND, BODY, END_EXPR };
602  Stmt* SubExprs[END_EXPR];
603  // This points to a linked list of case and default statements.
604  SwitchCase *FirstCase;
605  SourceLocation SwitchLoc;
606public:
607  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
608      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
609      SubExprs[BODY] = NULL;
610    }
611
612  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
613  const Stmt *getBody() const { return SubExprs[BODY]; }
614  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
615
616  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
617  Stmt *getBody() { return SubExprs[BODY]; }
618  SwitchCase *getSwitchCaseList() { return FirstCase; }
619
620  void setBody(Stmt *S, SourceLocation SL) {
621    SubExprs[BODY] = S;
622    SwitchLoc = SL;
623  }
624  void addSwitchCase(SwitchCase *SC) {
625    if (FirstCase)
626      SC->setNextSwitchCase(FirstCase);
627
628    FirstCase = SC;
629  }
630  virtual SourceRange getSourceRange() const {
631    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
632  }
633  static bool classof(const Stmt *T) {
634    return T->getStmtClass() == SwitchStmtClass;
635  }
636  static bool classof(const SwitchStmt *) { return true; }
637
638  // Iterators
639  virtual child_iterator child_begin();
640  virtual child_iterator child_end();
641
642  virtual void EmitImpl(llvm::Serializer& S) const;
643  static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
644};
645
646
647/// WhileStmt - This represents a 'while' stmt.
648///
649class WhileStmt : public Stmt {
650  enum { COND, BODY, END_EXPR };
651  Stmt* SubExprs[END_EXPR];
652  SourceLocation WhileLoc;
653public:
654  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
655    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
656    SubExprs[BODY] = body;
657    WhileLoc = WL;
658  }
659
660  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
661  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
662  Stmt *getBody() { return SubExprs[BODY]; }
663  const Stmt *getBody() const { return SubExprs[BODY]; }
664
665  virtual SourceRange getSourceRange() const {
666    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
667  }
668  static bool classof(const Stmt *T) {
669    return T->getStmtClass() == WhileStmtClass;
670  }
671  static bool classof(const WhileStmt *) { return true; }
672
673  // Iterators
674  virtual child_iterator child_begin();
675  virtual child_iterator child_end();
676
677  virtual void EmitImpl(llvm::Serializer& S) const;
678  static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
679};
680
681/// DoStmt - This represents a 'do/while' stmt.
682///
683class DoStmt : public Stmt {
684  enum { COND, BODY, END_EXPR };
685  Stmt* SubExprs[END_EXPR];
686  SourceLocation DoLoc;
687public:
688  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
689    : Stmt(DoStmtClass), DoLoc(DL) {
690    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
691    SubExprs[BODY] = body;
692    DoLoc = DL;
693  }
694
695  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
696  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
697  Stmt *getBody() { return SubExprs[BODY]; }
698  const Stmt *getBody() const { return SubExprs[BODY]; }
699
700  virtual SourceRange getSourceRange() const {
701    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
702  }
703  static bool classof(const Stmt *T) {
704    return T->getStmtClass() == DoStmtClass;
705  }
706  static bool classof(const DoStmt *) { return true; }
707
708  // Iterators
709  virtual child_iterator child_begin();
710  virtual child_iterator child_end();
711
712  virtual void EmitImpl(llvm::Serializer& S) const;
713  static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
714};
715
716
717/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
718/// the init/cond/inc parts of the ForStmt will be null if they were not
719/// specified in the source.
720///
721class ForStmt : public Stmt {
722  enum { INIT, COND, INC, BODY, END_EXPR };
723  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
724  SourceLocation ForLoc;
725public:
726  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
727    : Stmt(ForStmtClass) {
728    SubExprs[INIT] = Init;
729    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
730    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
731    SubExprs[BODY] = Body;
732    ForLoc = FL;
733  }
734
735  Stmt *getInit() { return SubExprs[INIT]; }
736  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
737  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
738  Stmt *getBody() { return SubExprs[BODY]; }
739
740  const Stmt *getInit() const { return SubExprs[INIT]; }
741  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
742  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
743  const Stmt *getBody() const { return SubExprs[BODY]; }
744
745  virtual SourceRange getSourceRange() const {
746    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
747  }
748  static bool classof(const Stmt *T) {
749    return T->getStmtClass() == ForStmtClass;
750  }
751  static bool classof(const ForStmt *) { return true; }
752
753  // Iterators
754  virtual child_iterator child_begin();
755  virtual child_iterator child_end();
756
757  virtual void EmitImpl(llvm::Serializer& S) const;
758  static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
759};
760
761/// GotoStmt - This represents a direct goto.
762///
763class GotoStmt : public Stmt {
764  LabelStmt *Label;
765  SourceLocation GotoLoc;
766  SourceLocation LabelLoc;
767public:
768  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
769    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
770
771  LabelStmt *getLabel() const { return Label; }
772
773  virtual SourceRange getSourceRange() const {
774    return SourceRange(GotoLoc, LabelLoc);
775  }
776  static bool classof(const Stmt *T) {
777    return T->getStmtClass() == GotoStmtClass;
778  }
779  static bool classof(const GotoStmt *) { return true; }
780
781  // Iterators
782  virtual child_iterator child_begin();
783  virtual child_iterator child_end();
784
785  virtual void EmitImpl(llvm::Serializer& S) const;
786  static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
787};
788
789/// IndirectGotoStmt - This represents an indirect goto.
790///
791class IndirectGotoStmt : public Stmt {
792  Stmt *Target;
793  // FIXME: Add location information (e.g. SourceLocation objects).
794  //        When doing so, update the serialization routines.
795public:
796  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass),
797                                   Target((Stmt*)target){}
798
799  Expr *getTarget();
800  const Expr *getTarget() const;
801
802  virtual SourceRange getSourceRange() const { return SourceRange(); }
803
804  static bool classof(const Stmt *T) {
805    return T->getStmtClass() == IndirectGotoStmtClass;
806  }
807  static bool classof(const IndirectGotoStmt *) { return true; }
808
809  // Iterators
810  virtual child_iterator child_begin();
811  virtual child_iterator child_end();
812
813  virtual void EmitImpl(llvm::Serializer& S) const;
814  static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
815};
816
817
818/// ContinueStmt - This represents a continue.
819///
820class ContinueStmt : public Stmt {
821  SourceLocation ContinueLoc;
822public:
823  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
824
825  virtual SourceRange getSourceRange() const {
826    return SourceRange(ContinueLoc);
827  }
828  static bool classof(const Stmt *T) {
829    return T->getStmtClass() == ContinueStmtClass;
830  }
831  static bool classof(const ContinueStmt *) { return true; }
832
833  // Iterators
834  virtual child_iterator child_begin();
835  virtual child_iterator child_end();
836
837  virtual void EmitImpl(llvm::Serializer& S) const;
838  static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
839};
840
841/// BreakStmt - This represents a break.
842///
843class BreakStmt : public Stmt {
844  SourceLocation BreakLoc;
845public:
846  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
847
848  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
849
850  static bool classof(const Stmt *T) {
851    return T->getStmtClass() == BreakStmtClass;
852  }
853  static bool classof(const BreakStmt *) { return true; }
854
855  // Iterators
856  virtual child_iterator child_begin();
857  virtual child_iterator child_end();
858
859  virtual void EmitImpl(llvm::Serializer& S) const;
860  static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
861};
862
863
864/// ReturnStmt - This represents a return, optionally of an expression:
865///   return;
866///   return 4;
867///
868/// Note that GCC allows return with no argument in a function declared to
869/// return a value, and it allows returning a value in functions declared to
870/// return void.  We explicitly model this in the AST, which means you can't
871/// depend on the return type of the function and the presence of an argument.
872///
873class ReturnStmt : public Stmt {
874  Stmt *RetExpr;
875  SourceLocation RetLoc;
876public:
877  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
878    RetExpr((Stmt*) E), RetLoc(RL) {}
879
880  const Expr *getRetValue() const;
881  Expr *getRetValue();
882
883  virtual SourceRange getSourceRange() const;
884
885  static bool classof(const Stmt *T) {
886    return T->getStmtClass() == ReturnStmtClass;
887  }
888  static bool classof(const ReturnStmt *) { return true; }
889
890  // Iterators
891  virtual child_iterator child_begin();
892  virtual child_iterator child_end();
893
894  virtual void EmitImpl(llvm::Serializer& S) const;
895  static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
896};
897
898/// AsmStmt - This represents a GNU inline-assembly statement extension.
899///
900class AsmStmt : public Stmt {
901  SourceLocation AsmLoc, RParenLoc;
902  StringLiteral *AsmStr;
903
904  bool IsSimple;
905  bool IsVolatile;
906
907  unsigned NumOutputs;
908  unsigned NumInputs;
909
910  llvm::SmallVector<std::string, 4> Names;
911  llvm::SmallVector<StringLiteral*, 4> Constraints;
912  llvm::SmallVector<Stmt*, 4> Exprs;
913
914  llvm::SmallVector<StringLiteral*, 4> Clobbers;
915public:
916  AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
917          unsigned numoutputs, unsigned numinputs,
918          std::string *names, StringLiteral **constraints,
919          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
920          StringLiteral **clobbers, SourceLocation rparenloc);
921
922  bool isVolatile() const { return IsVolatile; }
923  bool isSimple() const { return IsSimple; }
924
925  //===--- Asm String Analysis ---===//
926
927  const StringLiteral *getAsmString() const { return AsmStr; }
928  StringLiteral *getAsmString() { return AsmStr; }
929
930  /// AsmStringPiece - this is part of a decomposed asm string specification
931  /// (for use with the AnalyzeAsmString function below).  An asm string is
932  /// considered to be a concatenation of these parts.
933  class AsmStringPiece {
934  public:
935    enum Kind {
936      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
937      Operand  // Operand reference, with optional modifier %c4.
938    };
939  private:
940    Kind MyKind;
941    std::string Str;
942    unsigned OperandNo;
943  public:
944    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
945    AsmStringPiece(unsigned OpNo, char Modifier)
946      : MyKind(Operand), Str(), OperandNo(OpNo) {
947      Str += Modifier;
948    }
949
950    bool isString() const { return MyKind == String; }
951    bool isOperand() const { return MyKind == Operand; }
952
953    const std::string &getString() const {
954      assert(isString());
955      return Str;
956    }
957
958    unsigned getOperandNo() const {
959      assert(isOperand());
960      return OperandNo;
961    }
962
963    /// getModifier - Get the modifier for this operand, if present.  This
964    /// returns '\0' if there was no modifier.
965    char getModifier() const {
966      assert(isOperand());
967      return Str[0];
968    }
969  };
970
971  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
972  /// it into pieces.  If the asm string is erroneous, emit errors and return
973  /// true, otherwise return false.  This handles canonicalization and
974  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
975  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
976  bool AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
977                        ASTContext &C) const;
978
979
980  //===--- Output operands ---===//
981
982  unsigned getNumOutputs() const { return NumOutputs; }
983
984  const std::string &getOutputName(unsigned i) const {
985    return Names[i];
986  }
987
988  /// getOutputConstraint - Return the constraint string for the specified
989  /// output operand.  All output constraints are known to be non-empty (either
990  /// '=' or '+').
991  std::string getOutputConstraint(unsigned i) const;
992
993  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
994    return Constraints[i];
995  }
996  StringLiteral *getOutputConstraintLiteral(unsigned i) {
997    return Constraints[i];
998  }
999
1000
1001  Expr *getOutputExpr(unsigned i);
1002
1003  const Expr *getOutputExpr(unsigned i) const {
1004    return const_cast<AsmStmt*>(this)->getOutputExpr(i);
1005  }
1006
1007  /// isOutputPlusConstraint - Return true if the specified output constraint
1008  /// is a "+" constraint (which is both an input and an output) or false if it
1009  /// is an "=" constraint (just an output).
1010  bool isOutputPlusConstraint(unsigned i) const {
1011    return getOutputConstraint(i)[0] == '+';
1012  }
1013
1014  //===--- Input operands ---===//
1015
1016  unsigned getNumInputs() const { return NumInputs; }
1017
1018  const std::string &getInputName(unsigned i) const {
1019    return Names[i + NumOutputs];
1020  }
1021
1022  /// getInputConstraint - Return the specified input constraint.  Unlike output
1023  /// constraints, these can be empty.
1024  std::string getInputConstraint(unsigned i) const;
1025
1026  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
1027    return Constraints[i + NumOutputs];
1028  }
1029  StringLiteral *getInputConstraintLiteral(unsigned i) {
1030    return Constraints[i + NumOutputs];
1031  }
1032
1033
1034  Expr *getInputExpr(unsigned i);
1035
1036  const Expr *getInputExpr(unsigned i) const {
1037    return const_cast<AsmStmt*>(this)->getInputExpr(i);
1038  }
1039
1040  //===--- Other ---===//
1041
1042  /// getNamedOperand - Given a symbolic operand reference like %[foo],
1043  /// translate this into a numeric value needed to reference the same operand.
1044  /// This returns -1 if the operand name is invalid.
1045  int getNamedOperand(const std::string &SymbolicName) const;
1046
1047
1048
1049  unsigned getNumClobbers() const { return Clobbers.size(); }
1050  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
1051  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
1052
1053  virtual SourceRange getSourceRange() const {
1054    return SourceRange(AsmLoc, RParenLoc);
1055  }
1056
1057  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
1058  static bool classof(const AsmStmt *) { return true; }
1059
1060  // Input expr iterators.
1061
1062  typedef ExprIterator inputs_iterator;
1063  typedef ConstExprIterator const_inputs_iterator;
1064
1065  inputs_iterator begin_inputs() {
1066    return &Exprs[0] + NumOutputs;
1067  }
1068
1069  inputs_iterator end_inputs() {
1070    return  &Exprs[0] + NumOutputs + NumInputs;
1071  }
1072
1073  const_inputs_iterator begin_inputs() const {
1074    return &Exprs[0] + NumOutputs;
1075  }
1076
1077  const_inputs_iterator end_inputs() const {
1078    return  &Exprs[0] + NumOutputs + NumInputs;}
1079
1080  // Output expr iterators.
1081
1082  typedef ExprIterator outputs_iterator;
1083  typedef ConstExprIterator const_outputs_iterator;
1084
1085  outputs_iterator begin_outputs() { return &Exprs[0]; }
1086  outputs_iterator end_outputs() { return &Exprs[0] + NumOutputs; }
1087
1088  const_outputs_iterator begin_outputs() const { return &Exprs[0]; }
1089  const_outputs_iterator end_outputs() const { return &Exprs[0] + NumOutputs; }
1090
1091  // Input name iterator.
1092
1093  const std::string *begin_output_names() const {
1094    return &Names[0];
1095  }
1096
1097  const std::string *end_output_names() const {
1098    return &Names[0] + NumOutputs;
1099  }
1100
1101  // Child iterators
1102
1103  virtual child_iterator child_begin();
1104  virtual child_iterator child_end();
1105
1106  virtual void EmitImpl(llvm::Serializer& S) const;
1107  static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1108};
1109
1110/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
1111/// represented as 'for (element 'in' collection-expression)' stmt.
1112///
1113class ObjCForCollectionStmt : public Stmt {
1114  enum { ELEM, COLLECTION, BODY, END_EXPR };
1115  Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
1116  SourceLocation ForLoc;
1117  SourceLocation RParenLoc;
1118public:
1119  ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
1120                        SourceLocation FCL, SourceLocation RPL);
1121
1122  Stmt *getElement() { return SubExprs[ELEM]; }
1123  Expr *getCollection() {
1124    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
1125  }
1126  Stmt *getBody() { return SubExprs[BODY]; }
1127
1128  const Stmt *getElement() const { return SubExprs[ELEM]; }
1129  const Expr *getCollection() const {
1130    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
1131  }
1132  const Stmt *getBody() const { return SubExprs[BODY]; }
1133
1134  SourceLocation getRParenLoc() const { return RParenLoc; }
1135
1136  virtual SourceRange getSourceRange() const {
1137    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
1138  }
1139  static bool classof(const Stmt *T) {
1140    return T->getStmtClass() == ObjCForCollectionStmtClass;
1141  }
1142  static bool classof(const ObjCForCollectionStmt *) { return true; }
1143
1144  // Iterators
1145  virtual child_iterator child_begin();
1146  virtual child_iterator child_end();
1147
1148  virtual void EmitImpl(llvm::Serializer& S) const;
1149  static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1150};
1151
1152/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
1153class ObjCAtCatchStmt : public Stmt {
1154private:
1155  enum { BODY, NEXT_CATCH, END_EXPR };
1156  ParmVarDecl *ExceptionDecl;
1157  Stmt *SubExprs[END_EXPR];
1158  SourceLocation AtCatchLoc, RParenLoc;
1159
1160  // Used by deserialization.
1161  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc)
1162  : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {}
1163
1164public:
1165  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
1166                  ParmVarDecl *catchVarDecl,
1167                  Stmt *atCatchStmt, Stmt *atCatchList);
1168
1169  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
1170  Stmt *getCatchBody() { return SubExprs[BODY]; }
1171
1172  const ObjCAtCatchStmt *getNextCatchStmt() const {
1173    return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1174  }
1175  ObjCAtCatchStmt *getNextCatchStmt() {
1176    return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1177  }
1178
1179  const ParmVarDecl *getCatchParamDecl() const {
1180    return ExceptionDecl;
1181  }
1182  ParmVarDecl *getCatchParamDecl() {
1183    return ExceptionDecl;
1184  }
1185
1186  SourceLocation getRParenLoc() const { return RParenLoc; }
1187
1188  virtual SourceRange getSourceRange() const {
1189    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
1190  }
1191
1192  bool hasEllipsis() const { return getCatchParamDecl() == 0; }
1193
1194  static bool classof(const Stmt *T) {
1195    return T->getStmtClass() == ObjCAtCatchStmtClass;
1196  }
1197  static bool classof(const ObjCAtCatchStmt *) { return true; }
1198
1199  virtual child_iterator child_begin();
1200  virtual child_iterator child_end();
1201
1202  virtual void EmitImpl(llvm::Serializer& S) const;
1203  static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1204};
1205
1206/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
1207class ObjCAtFinallyStmt : public Stmt {
1208  Stmt *AtFinallyStmt;
1209  SourceLocation AtFinallyLoc;
1210public:
1211  ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
1212  : Stmt(ObjCAtFinallyStmtClass),
1213    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
1214
1215  const Stmt *getFinallyBody () const { return AtFinallyStmt; }
1216  Stmt *getFinallyBody () { return AtFinallyStmt; }
1217
1218  virtual SourceRange getSourceRange() const {
1219    return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
1220  }
1221
1222  static bool classof(const Stmt *T) {
1223    return T->getStmtClass() == ObjCAtFinallyStmtClass;
1224  }
1225  static bool classof(const ObjCAtFinallyStmt *) { return true; }
1226
1227  virtual child_iterator child_begin();
1228  virtual child_iterator child_end();
1229
1230  virtual void EmitImpl(llvm::Serializer& S) const;
1231  static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1232};
1233
1234/// ObjCAtTryStmt - This represent objective-c's over-all
1235/// @try ... @catch ... @finally statement.
1236class ObjCAtTryStmt : public Stmt {
1237private:
1238  enum { TRY, CATCH, FINALLY, END_EXPR };
1239  Stmt* SubStmts[END_EXPR];
1240
1241  SourceLocation AtTryLoc;
1242public:
1243  ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
1244                Stmt *atCatchStmt,
1245                Stmt *atFinallyStmt)
1246  : Stmt(ObjCAtTryStmtClass) {
1247      SubStmts[TRY] = atTryStmt;
1248      SubStmts[CATCH] = atCatchStmt;
1249      SubStmts[FINALLY] = atFinallyStmt;
1250      AtTryLoc = atTryLoc;
1251    }
1252
1253  const Stmt *getTryBody() const { return SubStmts[TRY]; }
1254  Stmt *getTryBody() { return SubStmts[TRY]; }
1255  const ObjCAtCatchStmt *getCatchStmts() const {
1256    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1257  }
1258  ObjCAtCatchStmt *getCatchStmts() {
1259    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1260  }
1261  const ObjCAtFinallyStmt *getFinallyStmt() const {
1262    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1263  }
1264  ObjCAtFinallyStmt *getFinallyStmt() {
1265    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1266  }
1267  virtual SourceRange getSourceRange() const {
1268    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
1269  }
1270
1271  static bool classof(const Stmt *T) {
1272    return T->getStmtClass() == ObjCAtTryStmtClass;
1273  }
1274  static bool classof(const ObjCAtTryStmt *) { return true; }
1275
1276  virtual child_iterator child_begin();
1277  virtual child_iterator child_end();
1278
1279  virtual void EmitImpl(llvm::Serializer& S) const;
1280  static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1281};
1282
1283/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
1284/// Example: @synchronized (sem) {
1285///             do-something;
1286///          }
1287///
1288class ObjCAtSynchronizedStmt : public Stmt {
1289private:
1290  enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
1291  Stmt* SubStmts[END_EXPR];
1292  SourceLocation AtSynchronizedLoc;
1293
1294public:
1295  ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
1296                         Stmt *synchBody)
1297  : Stmt(ObjCAtSynchronizedStmtClass) {
1298      SubStmts[SYNC_EXPR] = synchExpr;
1299      SubStmts[SYNC_BODY] = synchBody;
1300      AtSynchronizedLoc = atSynchronizedLoc;
1301    }
1302
1303  const CompoundStmt *getSynchBody() const {
1304    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1305  }
1306  CompoundStmt *getSynchBody() {
1307    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1308  }
1309
1310  const Expr *getSynchExpr() const {
1311    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1312  }
1313  Expr *getSynchExpr() {
1314    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1315  }
1316
1317  virtual SourceRange getSourceRange() const {
1318    return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
1319  }
1320
1321  static bool classof(const Stmt *T) {
1322    return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
1323  }
1324  static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
1325
1326  virtual child_iterator child_begin();
1327  virtual child_iterator child_end();
1328
1329  virtual void EmitImpl(llvm::Serializer& S) const;
1330  static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D,
1331                                            ASTContext& C);
1332};
1333
1334/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
1335class ObjCAtThrowStmt : public Stmt {
1336  Stmt *Throw;
1337  SourceLocation AtThrowLoc;
1338public:
1339  ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
1340  : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
1341    AtThrowLoc = atThrowLoc;
1342  }
1343
1344  const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
1345  Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
1346
1347  virtual SourceRange getSourceRange() const {
1348    if (Throw)
1349      return SourceRange(AtThrowLoc, Throw->getLocEnd());
1350    else
1351      return SourceRange(AtThrowLoc);
1352  }
1353
1354  static bool classof(const Stmt *T) {
1355    return T->getStmtClass() == ObjCAtThrowStmtClass;
1356  }
1357  static bool classof(const ObjCAtThrowStmt *) { return true; }
1358
1359  virtual child_iterator child_begin();
1360  virtual child_iterator child_end();
1361
1362  virtual void EmitImpl(llvm::Serializer& S) const;
1363  static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1364};
1365
1366/// CXXCatchStmt - This represents a C++ catch block.
1367class CXXCatchStmt : public Stmt {
1368  SourceLocation CatchLoc;
1369  /// The exception-declaration of the type.
1370  Decl *ExceptionDecl;
1371  /// The handler block.
1372  Stmt *HandlerBlock;
1373
1374public:
1375  CXXCatchStmt(SourceLocation catchLoc, Decl *exDecl, Stmt *handlerBlock)
1376  : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
1377    HandlerBlock(handlerBlock) {}
1378
1379  virtual void Destroy(ASTContext& Ctx);
1380
1381  virtual SourceRange getSourceRange() const {
1382    return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
1383  }
1384
1385  Decl *getExceptionDecl() { return ExceptionDecl; }
1386  QualType getCaughtType();
1387  Stmt *getHandlerBlock() { return HandlerBlock; }
1388
1389  static bool classof(const Stmt *T) {
1390    return T->getStmtClass() == CXXCatchStmtClass;
1391  }
1392  static bool classof(const CXXCatchStmt *) { return true; }
1393
1394  virtual child_iterator child_begin();
1395  virtual child_iterator child_end();
1396
1397  virtual void EmitImpl(llvm::Serializer& S) const;
1398  static CXXCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1399};
1400
1401/// CXXTryStmt - A C++ try block, including all handlers.
1402class CXXTryStmt : public Stmt {
1403  SourceLocation TryLoc;
1404  // First place is the guarded CompoundStatement. Subsequent are the handlers.
1405  // More than three handlers should be rare.
1406  llvm::SmallVector<Stmt*, 4> Stmts;
1407
1408public:
1409  CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
1410             Stmt **handlers, unsigned numHandlers);
1411
1412  virtual SourceRange getSourceRange() const {
1413    return SourceRange(TryLoc, Stmts.back()->getLocEnd());
1414  }
1415
1416  CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); }
1417  const CompoundStmt *getTryBlock() const {
1418    return llvm::cast<CompoundStmt>(Stmts[0]);
1419  }
1420
1421  unsigned getNumHandlers() const { return Stmts.size() - 1; }
1422  CXXCatchStmt *getHandler(unsigned i) {
1423    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
1424  }
1425  const CXXCatchStmt *getHandler(unsigned i) const {
1426    return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
1427  }
1428
1429  static bool classof(const Stmt *T) {
1430    return T->getStmtClass() == CXXTryStmtClass;
1431  }
1432  static bool classof(const CXXTryStmt *) { return true; }
1433
1434  virtual child_iterator child_begin();
1435  virtual child_iterator child_end();
1436
1437  virtual void EmitImpl(llvm::Serializer& S) const;
1438  static CXXTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1439};
1440
1441}  // end namespace clang
1442
1443#endif
1444