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