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