Stmt.h revision 0965f446e7685dc01fc0b5e718610530eed3cc63
1//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source 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 "clang/Basic/SourceLocation.h"
18#include "clang/AST/StmtIterator.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/iterator"
21#include "llvm/Bitcode/SerializationFwd.h"
22#include <iosfwd>
23
24namespace clang {
25  class Expr;
26  class Decl;
27  class ScopedDecl;
28  class IdentifierInfo;
29  class SourceManager;
30  class SwitchStmt;
31  class PrinterHelper;
32
33/// Stmt - This represents one statement.
34///
35class Stmt {
36public:
37  enum StmtClass {
38#define STMT(N, CLASS, PARENT) CLASS##Class = N,
39#define FIRST_STMT(N) firstStmtConstant = N,
40#define LAST_STMT(N) lastStmtConstant = N,
41#define FIRST_EXPR(N) firstExprConstant = N,
42#define LAST_EXPR(N) lastExprConstant = N
43#include "clang/AST/StmtNodes.def"
44};
45private:
46  const StmtClass sClass;
47public:
48  Stmt(StmtClass SC) : sClass(SC) {
49    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
50  }
51  virtual ~Stmt() {}
52
53  StmtClass getStmtClass() const { return sClass; }
54  const char *getStmtClassName() const;
55
56  /// SourceLocation tokens are not useful in isolation - they are low level
57  /// value objects created/interpreted by SourceManager. We assume AST
58  /// clients will have a pointer to the respective SourceManager.
59  virtual SourceRange getSourceRange() const = 0;
60  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
61  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
62
63  // global temp stats (until we have a per-module visitor)
64  static void addStmtClass(const StmtClass s);
65  static bool CollectingStats(bool enable=false);
66  static void PrintStats();
67
68  /// dump - This does a local dump of the specified AST fragment.  It dumps the
69  /// specified node and a few nodes underneath it, but not the whole subtree.
70  /// This is useful in a debugger.
71  void dump() const;
72  void dump(SourceManager &SM) const;
73
74  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
75  void dumpAll() const;
76  void dumpAll(SourceManager &SM) const;
77
78  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
79  /// back to its original source language syntax.
80  void dumpPretty() const;
81  void printPretty(std::ostream &OS, PrinterHelper* = NULL) const;
82
83  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
84  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
85  void viewAST() const;
86
87  // Implement isa<T> support.
88  static bool classof(const Stmt *) { return true; }
89
90  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
91  ///  contain implicit control-flow in the order their subexpressions
92  ///  are evaluated.  This predicate returns true if this statement has
93  ///  such implicit control-flow.  Such statements are also specially handled
94  ///  within CFGs.
95  bool hasImplicitControlFlow() const;
96
97  /// Child Iterators: All subclasses must implement child_begin and child_end
98  ///  to permit easy iteration over the substatements/subexpessions of an
99  ///  AST node.  This permits easy iteration over all nodes in the AST.
100  typedef StmtIterator       child_iterator;
101  typedef ConstStmtIterator  const_child_iterator;
102
103  virtual child_iterator child_begin() = 0;
104  virtual child_iterator child_end()   = 0;
105
106  const_child_iterator child_begin() const {
107    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
108  }
109
110  const_child_iterator child_end() const {
111    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
112  }
113
114  void Emit(llvm::Serializer& S) const;
115  static Stmt* Materialize(llvm::Deserializer& D);
116
117  virtual void directEmit(llvm::Serializer& S) const {
118    // This method will eventually be a pure-virtual function.
119    assert (false && "Not implemented.");
120  }
121};
122
123/// DeclStmt - Adaptor class for mixing declarations with statements and
124/// expressions. For example, CompoundStmt mixes statements, expressions
125/// and declarations (variables, types). Another example is ForStmt, where
126/// the first statement can be an expression or a declaration.
127///
128class DeclStmt : public Stmt {
129  ScopedDecl *TheDecl;
130public:
131  DeclStmt(ScopedDecl *D) : Stmt(DeclStmtClass), TheDecl(D) {}
132
133  const ScopedDecl *getDecl() const { return TheDecl; }
134  ScopedDecl *getDecl() { return TheDecl; }
135
136  virtual SourceRange getSourceRange() const { return SourceRange(); }
137
138  static bool classof(const Stmt *T) {
139    return T->getStmtClass() == DeclStmtClass;
140  }
141  static bool classof(const DeclStmt *) { return true; }
142
143  // Iterators
144  virtual child_iterator child_begin();
145  virtual child_iterator child_end();
146
147  virtual void directEmit(llvm::Serializer& S) const;
148  static DeclStmt* directMaterialize(llvm::Deserializer& D);
149};
150
151/// NullStmt - This is the null statement ";": C99 6.8.3p3.
152///
153class NullStmt : public Stmt {
154  SourceLocation SemiLoc;
155public:
156  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
157
158  SourceLocation getSemiLoc() const { return SemiLoc; }
159
160  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
161
162  static bool classof(const Stmt *T) {
163    return T->getStmtClass() == NullStmtClass;
164  }
165  static bool classof(const NullStmt *) { return true; }
166
167  // Iterators
168  virtual child_iterator child_begin();
169  virtual child_iterator child_end();
170};
171
172/// CompoundStmt - This represents a group of statements like { stmt stmt }.
173///
174class CompoundStmt : public Stmt {
175  llvm::SmallVector<Stmt*, 16> Body;
176  SourceLocation LBracLoc, RBracLoc;
177public:
178  CompoundStmt(Stmt **StmtStart, unsigned NumStmts,
179               SourceLocation LB, SourceLocation RB)
180    : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts),
181      LBracLoc(LB), RBracLoc(RB) {}
182
183  bool body_empty() const { return Body.empty(); }
184
185  typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
186  body_iterator body_begin() { return Body.begin(); }
187  body_iterator body_end() { return Body.end(); }
188  Stmt *body_back() { return Body.back(); }
189
190  typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
191  const_body_iterator body_begin() const { return Body.begin(); }
192  const_body_iterator body_end() const { return Body.end(); }
193  const Stmt *body_back() const { return Body.back(); }
194
195  typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator;
196  reverse_body_iterator body_rbegin() { return Body.rbegin(); }
197  reverse_body_iterator body_rend() { return Body.rend(); }
198
199  typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator
200    const_reverse_body_iterator;
201  const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); }
202  const_reverse_body_iterator body_rend() const { return Body.rend(); }
203
204  void push_back(Stmt *S) { Body.push_back(S); }
205
206  virtual SourceRange getSourceRange() const {
207    return SourceRange(LBracLoc, RBracLoc);
208  }
209
210  SourceLocation getLBracLoc() const { return LBracLoc; }
211  SourceLocation getRBracLoc() const { return RBracLoc; }
212
213  static bool classof(const Stmt *T) {
214    return T->getStmtClass() == CompoundStmtClass;
215  }
216  static bool classof(const CompoundStmt *) { return true; }
217
218  // Iterators
219  virtual child_iterator child_begin();
220  virtual child_iterator child_end();
221
222  virtual void directEmit(llvm::Serializer& S) const;
223  static CompoundStmt* directMaterialize(llvm::Deserializer& D);
224};
225
226// SwitchCase is the base class for CaseStmt and DefaultStmt,
227class SwitchCase : public Stmt {
228  // A pointer to the following CaseStmt or DefaultStmt class,
229  // used by SwitchStmt.
230  SwitchCase *NextSwitchCase;
231protected:
232  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
233
234public:
235  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
236
237  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
238
239  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
240
241  virtual Stmt* v_getSubStmt() = 0;
242  Stmt *getSubStmt() { return v_getSubStmt(); }
243
244  virtual SourceRange getSourceRange() const { return SourceRange(); }
245
246  static bool classof(const Stmt *T) {
247    return T->getStmtClass() == CaseStmtClass ||
248    T->getStmtClass() == DefaultStmtClass;
249  }
250  static bool classof(const SwitchCase *) { return true; }
251};
252
253class CaseStmt : public SwitchCase {
254  enum { SUBSTMT, LHS, RHS, END_EXPR };
255  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
256                             // GNU "case 1 ... 4" extension
257  SourceLocation CaseLoc;
258public:
259  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc)
260    : SwitchCase(CaseStmtClass) {
261    SubExprs[SUBSTMT] = substmt;
262    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
263    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
264    CaseLoc = caseLoc;
265  }
266
267  SourceLocation getCaseLoc() const { return CaseLoc; }
268
269  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
270  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
271  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
272  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
273  const Expr *getLHS() const {
274    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
275  }
276  const Expr *getRHS() const {
277    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
278  }
279  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
280
281  virtual SourceRange getSourceRange() const {
282    return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd());
283  }
284  static bool classof(const Stmt *T) {
285    return T->getStmtClass() == CaseStmtClass;
286  }
287  static bool classof(const CaseStmt *) { return true; }
288
289  // Iterators
290  virtual child_iterator child_begin();
291  virtual child_iterator child_end();
292};
293
294class DefaultStmt : public SwitchCase {
295  Stmt* SubStmt;
296  SourceLocation DefaultLoc;
297public:
298  DefaultStmt(SourceLocation DL, Stmt *substmt) :
299    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
300
301  Stmt *getSubStmt() { return SubStmt; }
302  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
303  const Stmt *getSubStmt() const { return SubStmt; }
304
305  SourceLocation getDefaultLoc() const { return DefaultLoc; }
306
307  virtual SourceRange getSourceRange() const {
308    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
309  }
310  static bool classof(const Stmt *T) {
311    return T->getStmtClass() == DefaultStmtClass;
312  }
313  static bool classof(const DefaultStmt *) { return true; }
314
315  // Iterators
316  virtual child_iterator child_begin();
317  virtual child_iterator child_end();
318};
319
320class LabelStmt : public Stmt {
321  IdentifierInfo *Label;
322  Stmt *SubStmt;
323  SourceLocation IdentLoc;
324public:
325  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
326    : Stmt(LabelStmtClass), Label(label),
327      SubStmt(substmt), IdentLoc(IL) {}
328
329  SourceLocation getIdentLoc() const { return IdentLoc; }
330  IdentifierInfo *getID() const { return Label; }
331  const char *getName() const;
332  Stmt *getSubStmt() { return SubStmt; }
333  const Stmt *getSubStmt() const { return SubStmt; }
334
335  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
336  void setSubStmt(Stmt *SS) { SubStmt = SS; }
337
338  virtual SourceRange getSourceRange() const {
339    return SourceRange(IdentLoc, SubStmt->getLocEnd());
340  }
341  static bool classof(const Stmt *T) {
342    return T->getStmtClass() == LabelStmtClass;
343  }
344  static bool classof(const LabelStmt *) { return true; }
345
346  // Iterators
347  virtual child_iterator child_begin();
348  virtual child_iterator child_end();
349};
350
351
352/// IfStmt - This represents an if/then/else.
353///
354class IfStmt : public Stmt {
355  enum { COND, THEN, ELSE, END_EXPR };
356  Stmt* SubExprs[END_EXPR];
357  SourceLocation IfLoc;
358public:
359  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
360    : Stmt(IfStmtClass)  {
361    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
362    SubExprs[THEN] = then;
363    SubExprs[ELSE] = elsev;
364    IfLoc = IL;
365  }
366
367  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
368  const Stmt *getThen() const { return SubExprs[THEN]; }
369  const Stmt *getElse() const { return SubExprs[ELSE]; }
370
371  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
372  Stmt *getThen() { return SubExprs[THEN]; }
373  Stmt *getElse() { return SubExprs[ELSE]; }
374
375  virtual SourceRange getSourceRange() const {
376    if (SubExprs[ELSE])
377      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
378    else
379      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
380  }
381
382  static bool classof(const Stmt *T) {
383    return T->getStmtClass() == IfStmtClass;
384  }
385  static bool classof(const IfStmt *) { return true; }
386
387  // Iterators
388  virtual child_iterator child_begin();
389  virtual child_iterator child_end();
390};
391
392/// SwitchStmt - This represents a 'switch' stmt.
393///
394class SwitchStmt : public Stmt {
395  enum { COND, BODY, END_EXPR };
396  Stmt* SubExprs[END_EXPR];
397  // This points to a linked list of case and default statements.
398  SwitchCase *FirstCase;
399  SourceLocation SwitchLoc;
400public:
401  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
402      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
403      SubExprs[BODY] = NULL;
404    }
405
406  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
407  const Stmt *getBody() const { return SubExprs[BODY]; }
408  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
409
410  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
411  Stmt *getBody() { return SubExprs[BODY]; }
412  SwitchCase *getSwitchCaseList() { return FirstCase; }
413
414  void setBody(Stmt *S, SourceLocation SL) {
415    SubExprs[BODY] = S;
416    SwitchLoc = SL;
417  }
418  void addSwitchCase(SwitchCase *SC) {
419    if (FirstCase)
420      SC->setNextSwitchCase(FirstCase);
421
422    FirstCase = SC;
423  }
424  virtual SourceRange getSourceRange() const {
425    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
426  }
427  static bool classof(const Stmt *T) {
428    return T->getStmtClass() == SwitchStmtClass;
429  }
430  static bool classof(const SwitchStmt *) { return true; }
431
432  // Iterators
433  virtual child_iterator child_begin();
434  virtual child_iterator child_end();
435};
436
437
438/// WhileStmt - This represents a 'while' stmt.
439///
440class WhileStmt : public Stmt {
441  enum { COND, BODY, END_EXPR };
442  Stmt* SubExprs[END_EXPR];
443  SourceLocation WhileLoc;
444public:
445  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
446    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
447    SubExprs[BODY] = body;
448    WhileLoc = WL;
449  }
450
451  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
452  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
453  Stmt *getBody() { return SubExprs[BODY]; }
454  const Stmt *getBody() const { return SubExprs[BODY]; }
455
456  virtual SourceRange getSourceRange() const {
457    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
458  }
459  static bool classof(const Stmt *T) {
460    return T->getStmtClass() == WhileStmtClass;
461  }
462  static bool classof(const WhileStmt *) { return true; }
463
464  // Iterators
465  virtual child_iterator child_begin();
466  virtual child_iterator child_end();
467};
468
469/// DoStmt - This represents a 'do/while' stmt.
470///
471class DoStmt : public Stmt {
472  enum { COND, BODY, END_EXPR };
473  Stmt* SubExprs[END_EXPR];
474  SourceLocation DoLoc;
475public:
476  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
477    : Stmt(DoStmtClass), DoLoc(DL) {
478    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
479    SubExprs[BODY] = body;
480    DoLoc = DL;
481  }
482
483  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
484  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
485  Stmt *getBody() { return SubExprs[BODY]; }
486  const Stmt *getBody() const { return SubExprs[BODY]; }
487
488  virtual SourceRange getSourceRange() const {
489    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
490  }
491  static bool classof(const Stmt *T) {
492    return T->getStmtClass() == DoStmtClass;
493  }
494  static bool classof(const DoStmt *) { return true; }
495
496  // Iterators
497  virtual child_iterator child_begin();
498  virtual child_iterator child_end();
499};
500
501
502/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
503/// the init/cond/inc parts of the ForStmt will be null if they were not
504/// specified in the source.
505///
506class ForStmt : public Stmt {
507  enum { INIT, COND, INC, BODY, END_EXPR };
508  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
509  SourceLocation ForLoc;
510public:
511  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
512    : Stmt(ForStmtClass) {
513    SubExprs[INIT] = Init;
514    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
515    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
516    SubExprs[BODY] = Body;
517    ForLoc = FL;
518  }
519
520  Stmt *getInit() { return SubExprs[INIT]; }
521  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
522  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
523  Stmt *getBody() { return SubExprs[BODY]; }
524
525  const Stmt *getInit() const { return SubExprs[INIT]; }
526  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
527  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
528  const Stmt *getBody() const { return SubExprs[BODY]; }
529
530  virtual SourceRange getSourceRange() const {
531    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
532  }
533  static bool classof(const Stmt *T) {
534    return T->getStmtClass() == ForStmtClass;
535  }
536  static bool classof(const ForStmt *) { return true; }
537
538  // Iterators
539  virtual child_iterator child_begin();
540  virtual child_iterator child_end();
541};
542
543/// GotoStmt - This represents a direct goto.
544///
545class GotoStmt : public Stmt {
546  LabelStmt *Label;
547  SourceLocation GotoLoc;
548  SourceLocation LabelLoc;
549public:
550  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
551    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
552
553  LabelStmt *getLabel() const { return Label; }
554
555  virtual SourceRange getSourceRange() const {
556    return SourceRange(GotoLoc, LabelLoc);
557  }
558  static bool classof(const Stmt *T) {
559    return T->getStmtClass() == GotoStmtClass;
560  }
561  static bool classof(const GotoStmt *) { return true; }
562
563  // Iterators
564  virtual child_iterator child_begin();
565  virtual child_iterator child_end();
566};
567
568/// IndirectGotoStmt - This represents an indirect goto.
569///
570class IndirectGotoStmt : public Stmt {
571  Expr *Target;
572public:
573  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){}
574
575  Expr *getTarget() { return Target; }
576  const Expr *getTarget() const { return Target; }
577
578  virtual SourceRange getSourceRange() const { return SourceRange(); }
579
580  static bool classof(const Stmt *T) {
581    return T->getStmtClass() == IndirectGotoStmtClass;
582  }
583  static bool classof(const IndirectGotoStmt *) { return true; }
584
585  // Iterators
586  virtual child_iterator child_begin();
587  virtual child_iterator child_end();
588};
589
590
591/// ContinueStmt - This represents a continue.
592///
593class ContinueStmt : public Stmt {
594  SourceLocation ContinueLoc;
595public:
596  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
597
598  virtual SourceRange getSourceRange() const {
599    return SourceRange(ContinueLoc);
600  }
601  static bool classof(const Stmt *T) {
602    return T->getStmtClass() == ContinueStmtClass;
603  }
604  static bool classof(const ContinueStmt *) { return true; }
605
606  // Iterators
607  virtual child_iterator child_begin();
608  virtual child_iterator child_end();
609};
610
611/// BreakStmt - This represents a break.
612///
613class BreakStmt : public Stmt {
614  SourceLocation BreakLoc;
615public:
616  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
617
618  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
619
620  static bool classof(const Stmt *T) {
621    return T->getStmtClass() == BreakStmtClass;
622  }
623  static bool classof(const BreakStmt *) { return true; }
624
625  // Iterators
626  virtual child_iterator child_begin();
627  virtual child_iterator child_end();
628};
629
630
631/// ReturnStmt - This represents a return, optionally of an expression.
632///
633class ReturnStmt : public Stmt {
634  Expr *RetExpr;
635  SourceLocation RetLoc;
636public:
637  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
638    RetExpr(E), RetLoc(RL) {}
639
640  const Expr *getRetValue() const { return RetExpr; }
641  Expr *getRetValue() { return RetExpr; }
642
643  virtual SourceRange getSourceRange() const;
644
645  static bool classof(const Stmt *T) {
646    return T->getStmtClass() == ReturnStmtClass;
647  }
648  static bool classof(const ReturnStmt *) { return true; }
649
650  // Iterators
651  virtual child_iterator child_begin();
652  virtual child_iterator child_end();
653
654  virtual void directEmit(llvm::Serializer& S) const;
655  static ReturnStmt* directMaterialize(llvm::Deserializer& D);
656};
657
658/// AsmStmt - This represents a GNU inline-assembly statement extension.
659///
660class AsmStmt : public Stmt {
661  SourceLocation AsmLoc, RParenLoc;
662  // FIXME: This doesn't capture most of the interesting pieces.
663public:
664  AsmStmt(SourceLocation asmloc, SourceLocation rparenloc)
665    : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {}
666
667  virtual SourceRange getSourceRange() const {
668    return SourceRange(AsmLoc, RParenLoc);
669  }
670
671  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
672  static bool classof(const AsmStmt *) { return true; }
673
674  virtual child_iterator child_begin();
675  virtual child_iterator child_end();
676};
677
678/// ObjcAtCatchStmt - This represents objective-c's @catch statement.
679class ObjcAtCatchStmt : public Stmt {
680private:
681  // Points to next @catch statement, or null
682  ObjcAtCatchStmt *NextAtCatchStmt;
683  enum { SELECTOR, BODY, END_EXPR };
684  Stmt *SubExprs[END_EXPR];
685  SourceLocation AtCatchLoc, RParenLoc;
686
687public:
688  ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
689                  Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList)
690  : Stmt(ObjcAtCatchStmtClass),
691    AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {
692      SubExprs[SELECTOR] = catchVarStmtDecl;
693      SubExprs[BODY] = atCatchStmt;
694      SubExprs[END_EXPR] = NULL;
695      if (!atCatchList)
696        NextAtCatchStmt = NULL;
697      else {
698        ObjcAtCatchStmt *AtCatchList =
699          static_cast<ObjcAtCatchStmt*>(atCatchList);
700        while (AtCatchList->NextAtCatchStmt)
701          AtCatchList = AtCatchList->NextAtCatchStmt;
702        AtCatchList->NextAtCatchStmt = this;
703      }
704    }
705
706  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
707  Stmt *getCatchBody() { return SubExprs[BODY]; }
708  const Stmt *getNextCatchStmt() const { return NextAtCatchStmt; }
709  Stmt *getNextCatchStmt() { return NextAtCatchStmt; }
710  const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; }
711  Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; }
712
713  virtual SourceRange getSourceRange() const {
714    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
715  }
716
717  static bool classof(const Stmt *T) {
718    return T->getStmtClass() == ObjcAtCatchStmtClass;
719  }
720  static bool classof(const ObjcAtCatchStmt *) { return true; }
721
722  virtual child_iterator child_begin();
723  virtual child_iterator child_end();
724
725};
726
727/// ObjcAtFinallyStmt - This represent objective-c's @finally Statement
728class ObjcAtFinallyStmt : public Stmt {
729  private:
730    Stmt *AtFinallyStmt;
731    SourceLocation AtFinallyLoc;
732
733  public:
734    ObjcAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
735    : Stmt(ObjcAtFinallyStmtClass),
736      AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
737
738    const Stmt *getFinallyBody () const { return AtFinallyStmt; }
739    Stmt *getFinallyBody () { return AtFinallyStmt; }
740
741    virtual SourceRange getSourceRange() const {
742      return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
743    }
744
745    static bool classof(const Stmt *T) {
746      return T->getStmtClass() == ObjcAtFinallyStmtClass;
747    }
748    static bool classof(const ObjcAtFinallyStmt *) { return true; }
749
750    virtual child_iterator child_begin();
751    virtual child_iterator child_end();
752
753};
754
755/// ObjcAtTryStmt - This represent objective-c's over-all
756/// @try ... @catch ... @finally statement.
757class ObjcAtTryStmt : public Stmt {
758private:
759  enum { TRY, CATCH, FINALLY, END_TRY };
760  Stmt* SubStmts[END_TRY];
761
762  SourceLocation AtTryLoc;
763
764public:
765  ObjcAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
766                Stmt *atCatchStmt,
767                Stmt *atFinallyStmt)
768  : Stmt(ObjcAtTryStmtClass) {
769      SubStmts[TRY] = atTryStmt;
770      SubStmts[CATCH] = atCatchStmt;
771      SubStmts[FINALLY] = atFinallyStmt;
772      SubStmts[END_TRY] = NULL;
773      AtTryLoc = atTryLoc;
774    }
775
776  const Stmt *getTryBody() const { return SubStmts[TRY]; }
777  Stmt *getTryBody() { return SubStmts[TRY]; }
778  const Stmt *getCatchStmts() const { return SubStmts[CATCH]; }
779  Stmt *getCatchStmts() { return SubStmts[CATCH]; }
780  const Stmt *getFinallyStmt() const { return SubStmts[FINALLY]; }
781  Stmt *getFinallyStmt() { return SubStmts[FINALLY]; }
782
783  virtual SourceRange getSourceRange() const {
784    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
785  }
786
787  static bool classof(const Stmt *T) {
788    return T->getStmtClass() == ObjcAtTryStmtClass;
789  }
790  static bool classof(const ObjcAtTryStmt *) { return true; }
791
792  virtual child_iterator child_begin();
793  virtual child_iterator child_end();
794
795};
796
797}  // end namespace clang
798
799#endif
800