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