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