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