Stmt.h revision 81c018d9482e7cc2addadc6202dcf162a01faefd
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  virtual child_iterator child_begin();
785  virtual child_iterator child_end();
786
787  virtual void EmitImpl(llvm::Serializer& S) const;
788  static AsmStmt* CreateImpl(llvm::Deserializer& D);
789};
790
791/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
792/// represented as 'for (element 'in' collection-expression)' stmt.
793///
794class ObjCForCollectionStmt : public Stmt {
795  enum { ELEM, COLLECTION, BODY, END_EXPR };
796  Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
797  SourceLocation ForLoc;
798  SourceLocation RParenLoc;
799public:
800  ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
801                        SourceLocation FCL, SourceLocation RPL);
802
803  Stmt *getElement() { return SubExprs[ELEM]; }
804  Expr *getCollection() {
805    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
806  }
807  Stmt *getBody() { return SubExprs[BODY]; }
808
809  const Stmt *getElement() const { return SubExprs[ELEM]; }
810  const Expr *getCollection() const {
811    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
812  }
813  const Stmt *getBody() const { return SubExprs[BODY]; }
814
815  SourceLocation getRParenLoc() const { return RParenLoc; }
816
817  virtual SourceRange getSourceRange() const {
818    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
819  }
820  static bool classof(const Stmt *T) {
821    return T->getStmtClass() == ObjCForCollectionStmtClass;
822  }
823  static bool classof(const ObjCForCollectionStmt *) { return true; }
824
825  // Iterators
826  virtual child_iterator child_begin();
827  virtual child_iterator child_end();
828
829  virtual void EmitImpl(llvm::Serializer& S) const;
830  static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D);
831};
832
833/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
834class ObjCAtCatchStmt : public Stmt {
835private:
836  enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR };
837  Stmt *SubExprs[END_EXPR];
838  SourceLocation AtCatchLoc, RParenLoc;
839
840  // Used by deserialization.
841  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc)
842  : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {}
843
844public:
845  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
846                  Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList);
847
848  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
849  Stmt *getCatchBody() { return SubExprs[BODY]; }
850
851  const ObjCAtCatchStmt *getNextCatchStmt() const {
852    return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
853  }
854  ObjCAtCatchStmt *getNextCatchStmt() {
855    return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
856  }
857
858  const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; }
859  Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; }
860
861  SourceLocation getRParenLoc() const { return RParenLoc; }
862
863  virtual SourceRange getSourceRange() const {
864    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
865  }
866
867  bool hasEllipsis() const { return getCatchParamStmt() == 0; }
868
869  static bool classof(const Stmt *T) {
870    return T->getStmtClass() == ObjCAtCatchStmtClass;
871  }
872  static bool classof(const ObjCAtCatchStmt *) { return true; }
873
874  virtual child_iterator child_begin();
875  virtual child_iterator child_end();
876
877  virtual void EmitImpl(llvm::Serializer& S) const;
878  static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D);
879};
880
881/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
882class ObjCAtFinallyStmt : public Stmt {
883  Stmt *AtFinallyStmt;
884  SourceLocation AtFinallyLoc;
885public:
886  ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
887  : Stmt(ObjCAtFinallyStmtClass),
888    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
889
890  const Stmt *getFinallyBody () const { return AtFinallyStmt; }
891  Stmt *getFinallyBody () { return AtFinallyStmt; }
892
893  virtual SourceRange getSourceRange() const {
894    return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
895  }
896
897  static bool classof(const Stmt *T) {
898    return T->getStmtClass() == ObjCAtFinallyStmtClass;
899  }
900  static bool classof(const ObjCAtFinallyStmt *) { return true; }
901
902  virtual child_iterator child_begin();
903  virtual child_iterator child_end();
904
905  virtual void EmitImpl(llvm::Serializer& S) const;
906  static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D);
907};
908
909/// ObjCAtTryStmt - This represent objective-c's over-all
910/// @try ... @catch ... @finally statement.
911class ObjCAtTryStmt : public Stmt {
912private:
913  enum { TRY, CATCH, FINALLY, END_EXPR };
914  Stmt* SubStmts[END_EXPR];
915
916  SourceLocation AtTryLoc;
917public:
918  ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
919                Stmt *atCatchStmt,
920                Stmt *atFinallyStmt)
921  : Stmt(ObjCAtTryStmtClass) {
922      SubStmts[TRY] = atTryStmt;
923      SubStmts[CATCH] = atCatchStmt;
924      SubStmts[FINALLY] = atFinallyStmt;
925      AtTryLoc = atTryLoc;
926    }
927
928  const Stmt *getTryBody() const { return SubStmts[TRY]; }
929  Stmt *getTryBody() { return SubStmts[TRY]; }
930  const ObjCAtCatchStmt *getCatchStmts() const {
931    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
932  }
933  ObjCAtCatchStmt *getCatchStmts() {
934    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
935  }
936  const ObjCAtFinallyStmt *getFinallyStmt() const {
937    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
938  }
939  ObjCAtFinallyStmt *getFinallyStmt() {
940    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
941  }
942  virtual SourceRange getSourceRange() const {
943    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
944  }
945
946  static bool classof(const Stmt *T) {
947    return T->getStmtClass() == ObjCAtTryStmtClass;
948  }
949  static bool classof(const ObjCAtTryStmt *) { return true; }
950
951  virtual child_iterator child_begin();
952  virtual child_iterator child_end();
953
954  virtual void EmitImpl(llvm::Serializer& S) const;
955  static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D);
956};
957
958/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
959/// Example: @synchronized (sem) {
960///             do-something;
961///          }
962///
963class ObjCAtSynchronizedStmt : public Stmt {
964private:
965  enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
966  Stmt* SubStmts[END_EXPR];
967  SourceLocation AtSynchronizedLoc;
968
969public:
970  ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
971                         Stmt *synchBody)
972  : Stmt(ObjCAtSynchronizedStmtClass) {
973      SubStmts[SYNC_EXPR] = synchExpr;
974      SubStmts[SYNC_BODY] = synchBody;
975      AtSynchronizedLoc = atSynchronizedLoc;
976    }
977
978  const CompoundStmt *getSynchBody() const {
979    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
980  }
981  CompoundStmt *getSynchBody() {
982    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
983  }
984
985  const Expr *getSynchExpr() const {
986    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
987  }
988  Expr *getSynchExpr() {
989    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
990  }
991
992  virtual SourceRange getSourceRange() const {
993    return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
994  }
995
996  static bool classof(const Stmt *T) {
997    return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
998  }
999  static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
1000
1001  virtual child_iterator child_begin();
1002  virtual child_iterator child_end();
1003
1004  virtual void EmitImpl(llvm::Serializer& S) const;
1005  static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D);
1006};
1007
1008/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
1009class ObjCAtThrowStmt : public Stmt {
1010  Stmt *Throw;
1011  SourceLocation AtThrowLoc;
1012public:
1013  ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
1014  : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
1015    AtThrowLoc = atThrowLoc;
1016  }
1017
1018  Expr *const getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
1019
1020  virtual SourceRange getSourceRange() const {
1021    if (Throw)
1022      return SourceRange(AtThrowLoc, Throw->getLocEnd());
1023    else
1024      return SourceRange(AtThrowLoc);
1025  }
1026
1027  static bool classof(const Stmt *T) {
1028    return T->getStmtClass() == ObjCAtThrowStmtClass;
1029  }
1030  static bool classof(const ObjCAtThrowStmt *) { return true; }
1031
1032  virtual child_iterator child_begin();
1033  virtual child_iterator child_end();
1034
1035  virtual void EmitImpl(llvm::Serializer& S) const;
1036  static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D);
1037};
1038
1039}  // end namespace clang
1040
1041#endif
1042