Stmt.h revision d97bb6c1384cb773ba5cdbd198008dec127cebad
1//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the Stmt interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_STMT_H
15#define LLVM_CLANG_AST_STMT_H
16
17#include "clang/Basic/SourceLocation.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/iterator"
20#include <iosfwd>
21
22namespace clang {
23  class Expr;
24  class Decl;
25  class IdentifierInfo;
26  class SourceManager;
27  class SwitchStmt;
28
29/// Stmt - This represents one statement.
30///
31class Stmt {
32public:
33  enum StmtClass {
34#define STMT(N, CLASS, PARENT) CLASS##Class = N,
35#define FIRST_STMT(N) firstStmtConstant = N,
36#define LAST_STMT(N) lastStmtConstant = N,
37#define FIRST_EXPR(N) firstExprConstant = N,
38#define LAST_EXPR(N) lastExprConstant = N
39#include "clang/AST/StmtNodes.def"
40};
41private:
42  const StmtClass sClass;
43public:
44  Stmt(StmtClass SC) : sClass(SC) {
45    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
46  }
47  virtual ~Stmt() {}
48
49  StmtClass getStmtClass() const { return sClass; }
50  const char *getStmtClassName() const;
51
52  // global temp stats (until we have a per-module visitor)
53  static void addStmtClass(const StmtClass s);
54  static bool CollectingStats(bool enable=false);
55  static void PrintStats();
56
57  /// dump - This does a local dump of the specified AST fragment.  It dumps the
58  /// specified node and a few nodes underneath it, but not the whole subtree.
59  /// This is useful in a debugger.
60  void dump() const;
61  void dump(SourceManager &SM) const;
62
63  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
64  void dumpAll() const;
65  void dumpAll(SourceManager &SM) const;
66
67  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
68  /// back to its original source language syntax.
69  void dumpPretty() const;
70  void printPretty(std::ostream &OS) const;
71
72  // Implement isa<T> support.
73  static bool classof(const Stmt *) { return true; }
74
75  /// Child Iterators: All subclasses must implement child_begin and child_end
76  ///  to permit easy iteration over the substatements/subexpessions of an
77  ///  AST node.  This permits easy iteration over all nodes in the AST.
78  typedef Stmt**                                               child_iterator;
79  typedef Stmt* const *                                  const_child_iterator;
80
81  typedef std::reverse_iterator<child_iterator>
82  reverse_child_iterator;
83  typedef std::reverse_iterator<const_child_iterator>
84  const_reverse_child_iterator;
85
86  virtual child_iterator child_begin() = 0;
87  virtual child_iterator child_end()   = 0;
88
89  const_child_iterator child_begin() const {
90    return (child_iterator) const_cast<Stmt*>(this)->child_begin();
91  }
92
93  const_child_iterator child_end() const {
94    return (child_iterator) const_cast<Stmt*>(this)->child_end();
95  }
96
97  reverse_child_iterator child_rbegin() {
98    return reverse_child_iterator(child_end());
99  }
100
101  reverse_child_iterator child_rend() {
102    return reverse_child_iterator(child_begin());
103  }
104
105  const_reverse_child_iterator child_rbegin() const {
106    return const_reverse_child_iterator(child_end());
107  }
108
109  const_reverse_child_iterator child_rend() const {
110    return const_reverse_child_iterator(child_begin());
111  }
112};
113
114/// DeclStmt - Adaptor class for mixing declarations with statements and
115/// expressions. For example, CompoundStmt mixes statements, expressions
116/// and declarations (variables, types). Another example is ForStmt, where
117/// the first statement can be an expression or a declaration.
118///
119class DeclStmt : public Stmt {
120  Decl *TheDecl;
121public:
122  DeclStmt(Decl *D) : Stmt(DeclStmtClass), TheDecl(D) {}
123
124  const Decl *getDecl() const { return TheDecl; }
125  Decl *getDecl() { return TheDecl; }
126
127  static bool classof(const Stmt *T) {
128    return T->getStmtClass() == DeclStmtClass;
129  }
130  static bool classof(const DeclStmt *) { return true; }
131
132  // Iterators
133  virtual child_iterator child_begin();
134  virtual child_iterator child_end();
135};
136
137/// NullStmt - This is the null statement ";": C99 6.8.3p3.
138///
139class NullStmt : public Stmt {
140  SourceLocation SemiLoc;
141public:
142  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
143
144  SourceLocation getSemiLoc() const { return SemiLoc; }
145
146  static bool classof(const Stmt *T) {
147    return T->getStmtClass() == NullStmtClass;
148  }
149  static bool classof(const NullStmt *) { return true; }
150
151  // Iterators
152  virtual child_iterator child_begin();
153  virtual child_iterator child_end();
154};
155
156/// CompoundStmt - This represents a group of statements like { stmt stmt }.
157///
158class CompoundStmt : public Stmt {
159  llvm::SmallVector<Stmt*, 16> Body;
160public:
161  CompoundStmt(Stmt **StmtStart, unsigned NumStmts)
162    : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts) {}
163
164  bool body_empty() const { return Body.empty(); }
165
166  typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
167  body_iterator body_begin() { return Body.begin(); }
168  body_iterator body_end() { return Body.end(); }
169  Stmt *body_back() { return Body.back(); }
170
171  typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
172  const_body_iterator body_begin() const { return Body.begin(); }
173  const_body_iterator body_end() const { return Body.end(); }
174  const Stmt *body_back() const { return Body.back(); }
175
176  typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator;
177  reverse_body_iterator body_rbegin() { return Body.rbegin(); }
178  reverse_body_iterator body_rend() { return Body.rend(); }
179
180  typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator
181    const_reverse_body_iterator;
182  const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); }
183  const_reverse_body_iterator body_rend() const { return Body.rend(); }
184
185  void push_back(Stmt *S) { Body.push_back(S); }
186
187  static bool classof(const Stmt *T) {
188    return T->getStmtClass() == CompoundStmtClass;
189  }
190  static bool classof(const CompoundStmt *) { return true; }
191
192  // Iterators
193  virtual child_iterator child_begin();
194  virtual child_iterator child_end();
195};
196
197// SwitchCase is the base class for CaseStmt and DefaultStmt,
198class SwitchCase : public Stmt {
199  // A pointer to the following CaseStmt or DefaultStmt class,
200  // used by SwitchStmt.
201  SwitchCase *NextSwitchCase;
202protected:
203  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
204
205public:
206  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
207
208  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
209
210  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
211
212  virtual Stmt* v_getSubStmt() = 0;
213  Stmt *getSubStmt() { return v_getSubStmt(); }
214
215  static bool classof(const Stmt *T) {
216    return T->getStmtClass() == CaseStmtClass ||
217    T->getStmtClass() == DefaultStmtClass;
218  }
219  static bool classof(const SwitchCase *) { return true; }
220};
221
222class CaseStmt : public SwitchCase {
223  enum { SUBSTMT, LHS, RHS, END_EXPR };
224  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
225                             // GNU "case 1 ... 4" extension
226public:
227  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt)
228    : SwitchCase(CaseStmtClass) {
229    SubExprs[SUBSTMT] = substmt;
230    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
231    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
232  }
233
234  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
235  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
236  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
237  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
238
239  static bool classof(const Stmt *T) {
240    return T->getStmtClass() == CaseStmtClass;
241  }
242  static bool classof(const CaseStmt *) { return true; }
243
244  // Iterators
245  virtual child_iterator child_begin();
246  virtual child_iterator child_end();
247};
248
249class DefaultStmt : public SwitchCase {
250  Stmt* SubStmt;
251  SourceLocation DefaultLoc;
252public:
253  DefaultStmt(SourceLocation DL, Stmt *substmt) :
254    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
255
256  Stmt *getSubStmt() { return SubStmt; }
257  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
258
259  SourceLocation getDefaultLoc() const { return DefaultLoc; }
260
261  static bool classof(const Stmt *T) {
262    return T->getStmtClass() == DefaultStmtClass;
263  }
264  static bool classof(const DefaultStmt *) { return true; }
265
266  // Iterators
267  virtual child_iterator child_begin();
268  virtual child_iterator child_end();
269};
270
271class LabelStmt : public Stmt {
272  SourceLocation IdentLoc;
273  IdentifierInfo *Label;
274  Stmt *SubStmt;
275public:
276  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
277    : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {}
278
279  SourceLocation getIdentLoc() const { return IdentLoc; }
280  IdentifierInfo *getID() const { return Label; }
281  const char *getName() const;
282  Stmt *getSubStmt() { return SubStmt; }
283  const Stmt *getSubStmt() const { return SubStmt; }
284
285  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
286  void setSubStmt(Stmt *SS) { SubStmt = SS; }
287
288  static bool classof(const Stmt *T) {
289    return T->getStmtClass() == LabelStmtClass;
290  }
291  static bool classof(const LabelStmt *) { return true; }
292
293  // Iterators
294  virtual child_iterator child_begin();
295  virtual child_iterator child_end();
296};
297
298
299/// IfStmt - This represents an if/then/else.
300///
301class IfStmt : public Stmt {
302  enum { COND, THEN, ELSE, END_EXPR };
303  Stmt* SubExprs[END_EXPR];
304public:
305  IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0) : Stmt(IfStmtClass)  {
306    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
307    SubExprs[THEN] = then;
308    SubExprs[ELSE] = elsev;
309  }
310
311  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
312  const Stmt *getThen() const { return SubExprs[THEN]; }
313  const Stmt *getElse() const { return SubExprs[ELSE]; }
314
315  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
316  Stmt *getThen() { return SubExprs[THEN]; }
317  Stmt *getElse() { return SubExprs[ELSE]; }
318
319  static bool classof(const Stmt *T) {
320    return T->getStmtClass() == IfStmtClass;
321  }
322  static bool classof(const IfStmt *) { return true; }
323
324  // Iterators
325  virtual child_iterator child_begin();
326  virtual child_iterator child_end();
327};
328
329/// SwitchStmt - This represents a 'switch' stmt.
330///
331class SwitchStmt : public Stmt {
332  enum { COND, BODY, END_EXPR };
333  Stmt* SubExprs[END_EXPR];
334  // This points to a linked list of case and default statements.
335  SwitchCase *FirstCase;
336public:
337  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
338      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
339      SubExprs[BODY] = NULL;
340    }
341
342  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
343  const Stmt *getBody() const { return SubExprs[BODY]; }
344  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
345
346  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
347  Stmt *getBody() { return SubExprs[BODY]; }
348  SwitchCase *getSwitchCaseList() { return FirstCase; }
349
350  void setBody(Stmt *S) { SubExprs[BODY] = S; }
351
352  void addSwitchCase(SwitchCase *SC) {
353    if (FirstCase)
354      SC->setNextSwitchCase(FirstCase);
355
356    FirstCase = SC;
357  }
358
359  static bool classof(const Stmt *T) {
360    return T->getStmtClass() == SwitchStmtClass;
361  }
362  static bool classof(const SwitchStmt *) { return true; }
363
364  // Iterators
365  virtual child_iterator child_begin();
366  virtual child_iterator child_end();
367};
368
369
370/// WhileStmt - This represents a 'while' stmt.
371///
372class WhileStmt : public Stmt {
373  enum { COND, BODY, END_EXPR };
374  Stmt* SubExprs[END_EXPR];
375public:
376  WhileStmt(Expr *cond, Stmt *body) : Stmt(WhileStmtClass) {
377    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
378    SubExprs[BODY] = body;
379  }
380
381  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
382  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
383  Stmt *getBody() { return SubExprs[BODY]; }
384  const Stmt *getBody() const { return SubExprs[BODY]; }
385
386  static bool classof(const Stmt *T) {
387    return T->getStmtClass() == WhileStmtClass;
388  }
389  static bool classof(const WhileStmt *) { return true; }
390
391  // Iterators
392  virtual child_iterator child_begin();
393  virtual child_iterator child_end();
394};
395
396/// DoStmt - This represents a 'do/while' stmt.
397///
398class DoStmt : public Stmt {
399  enum { COND, BODY, END_EXPR };
400  Stmt* SubExprs[END_EXPR];
401public:
402  DoStmt(Stmt *body, Expr *cond) : Stmt(DoStmtClass) {
403    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
404    SubExprs[BODY] = body;
405  }
406
407  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
408  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
409  Stmt *getBody() { return SubExprs[BODY]; }
410  const Stmt *getBody() const { return SubExprs[BODY]; }
411
412  static bool classof(const Stmt *T) {
413    return T->getStmtClass() == DoStmtClass;
414  }
415  static bool classof(const DoStmt *) { return true; }
416
417  // Iterators
418  virtual child_iterator child_begin();
419  virtual child_iterator child_end();
420};
421
422
423/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
424/// the init/cond/inc parts of the ForStmt will be null if they were not
425/// specified in the source.
426///
427class ForStmt : public Stmt {
428  enum { INIT, COND, INC, BODY, END_EXPR };
429  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
430public:
431  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body) : Stmt(ForStmtClass) {
432    SubExprs[INIT] = Init;
433    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
434    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
435    SubExprs[BODY] = Body;
436  }
437
438  Stmt *getInit() { return SubExprs[INIT]; }
439  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
440  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
441  Stmt *getBody() { return SubExprs[BODY]; }
442
443  const Stmt *getInit() const { return SubExprs[INIT]; }
444  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
445  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
446  const Stmt *getBody() const { return SubExprs[BODY]; }
447
448  static bool classof(const Stmt *T) {
449    return T->getStmtClass() == ForStmtClass;
450  }
451  static bool classof(const ForStmt *) { return true; }
452
453  // Iterators
454  virtual child_iterator child_begin();
455  virtual child_iterator child_end();
456};
457
458/// GotoStmt - This represents a direct goto.
459///
460class GotoStmt : public Stmt {
461  LabelStmt *Label;
462public:
463  GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {}
464
465  LabelStmt *getLabel() const { return Label; }
466
467  static bool classof(const Stmt *T) {
468    return T->getStmtClass() == GotoStmtClass;
469  }
470  static bool classof(const GotoStmt *) { return true; }
471
472  // Iterators
473  virtual child_iterator child_begin();
474  virtual child_iterator child_end();
475};
476
477/// IndirectGotoStmt - This represents an indirect goto.
478///
479class IndirectGotoStmt : public Stmt {
480  Expr *Target;
481public:
482  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){}
483
484  Expr *getTarget() { return Target; }
485  const Expr *getTarget() const { return Target; }
486
487  static bool classof(const Stmt *T) {
488    return T->getStmtClass() == IndirectGotoStmtClass;
489  }
490  static bool classof(const IndirectGotoStmt *) { return true; }
491
492  // Iterators
493  virtual child_iterator child_begin();
494  virtual child_iterator child_end();
495};
496
497
498/// ContinueStmt - This represents a continue.
499///
500class ContinueStmt : public Stmt {
501public:
502  ContinueStmt() : Stmt(ContinueStmtClass) {}
503  static bool classof(const Stmt *T) {
504    return T->getStmtClass() == ContinueStmtClass;
505  }
506  static bool classof(const ContinueStmt *) { return true; }
507
508  // Iterators
509  virtual child_iterator child_begin();
510  virtual child_iterator child_end();
511};
512
513/// BreakStmt - This represents a break.
514///
515class BreakStmt : public Stmt {
516public:
517  BreakStmt() : Stmt(BreakStmtClass) {}
518  static bool classof(const Stmt *T) {
519    return T->getStmtClass() == BreakStmtClass;
520  }
521  static bool classof(const BreakStmt *) { return true; }
522
523  // Iterators
524  virtual child_iterator child_begin();
525  virtual child_iterator child_end();
526};
527
528
529/// ReturnStmt - This represents a return, optionally of an expression.
530///
531class ReturnStmt : public Stmt {
532  Expr *RetExpr;
533public:
534  ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {}
535
536  const Expr *getRetValue() const { return RetExpr; }
537  Expr *getRetValue() { return RetExpr; }
538
539  static bool classof(const Stmt *T) {
540    return T->getStmtClass() == ReturnStmtClass;
541  }
542  static bool classof(const ReturnStmt *) { return true; }
543
544  // Iterators
545  virtual child_iterator child_begin();
546  virtual child_iterator child_end();
547};
548
549}  // end namespace clang
550
551#endif
552