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