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