Stmt.h revision 1f85acd5ff54345788b93111197088160fe9f06e
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* Create(llvm::Deserializer& D);
119
120  virtual void EmitImpl(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 EmitImpl(llvm::Serializer& S) const;
151  static DeclStmt* CreateImpl(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 EmitImpl(llvm::Serializer& S) const;
175  static NullStmt* CreateImpl(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 EmitImpl(llvm::Serializer& S) const;
229  static CompoundStmt* CreateImpl(llvm::Deserializer& D);
230};
231
232// SwitchCase is the base class for CaseStmt and DefaultStmt,
233class SwitchCase : public Stmt {
234protected:
235  // A pointer to the following CaseStmt or DefaultStmt class,
236  // used by SwitchStmt.
237  SwitchCase *NextSwitchCase;
238
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  virtual void EmitImpl(llvm::Serializer& S) const;
301  static CaseStmt* CreateImpl(llvm::Deserializer& D);
302};
303
304class DefaultStmt : public SwitchCase {
305  Stmt* SubStmt;
306  SourceLocation DefaultLoc;
307public:
308  DefaultStmt(SourceLocation DL, Stmt *substmt) :
309    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
310
311  Stmt *getSubStmt() { return SubStmt; }
312  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
313  const Stmt *getSubStmt() const { return SubStmt; }
314
315  SourceLocation getDefaultLoc() const { return DefaultLoc; }
316
317  virtual SourceRange getSourceRange() const {
318    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
319  }
320  static bool classof(const Stmt *T) {
321    return T->getStmtClass() == DefaultStmtClass;
322  }
323  static bool classof(const DefaultStmt *) { return true; }
324
325  // Iterators
326  virtual child_iterator child_begin();
327  virtual child_iterator child_end();
328
329  virtual void EmitImpl(llvm::Serializer& S) const;
330  static DefaultStmt* CreateImpl(llvm::Deserializer& D);
331};
332
333class LabelStmt : public Stmt {
334  IdentifierInfo *Label;
335  Stmt *SubStmt;
336  SourceLocation IdentLoc;
337public:
338  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
339    : Stmt(LabelStmtClass), Label(label),
340      SubStmt(substmt), IdentLoc(IL) {}
341
342  SourceLocation getIdentLoc() const { return IdentLoc; }
343  IdentifierInfo *getID() const { return Label; }
344  const char *getName() const;
345  Stmt *getSubStmt() { return SubStmt; }
346  const Stmt *getSubStmt() const { return SubStmt; }
347
348  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
349  void setSubStmt(Stmt *SS) { SubStmt = SS; }
350
351  virtual SourceRange getSourceRange() const {
352    return SourceRange(IdentLoc, SubStmt->getLocEnd());
353  }
354  static bool classof(const Stmt *T) {
355    return T->getStmtClass() == LabelStmtClass;
356  }
357  static bool classof(const LabelStmt *) { return true; }
358
359  // Iterators
360  virtual child_iterator child_begin();
361  virtual child_iterator child_end();
362
363  virtual void EmitImpl(llvm::Serializer& S) const;
364  static LabelStmt* CreateImpl(llvm::Deserializer& D);
365};
366
367
368/// IfStmt - This represents an if/then/else.
369///
370class IfStmt : public Stmt {
371  enum { COND, THEN, ELSE, END_EXPR };
372  Stmt* SubExprs[END_EXPR];
373  SourceLocation IfLoc;
374public:
375  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
376    : Stmt(IfStmtClass)  {
377    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
378    SubExprs[THEN] = then;
379    SubExprs[ELSE] = elsev;
380    IfLoc = IL;
381  }
382
383  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
384  const Stmt *getThen() const { return SubExprs[THEN]; }
385  const Stmt *getElse() const { return SubExprs[ELSE]; }
386
387  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
388  Stmt *getThen() { return SubExprs[THEN]; }
389  Stmt *getElse() { return SubExprs[ELSE]; }
390
391  virtual SourceRange getSourceRange() const {
392    if (SubExprs[ELSE])
393      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
394    else
395      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
396  }
397
398  static bool classof(const Stmt *T) {
399    return T->getStmtClass() == IfStmtClass;
400  }
401  static bool classof(const IfStmt *) { return true; }
402
403  // Iterators
404  virtual child_iterator child_begin();
405  virtual child_iterator child_end();
406
407  virtual void EmitImpl(llvm::Serializer& S) const;
408  static IfStmt* CreateImpl(llvm::Deserializer& D);
409};
410
411/// SwitchStmt - This represents a 'switch' stmt.
412///
413class SwitchStmt : public Stmt {
414  enum { COND, BODY, END_EXPR };
415  Stmt* SubExprs[END_EXPR];
416  // This points to a linked list of case and default statements.
417  SwitchCase *FirstCase;
418  SourceLocation SwitchLoc;
419public:
420  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
421      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
422      SubExprs[BODY] = NULL;
423    }
424
425  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
426  const Stmt *getBody() const { return SubExprs[BODY]; }
427  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
428
429  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
430  Stmt *getBody() { return SubExprs[BODY]; }
431  SwitchCase *getSwitchCaseList() { return FirstCase; }
432
433  void setBody(Stmt *S, SourceLocation SL) {
434    SubExprs[BODY] = S;
435    SwitchLoc = SL;
436  }
437  void addSwitchCase(SwitchCase *SC) {
438    if (FirstCase)
439      SC->setNextSwitchCase(FirstCase);
440
441    FirstCase = SC;
442  }
443  virtual SourceRange getSourceRange() const {
444    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
445  }
446  static bool classof(const Stmt *T) {
447    return T->getStmtClass() == SwitchStmtClass;
448  }
449  static bool classof(const SwitchStmt *) { return true; }
450
451  // Iterators
452  virtual child_iterator child_begin();
453  virtual child_iterator child_end();
454
455  virtual void EmitImpl(llvm::Serializer& S) const;
456  static SwitchStmt* CreateImpl(llvm::Deserializer& D);
457};
458
459
460/// WhileStmt - This represents a 'while' stmt.
461///
462class WhileStmt : public Stmt {
463  enum { COND, BODY, END_EXPR };
464  Stmt* SubExprs[END_EXPR];
465  SourceLocation WhileLoc;
466public:
467  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
468    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
469    SubExprs[BODY] = body;
470    WhileLoc = WL;
471  }
472
473  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
474  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
475  Stmt *getBody() { return SubExprs[BODY]; }
476  const Stmt *getBody() const { return SubExprs[BODY]; }
477
478  virtual SourceRange getSourceRange() const {
479    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
480  }
481  static bool classof(const Stmt *T) {
482    return T->getStmtClass() == WhileStmtClass;
483  }
484  static bool classof(const WhileStmt *) { return true; }
485
486  // Iterators
487  virtual child_iterator child_begin();
488  virtual child_iterator child_end();
489
490  virtual void EmitImpl(llvm::Serializer& S) const;
491  static WhileStmt* CreateImpl(llvm::Deserializer& D);
492};
493
494/// DoStmt - This represents a 'do/while' stmt.
495///
496class DoStmt : public Stmt {
497  enum { COND, BODY, END_EXPR };
498  Stmt* SubExprs[END_EXPR];
499  SourceLocation DoLoc;
500public:
501  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
502    : Stmt(DoStmtClass), DoLoc(DL) {
503    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
504    SubExprs[BODY] = body;
505    DoLoc = DL;
506  }
507
508  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
509  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
510  Stmt *getBody() { return SubExprs[BODY]; }
511  const Stmt *getBody() const { return SubExprs[BODY]; }
512
513  virtual SourceRange getSourceRange() const {
514    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
515  }
516  static bool classof(const Stmt *T) {
517    return T->getStmtClass() == DoStmtClass;
518  }
519  static bool classof(const DoStmt *) { return true; }
520
521  // Iterators
522  virtual child_iterator child_begin();
523  virtual child_iterator child_end();
524
525  virtual void EmitImpl(llvm::Serializer& S) const;
526  static DoStmt* CreateImpl(llvm::Deserializer& D);
527};
528
529
530/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
531/// the init/cond/inc parts of the ForStmt will be null if they were not
532/// specified in the source.
533///
534class ForStmt : public Stmt {
535  enum { INIT, COND, INC, BODY, END_EXPR };
536  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
537  SourceLocation ForLoc;
538public:
539  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
540    : Stmt(ForStmtClass) {
541    SubExprs[INIT] = Init;
542    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
543    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
544    SubExprs[BODY] = Body;
545    ForLoc = FL;
546  }
547
548  Stmt *getInit() { return SubExprs[INIT]; }
549  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
550  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
551  Stmt *getBody() { return SubExprs[BODY]; }
552
553  const Stmt *getInit() const { return SubExprs[INIT]; }
554  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
555  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
556  const Stmt *getBody() const { return SubExprs[BODY]; }
557
558  virtual SourceRange getSourceRange() const {
559    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
560  }
561  static bool classof(const Stmt *T) {
562    return T->getStmtClass() == ForStmtClass;
563  }
564  static bool classof(const ForStmt *) { return true; }
565
566  // Iterators
567  virtual child_iterator child_begin();
568  virtual child_iterator child_end();
569
570  virtual void EmitImpl(llvm::Serializer& S) const;
571  static ForStmt* CreateImpl(llvm::Deserializer& D);
572};
573
574/// GotoStmt - This represents a direct goto.
575///
576class GotoStmt : public Stmt {
577  LabelStmt *Label;
578  SourceLocation GotoLoc;
579  SourceLocation LabelLoc;
580public:
581  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
582    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
583
584  LabelStmt *getLabel() const { return Label; }
585
586  virtual SourceRange getSourceRange() const {
587    return SourceRange(GotoLoc, LabelLoc);
588  }
589  static bool classof(const Stmt *T) {
590    return T->getStmtClass() == GotoStmtClass;
591  }
592  static bool classof(const GotoStmt *) { return true; }
593
594  // Iterators
595  virtual child_iterator child_begin();
596  virtual child_iterator child_end();
597
598  virtual void EmitImpl(llvm::Serializer& S) const;
599  static GotoStmt* CreateImpl(llvm::Deserializer& D);
600};
601
602/// IndirectGotoStmt - This represents an indirect goto.
603///
604class IndirectGotoStmt : public Stmt {
605  Expr *Target;
606  // FIXME: Add location information (e.g. SourceLocation objects).
607  //        When doing so, update the serialization routines.
608public:
609  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){}
610
611  Expr *getTarget() { return Target; }
612  const Expr *getTarget() const { return Target; }
613
614  virtual SourceRange getSourceRange() const { return SourceRange(); }
615
616  static bool classof(const Stmt *T) {
617    return T->getStmtClass() == IndirectGotoStmtClass;
618  }
619  static bool classof(const IndirectGotoStmt *) { return true; }
620
621  // Iterators
622  virtual child_iterator child_begin();
623  virtual child_iterator child_end();
624
625  virtual void EmitImpl(llvm::Serializer& S) const;
626  static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D);
627};
628
629
630/// ContinueStmt - This represents a continue.
631///
632class ContinueStmt : public Stmt {
633  SourceLocation ContinueLoc;
634public:
635  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
636
637  virtual SourceRange getSourceRange() const {
638    return SourceRange(ContinueLoc);
639  }
640  static bool classof(const Stmt *T) {
641    return T->getStmtClass() == ContinueStmtClass;
642  }
643  static bool classof(const ContinueStmt *) { return true; }
644
645  // Iterators
646  virtual child_iterator child_begin();
647  virtual child_iterator child_end();
648
649  virtual void EmitImpl(llvm::Serializer& S) const;
650  static ContinueStmt* CreateImpl(llvm::Deserializer& D);
651};
652
653/// BreakStmt - This represents a break.
654///
655class BreakStmt : public Stmt {
656  SourceLocation BreakLoc;
657public:
658  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
659
660  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
661
662  static bool classof(const Stmt *T) {
663    return T->getStmtClass() == BreakStmtClass;
664  }
665  static bool classof(const BreakStmt *) { return true; }
666
667  // Iterators
668  virtual child_iterator child_begin();
669  virtual child_iterator child_end();
670
671  virtual void EmitImpl(llvm::Serializer& S) const;
672  static BreakStmt* CreateImpl(llvm::Deserializer& D);
673};
674
675
676/// ReturnStmt - This represents a return, optionally of an expression.
677///
678class ReturnStmt : public Stmt {
679  Expr *RetExpr;
680  SourceLocation RetLoc;
681public:
682  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
683    RetExpr(E), RetLoc(RL) {}
684
685  const Expr *getRetValue() const { return RetExpr; }
686  Expr *getRetValue() { return RetExpr; }
687
688  virtual SourceRange getSourceRange() const;
689
690  static bool classof(const Stmt *T) {
691    return T->getStmtClass() == ReturnStmtClass;
692  }
693  static bool classof(const ReturnStmt *) { return true; }
694
695  // Iterators
696  virtual child_iterator child_begin();
697  virtual child_iterator child_end();
698
699  virtual void EmitImpl(llvm::Serializer& S) const;
700  static ReturnStmt* CreateImpl(llvm::Deserializer& D);
701};
702
703/// AsmStmt - This represents a GNU inline-assembly statement extension.
704///
705class AsmStmt : public Stmt {
706  SourceLocation AsmLoc, RParenLoc;
707  // FIXME: This doesn't capture most of the interesting pieces.
708public:
709  AsmStmt(SourceLocation asmloc, SourceLocation rparenloc)
710    : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {}
711
712  virtual SourceRange getSourceRange() const {
713    return SourceRange(AsmLoc, RParenLoc);
714  }
715
716  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
717  static bool classof(const AsmStmt *) { return true; }
718
719  virtual child_iterator child_begin();
720  virtual child_iterator child_end();
721
722  virtual void EmitImpl(llvm::Serializer& S) const;
723  static AsmStmt* CreateImpl(llvm::Deserializer& D);
724};
725
726/// ObjcAtCatchStmt - This represents objective-c's @catch statement.
727class ObjcAtCatchStmt : public Stmt {
728private:
729  // Points to next @catch statement, or null
730  ObjcAtCatchStmt *NextAtCatchStmt;
731  enum { SELECTOR, BODY, END_EXPR };
732  Stmt *SubExprs[END_EXPR];
733  SourceLocation AtCatchLoc, RParenLoc;
734
735public:
736  ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
737                  Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList)
738  : Stmt(ObjcAtCatchStmtClass) {
739      SubExprs[SELECTOR] = catchVarStmtDecl;
740      SubExprs[BODY] = atCatchStmt;
741      if (!atCatchList)
742        NextAtCatchStmt = NULL;
743      else {
744        ObjcAtCatchStmt *AtCatchList =
745          static_cast<ObjcAtCatchStmt*>(atCatchList);
746        while (AtCatchList->NextAtCatchStmt)
747          AtCatchList = AtCatchList->NextAtCatchStmt;
748        AtCatchList->NextAtCatchStmt = this;
749      }
750      AtCatchLoc = atCatchLoc;
751      RParenLoc = rparenloc;
752    }
753
754  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
755  Stmt *getCatchBody() { return SubExprs[BODY]; }
756  const ObjcAtCatchStmt *getNextCatchStmt() const { return NextAtCatchStmt; }
757  ObjcAtCatchStmt *getNextCatchStmt() { return NextAtCatchStmt; }
758  const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; }
759  Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; }
760
761  SourceLocation getRParenLoc() const { return RParenLoc; }
762
763  virtual SourceRange getSourceRange() const {
764    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
765  }
766
767  static bool classof(const Stmt *T) {
768    return T->getStmtClass() == ObjcAtCatchStmtClass;
769  }
770  static bool classof(const ObjcAtCatchStmt *) { return true; }
771
772  virtual child_iterator child_begin();
773  virtual child_iterator child_end();
774
775};
776
777/// ObjcAtFinallyStmt - This represent objective-c's @finally Statement
778class ObjcAtFinallyStmt : public Stmt {
779  private:
780    Stmt *AtFinallyStmt;
781    SourceLocation AtFinallyLoc;
782
783  public:
784    ObjcAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
785    : Stmt(ObjcAtFinallyStmtClass),
786      AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
787
788    const Stmt *getFinallyBody () const { return AtFinallyStmt; }
789    Stmt *getFinallyBody () { return AtFinallyStmt; }
790
791    virtual SourceRange getSourceRange() const {
792      return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
793    }
794
795    static bool classof(const Stmt *T) {
796      return T->getStmtClass() == ObjcAtFinallyStmtClass;
797    }
798    static bool classof(const ObjcAtFinallyStmt *) { return true; }
799
800    virtual child_iterator child_begin();
801    virtual child_iterator child_end();
802
803};
804
805/// ObjcAtTryStmt - This represent objective-c's over-all
806/// @try ... @catch ... @finally statement.
807class ObjcAtTryStmt : public Stmt {
808private:
809  enum { TRY, CATCH, FINALLY, END_EXPR };
810  Stmt* SubStmts[END_EXPR];
811
812  SourceLocation AtTryLoc;
813
814public:
815  ObjcAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
816                Stmt *atCatchStmt,
817                Stmt *atFinallyStmt)
818  : Stmt(ObjcAtTryStmtClass) {
819      SubStmts[TRY] = atTryStmt;
820      SubStmts[CATCH] = atCatchStmt;
821      SubStmts[FINALLY] = atFinallyStmt;
822      AtTryLoc = atTryLoc;
823    }
824
825  const Stmt *getTryBody() const { return SubStmts[TRY]; }
826  Stmt *getTryBody() { return SubStmts[TRY]; }
827  const ObjcAtCatchStmt *getCatchStmts() const {
828    return dyn_cast_or_null<ObjcAtCatchStmt>(SubStmts[CATCH]);
829  }
830  ObjcAtCatchStmt *getCatchStmts() {
831    return dyn_cast_or_null<ObjcAtCatchStmt>(SubStmts[CATCH]);
832  }
833  const ObjcAtFinallyStmt *getFinallyStmt() const {
834    return dyn_cast_or_null<ObjcAtFinallyStmt>(SubStmts[FINALLY]);
835  }
836  ObjcAtFinallyStmt *getFinallyStmt() {
837    return dyn_cast_or_null<ObjcAtFinallyStmt>(SubStmts[FINALLY]);
838  }
839  virtual SourceRange getSourceRange() const {
840    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
841  }
842
843  static bool classof(const Stmt *T) {
844    return T->getStmtClass() == ObjcAtTryStmtClass;
845  }
846  static bool classof(const ObjcAtTryStmt *) { return true; }
847
848  virtual child_iterator child_begin();
849  virtual child_iterator child_end();
850
851};
852
853/// ObjcAtThrowStmt - This represents objective-c's @throw statement.
854class ObjcAtThrowStmt : public Stmt {
855private:
856  Stmt *Throw;
857  SourceLocation AtThrowLoc;
858
859public:
860  ObjcAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
861  : Stmt(ObjcAtThrowStmtClass), Throw(throwExpr) {
862    AtThrowLoc = atThrowLoc;
863  }
864
865  Expr *const getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
866
867  virtual SourceRange getSourceRange() const {
868    return SourceRange(AtThrowLoc, Throw->getLocEnd());
869  }
870
871  static bool classof(const Stmt *T) {
872    return T->getStmtClass() == ObjcAtThrowStmtClass;
873  }
874  static bool classof(const ObjcAtThrowStmt *) { return true; }
875
876  virtual child_iterator child_begin();
877  virtual child_iterator child_end();
878};
879
880}  // end namespace clang
881
882#endif
883