Stmt.h revision 39f8f159c488a900e5958d5aab3e467af9ec8a2b
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  virtual void directEmit(llvm::Serializer& S) const;
172  static NullStmt* directMaterialize(llvm::Deserializer& D);
173};
174
175/// CompoundStmt - This represents a group of statements like { stmt stmt }.
176///
177class CompoundStmt : public Stmt {
178  llvm::SmallVector<Stmt*, 16> Body;
179  SourceLocation LBracLoc, RBracLoc;
180public:
181  CompoundStmt(Stmt **StmtStart, unsigned NumStmts,
182               SourceLocation LB, SourceLocation RB)
183    : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts),
184      LBracLoc(LB), RBracLoc(RB) {}
185
186  bool body_empty() const { return Body.empty(); }
187
188  typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
189  body_iterator body_begin() { return Body.begin(); }
190  body_iterator body_end() { return Body.end(); }
191  Stmt *body_back() { return Body.back(); }
192
193  typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
194  const_body_iterator body_begin() const { return Body.begin(); }
195  const_body_iterator body_end() const { return Body.end(); }
196  const Stmt *body_back() const { return Body.back(); }
197
198  typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator;
199  reverse_body_iterator body_rbegin() { return Body.rbegin(); }
200  reverse_body_iterator body_rend() { return Body.rend(); }
201
202  typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator
203    const_reverse_body_iterator;
204  const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); }
205  const_reverse_body_iterator body_rend() const { return Body.rend(); }
206
207  void push_back(Stmt *S) { Body.push_back(S); }
208
209  virtual SourceRange getSourceRange() const {
210    return SourceRange(LBracLoc, RBracLoc);
211  }
212
213  SourceLocation getLBracLoc() const { return LBracLoc; }
214  SourceLocation getRBracLoc() const { return RBracLoc; }
215
216  static bool classof(const Stmt *T) {
217    return T->getStmtClass() == CompoundStmtClass;
218  }
219  static bool classof(const CompoundStmt *) { return true; }
220
221  // Iterators
222  virtual child_iterator child_begin();
223  virtual child_iterator child_end();
224
225  virtual void directEmit(llvm::Serializer& S) const;
226  static CompoundStmt* directMaterialize(llvm::Deserializer& D);
227};
228
229// SwitchCase is the base class for CaseStmt and DefaultStmt,
230class SwitchCase : public Stmt {
231  // A pointer to the following CaseStmt or DefaultStmt class,
232  // used by SwitchStmt.
233  SwitchCase *NextSwitchCase;
234protected:
235  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
236
237public:
238  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
239
240  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
241
242  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
243
244  virtual Stmt* v_getSubStmt() = 0;
245  Stmt *getSubStmt() { return v_getSubStmt(); }
246
247  virtual SourceRange getSourceRange() const { return SourceRange(); }
248
249  static bool classof(const Stmt *T) {
250    return T->getStmtClass() == CaseStmtClass ||
251    T->getStmtClass() == DefaultStmtClass;
252  }
253  static bool classof(const SwitchCase *) { return true; }
254};
255
256class CaseStmt : public SwitchCase {
257  enum { SUBSTMT, LHS, RHS, END_EXPR };
258  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
259                             // GNU "case 1 ... 4" extension
260  SourceLocation CaseLoc;
261public:
262  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc)
263    : SwitchCase(CaseStmtClass) {
264    SubExprs[SUBSTMT] = substmt;
265    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
266    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
267    CaseLoc = caseLoc;
268  }
269
270  SourceLocation getCaseLoc() const { return CaseLoc; }
271
272  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
273  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
274  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
275  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
276  const Expr *getLHS() const {
277    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
278  }
279  const Expr *getRHS() const {
280    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
281  }
282  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
283
284  virtual SourceRange getSourceRange() const {
285    return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd());
286  }
287  static bool classof(const Stmt *T) {
288    return T->getStmtClass() == CaseStmtClass;
289  }
290  static bool classof(const CaseStmt *) { return true; }
291
292  // Iterators
293  virtual child_iterator child_begin();
294  virtual child_iterator child_end();
295};
296
297class DefaultStmt : public SwitchCase {
298  Stmt* SubStmt;
299  SourceLocation DefaultLoc;
300public:
301  DefaultStmt(SourceLocation DL, Stmt *substmt) :
302    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
303
304  Stmt *getSubStmt() { return SubStmt; }
305  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
306  const Stmt *getSubStmt() const { return SubStmt; }
307
308  SourceLocation getDefaultLoc() const { return DefaultLoc; }
309
310  virtual SourceRange getSourceRange() const {
311    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
312  }
313  static bool classof(const Stmt *T) {
314    return T->getStmtClass() == DefaultStmtClass;
315  }
316  static bool classof(const DefaultStmt *) { return true; }
317
318  // Iterators
319  virtual child_iterator child_begin();
320  virtual child_iterator child_end();
321};
322
323class LabelStmt : public Stmt {
324  IdentifierInfo *Label;
325  Stmt *SubStmt;
326  SourceLocation IdentLoc;
327public:
328  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
329    : Stmt(LabelStmtClass), Label(label),
330      SubStmt(substmt), IdentLoc(IL) {}
331
332  SourceLocation getIdentLoc() const { return IdentLoc; }
333  IdentifierInfo *getID() const { return Label; }
334  const char *getName() const;
335  Stmt *getSubStmt() { return SubStmt; }
336  const Stmt *getSubStmt() const { return SubStmt; }
337
338  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
339  void setSubStmt(Stmt *SS) { SubStmt = SS; }
340
341  virtual SourceRange getSourceRange() const {
342    return SourceRange(IdentLoc, SubStmt->getLocEnd());
343  }
344  static bool classof(const Stmt *T) {
345    return T->getStmtClass() == LabelStmtClass;
346  }
347  static bool classof(const LabelStmt *) { return true; }
348
349  // Iterators
350  virtual child_iterator child_begin();
351  virtual child_iterator child_end();
352
353  virtual void directEmit(llvm::Serializer& S) const;
354  static LabelStmt* directMaterialize(llvm::Deserializer& D);
355};
356
357
358/// IfStmt - This represents an if/then/else.
359///
360class IfStmt : public Stmt {
361  enum { COND, THEN, ELSE, END_EXPR };
362  Stmt* SubExprs[END_EXPR];
363  SourceLocation IfLoc;
364public:
365  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
366    : Stmt(IfStmtClass)  {
367    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
368    SubExprs[THEN] = then;
369    SubExprs[ELSE] = elsev;
370    IfLoc = IL;
371  }
372
373  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
374  const Stmt *getThen() const { return SubExprs[THEN]; }
375  const Stmt *getElse() const { return SubExprs[ELSE]; }
376
377  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
378  Stmt *getThen() { return SubExprs[THEN]; }
379  Stmt *getElse() { return SubExprs[ELSE]; }
380
381  virtual SourceRange getSourceRange() const {
382    if (SubExprs[ELSE])
383      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
384    else
385      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
386  }
387
388  static bool classof(const Stmt *T) {
389    return T->getStmtClass() == IfStmtClass;
390  }
391  static bool classof(const IfStmt *) { return true; }
392
393  // Iterators
394  virtual child_iterator child_begin();
395  virtual child_iterator child_end();
396};
397
398/// SwitchStmt - This represents a 'switch' stmt.
399///
400class SwitchStmt : public Stmt {
401  enum { COND, BODY, END_EXPR };
402  Stmt* SubExprs[END_EXPR];
403  // This points to a linked list of case and default statements.
404  SwitchCase *FirstCase;
405  SourceLocation SwitchLoc;
406public:
407  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
408      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
409      SubExprs[BODY] = NULL;
410    }
411
412  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
413  const Stmt *getBody() const { return SubExprs[BODY]; }
414  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
415
416  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
417  Stmt *getBody() { return SubExprs[BODY]; }
418  SwitchCase *getSwitchCaseList() { return FirstCase; }
419
420  void setBody(Stmt *S, SourceLocation SL) {
421    SubExprs[BODY] = S;
422    SwitchLoc = SL;
423  }
424  void addSwitchCase(SwitchCase *SC) {
425    if (FirstCase)
426      SC->setNextSwitchCase(FirstCase);
427
428    FirstCase = SC;
429  }
430  virtual SourceRange getSourceRange() const {
431    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
432  }
433  static bool classof(const Stmt *T) {
434    return T->getStmtClass() == SwitchStmtClass;
435  }
436  static bool classof(const SwitchStmt *) { return true; }
437
438  // Iterators
439  virtual child_iterator child_begin();
440  virtual child_iterator child_end();
441};
442
443
444/// WhileStmt - This represents a 'while' stmt.
445///
446class WhileStmt : public Stmt {
447  enum { COND, BODY, END_EXPR };
448  Stmt* SubExprs[END_EXPR];
449  SourceLocation WhileLoc;
450public:
451  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
452    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
453    SubExprs[BODY] = body;
454    WhileLoc = WL;
455  }
456
457  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
458  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
459  Stmt *getBody() { return SubExprs[BODY]; }
460  const Stmt *getBody() const { return SubExprs[BODY]; }
461
462  virtual SourceRange getSourceRange() const {
463    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
464  }
465  static bool classof(const Stmt *T) {
466    return T->getStmtClass() == WhileStmtClass;
467  }
468  static bool classof(const WhileStmt *) { return true; }
469
470  // Iterators
471  virtual child_iterator child_begin();
472  virtual child_iterator child_end();
473};
474
475/// DoStmt - This represents a 'do/while' stmt.
476///
477class DoStmt : public Stmt {
478  enum { COND, BODY, END_EXPR };
479  Stmt* SubExprs[END_EXPR];
480  SourceLocation DoLoc;
481public:
482  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
483    : Stmt(DoStmtClass), DoLoc(DL) {
484    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
485    SubExprs[BODY] = body;
486    DoLoc = DL;
487  }
488
489  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
490  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
491  Stmt *getBody() { return SubExprs[BODY]; }
492  const Stmt *getBody() const { return SubExprs[BODY]; }
493
494  virtual SourceRange getSourceRange() const {
495    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
496  }
497  static bool classof(const Stmt *T) {
498    return T->getStmtClass() == DoStmtClass;
499  }
500  static bool classof(const DoStmt *) { return true; }
501
502  // Iterators
503  virtual child_iterator child_begin();
504  virtual child_iterator child_end();
505};
506
507
508/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
509/// the init/cond/inc parts of the ForStmt will be null if they were not
510/// specified in the source.
511///
512class ForStmt : public Stmt {
513  enum { INIT, COND, INC, BODY, END_EXPR };
514  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
515  SourceLocation ForLoc;
516public:
517  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
518    : Stmt(ForStmtClass) {
519    SubExprs[INIT] = Init;
520    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
521    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
522    SubExprs[BODY] = Body;
523    ForLoc = FL;
524  }
525
526  Stmt *getInit() { return SubExprs[INIT]; }
527  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
528  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
529  Stmt *getBody() { return SubExprs[BODY]; }
530
531  const Stmt *getInit() const { return SubExprs[INIT]; }
532  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
533  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
534  const Stmt *getBody() const { return SubExprs[BODY]; }
535
536  virtual SourceRange getSourceRange() const {
537    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
538  }
539  static bool classof(const Stmt *T) {
540    return T->getStmtClass() == ForStmtClass;
541  }
542  static bool classof(const ForStmt *) { return true; }
543
544  // Iterators
545  virtual child_iterator child_begin();
546  virtual child_iterator child_end();
547};
548
549/// GotoStmt - This represents a direct goto.
550///
551class GotoStmt : public Stmt {
552  LabelStmt *Label;
553  SourceLocation GotoLoc;
554  SourceLocation LabelLoc;
555public:
556  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
557    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
558
559  LabelStmt *getLabel() const { return Label; }
560
561  virtual SourceRange getSourceRange() const {
562    return SourceRange(GotoLoc, LabelLoc);
563  }
564  static bool classof(const Stmt *T) {
565    return T->getStmtClass() == GotoStmtClass;
566  }
567  static bool classof(const GotoStmt *) { return true; }
568
569  // Iterators
570  virtual child_iterator child_begin();
571  virtual child_iterator child_end();
572};
573
574/// IndirectGotoStmt - This represents an indirect goto.
575///
576class IndirectGotoStmt : public Stmt {
577  Expr *Target;
578public:
579  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){}
580
581  Expr *getTarget() { return Target; }
582  const Expr *getTarget() const { return Target; }
583
584  virtual SourceRange getSourceRange() const { return SourceRange(); }
585
586  static bool classof(const Stmt *T) {
587    return T->getStmtClass() == IndirectGotoStmtClass;
588  }
589  static bool classof(const IndirectGotoStmt *) { return true; }
590
591  // Iterators
592  virtual child_iterator child_begin();
593  virtual child_iterator child_end();
594};
595
596
597/// ContinueStmt - This represents a continue.
598///
599class ContinueStmt : public Stmt {
600  SourceLocation ContinueLoc;
601public:
602  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
603
604  virtual SourceRange getSourceRange() const {
605    return SourceRange(ContinueLoc);
606  }
607  static bool classof(const Stmt *T) {
608    return T->getStmtClass() == ContinueStmtClass;
609  }
610  static bool classof(const ContinueStmt *) { return true; }
611
612  // Iterators
613  virtual child_iterator child_begin();
614  virtual child_iterator child_end();
615};
616
617/// BreakStmt - This represents a break.
618///
619class BreakStmt : public Stmt {
620  SourceLocation BreakLoc;
621public:
622  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
623
624  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
625
626  static bool classof(const Stmt *T) {
627    return T->getStmtClass() == BreakStmtClass;
628  }
629  static bool classof(const BreakStmt *) { return true; }
630
631  // Iterators
632  virtual child_iterator child_begin();
633  virtual child_iterator child_end();
634};
635
636
637/// ReturnStmt - This represents a return, optionally of an expression.
638///
639class ReturnStmt : public Stmt {
640  Expr *RetExpr;
641  SourceLocation RetLoc;
642public:
643  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
644    RetExpr(E), RetLoc(RL) {}
645
646  const Expr *getRetValue() const { return RetExpr; }
647  Expr *getRetValue() { return RetExpr; }
648
649  virtual SourceRange getSourceRange() const;
650
651  static bool classof(const Stmt *T) {
652    return T->getStmtClass() == ReturnStmtClass;
653  }
654  static bool classof(const ReturnStmt *) { return true; }
655
656  // Iterators
657  virtual child_iterator child_begin();
658  virtual child_iterator child_end();
659
660  virtual void directEmit(llvm::Serializer& S) const;
661  static ReturnStmt* directMaterialize(llvm::Deserializer& D);
662};
663
664/// AsmStmt - This represents a GNU inline-assembly statement extension.
665///
666class AsmStmt : public Stmt {
667  SourceLocation AsmLoc, RParenLoc;
668  // FIXME: This doesn't capture most of the interesting pieces.
669public:
670  AsmStmt(SourceLocation asmloc, SourceLocation rparenloc)
671    : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {}
672
673  virtual SourceRange getSourceRange() const {
674    return SourceRange(AsmLoc, RParenLoc);
675  }
676
677  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
678  static bool classof(const AsmStmt *) { return true; }
679
680  virtual child_iterator child_begin();
681  virtual child_iterator child_end();
682};
683
684/// ObjcAtCatchStmt - This represents objective-c's @catch statement.
685class ObjcAtCatchStmt : public Stmt {
686private:
687  // Points to next @catch statement, or null
688  ObjcAtCatchStmt *NextAtCatchStmt;
689  enum { SELECTOR, BODY, END_EXPR };
690  Stmt *SubExprs[END_EXPR];
691  SourceLocation AtCatchLoc, RParenLoc;
692
693public:
694  ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
695                  Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList)
696  : Stmt(ObjcAtCatchStmtClass),
697    AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {
698      SubExprs[SELECTOR] = catchVarStmtDecl;
699      SubExprs[BODY] = atCatchStmt;
700      SubExprs[END_EXPR] = NULL;
701      if (!atCatchList)
702        NextAtCatchStmt = NULL;
703      else {
704        ObjcAtCatchStmt *AtCatchList =
705          static_cast<ObjcAtCatchStmt*>(atCatchList);
706        while (AtCatchList->NextAtCatchStmt)
707          AtCatchList = AtCatchList->NextAtCatchStmt;
708        AtCatchList->NextAtCatchStmt = this;
709      }
710    }
711
712  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
713  Stmt *getCatchBody() { return SubExprs[BODY]; }
714  const Stmt *getNextCatchStmt() const { return NextAtCatchStmt; }
715  Stmt *getNextCatchStmt() { return NextAtCatchStmt; }
716  const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; }
717  Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; }
718
719  virtual SourceRange getSourceRange() const {
720    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
721  }
722
723  static bool classof(const Stmt *T) {
724    return T->getStmtClass() == ObjcAtCatchStmtClass;
725  }
726  static bool classof(const ObjcAtCatchStmt *) { return true; }
727
728  virtual child_iterator child_begin();
729  virtual child_iterator child_end();
730
731};
732
733/// ObjcAtFinallyStmt - This represent objective-c's @finally Statement
734class ObjcAtFinallyStmt : public Stmt {
735  private:
736    Stmt *AtFinallyStmt;
737    SourceLocation AtFinallyLoc;
738
739  public:
740    ObjcAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
741    : Stmt(ObjcAtFinallyStmtClass),
742      AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
743
744    const Stmt *getFinallyBody () const { return AtFinallyStmt; }
745    Stmt *getFinallyBody () { return AtFinallyStmt; }
746
747    virtual SourceRange getSourceRange() const {
748      return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
749    }
750
751    static bool classof(const Stmt *T) {
752      return T->getStmtClass() == ObjcAtFinallyStmtClass;
753    }
754    static bool classof(const ObjcAtFinallyStmt *) { return true; }
755
756    virtual child_iterator child_begin();
757    virtual child_iterator child_end();
758
759};
760
761/// ObjcAtTryStmt - This represent objective-c's over-all
762/// @try ... @catch ... @finally statement.
763class ObjcAtTryStmt : public Stmt {
764private:
765  enum { TRY, CATCH, FINALLY, END_TRY };
766  Stmt* SubStmts[END_TRY];
767
768  SourceLocation AtTryLoc;
769
770public:
771  ObjcAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
772                Stmt *atCatchStmt,
773                Stmt *atFinallyStmt)
774  : Stmt(ObjcAtTryStmtClass) {
775      SubStmts[TRY] = atTryStmt;
776      SubStmts[CATCH] = atCatchStmt;
777      SubStmts[FINALLY] = atFinallyStmt;
778      SubStmts[END_TRY] = NULL;
779      AtTryLoc = atTryLoc;
780    }
781
782  const Stmt *getTryBody() const { return SubStmts[TRY]; }
783  Stmt *getTryBody() { return SubStmts[TRY]; }
784  const Stmt *getCatchStmts() const { return SubStmts[CATCH]; }
785  Stmt *getCatchStmts() { return SubStmts[CATCH]; }
786  const Stmt *getFinallyStmt() const { return SubStmts[FINALLY]; }
787  Stmt *getFinallyStmt() { return SubStmts[FINALLY]; }
788
789  virtual SourceRange getSourceRange() const {
790    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
791  }
792
793  static bool classof(const Stmt *T) {
794    return T->getStmtClass() == ObjcAtTryStmtClass;
795  }
796  static bool classof(const ObjcAtTryStmt *) { return true; }
797
798  virtual child_iterator child_begin();
799  virtual child_iterator child_end();
800
801};
802
803/// ObjcAtThrowStmt - This represents objective-c's @throw statement.
804class ObjcAtThrowStmt : public Stmt {
805private:
806  Stmt *Throw;
807  SourceLocation AtThrowLoc;
808
809public:
810  ObjcAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
811  : Stmt(ObjcAtThrowStmtClass), Throw(throwExpr) {
812    AtThrowLoc = atThrowLoc;
813  }
814
815  Expr *const getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
816
817  virtual SourceRange getSourceRange() const {
818    return SourceRange(AtThrowLoc, Throw->getLocEnd());
819  }
820
821  static bool classof(const Stmt *T) {
822    return T->getStmtClass() == ObjcAtThrowStmtClass;
823  }
824  static bool classof(const ObjcAtThrowStmt *) { return true; }
825
826  virtual child_iterator child_begin();
827  virtual child_iterator child_end();
828};
829
830}  // end namespace clang
831
832#endif
833