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