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