Stmt.h revision 0c727a35718556866a978f64ac549d9798735f08
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(const 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(const 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;
202  Stmt *SubStmt;
203protected:
204  SwitchCase(StmtClass SC, Stmt* substmt) : Stmt(SC), NextSwitchCase(0),
205                                            SubStmt(substmt) {}
206
207public:
208  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
209
210  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
211
212  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
213
214  Stmt *getSubStmt() { return SubStmt; }
215
216  static bool classof(const Stmt *T) {
217    return T->getStmtClass() == CaseStmtClass ||
218    T->getStmtClass() == DefaultStmtClass;
219  }
220  static bool classof(const SwitchCase *) { return true; }
221
222  // Iterators
223  virtual child_iterator child_begin();
224  virtual child_iterator child_end();
225};
226
227class CaseStmt : public SwitchCase {
228  Expr *LHSVal;
229  Expr *RHSVal;  // Non-null for GNU "case 1 ... 4" extension
230public:
231  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt)
232    : SwitchCase(CaseStmtClass,substmt), LHSVal(lhs), RHSVal(rhs) {}
233
234  Expr *getLHS() { return LHSVal; }
235  Expr *getRHS() { return RHSVal; }
236
237  static bool classof(const Stmt *T) {
238    return T->getStmtClass() == CaseStmtClass;
239  }
240  static bool classof(const CaseStmt *) { return true; }
241};
242
243class DefaultStmt : public SwitchCase {
244  SourceLocation DefaultLoc;
245public:
246  DefaultStmt(SourceLocation DL, Stmt *substmt) :
247    SwitchCase(DefaultStmtClass,substmt), DefaultLoc(DL) {}
248
249  SourceLocation getDefaultLoc() const { return DefaultLoc; }
250
251  static bool classof(const Stmt *T) {
252    return T->getStmtClass() == DefaultStmtClass;
253  }
254  static bool classof(const DefaultStmt *) { return true; }
255};
256
257class LabelStmt : public Stmt {
258  SourceLocation IdentLoc;
259  IdentifierInfo *Label;
260  Stmt *SubStmt;
261public:
262  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
263    : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {}
264
265  SourceLocation getIdentLoc() const { return IdentLoc; }
266  IdentifierInfo *getID() const { return Label; }
267  const char *getName() const;
268  Stmt *getSubStmt() { return SubStmt; }
269  const Stmt *getSubStmt() const { return SubStmt; }
270
271  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
272  void setSubStmt(Stmt *SS) { SubStmt = SS; }
273
274  static bool classof(const Stmt *T) {
275    return T->getStmtClass() == LabelStmtClass;
276  }
277  static bool classof(const LabelStmt *) { return true; }
278
279  // Iterators
280  virtual child_iterator child_begin();
281  virtual child_iterator child_end();
282};
283
284
285/// IfStmt - This represents an if/then/else.
286///
287class IfStmt : public Stmt {
288  enum { COND, THEN, ELSE, END_EXPR };
289  Stmt* SubExprs[END_EXPR];
290public:
291  IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0) : Stmt(IfStmtClass)  {
292    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
293    SubExprs[THEN] = then;
294    SubExprs[ELSE] = elsev;
295  }
296
297  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
298  const Stmt *getThen() const { return SubExprs[THEN]; }
299  const Stmt *getElse() const { return SubExprs[ELSE]; }
300
301  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
302  Stmt *getThen() { return SubExprs[THEN]; }
303  Stmt *getElse() { return SubExprs[ELSE]; }
304
305  static bool classof(const Stmt *T) {
306    return T->getStmtClass() == IfStmtClass;
307  }
308  static bool classof(const IfStmt *) { return true; }
309
310  // Iterators
311  virtual child_iterator child_begin();
312  virtual child_iterator child_end();
313};
314
315/// SwitchStmt - This represents a 'switch' stmt.
316///
317class SwitchStmt : public Stmt {
318  enum { COND, BODY, END_EXPR };
319  Stmt* SubExprs[END_EXPR];
320  // This points to a linked list of case and default statements.
321  SwitchCase *FirstCase;
322public:
323  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
324      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
325      SubExprs[BODY] = NULL;
326    }
327
328  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
329  const Stmt *getBody() const { return SubExprs[BODY]; }
330  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
331
332  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
333  Stmt *getBody() { return SubExprs[BODY]; }
334  SwitchCase *getSwitchCaseList() { return FirstCase; }
335
336  void setBody(Stmt *S) { SubExprs[BODY] = S; }
337
338  void addSwitchCase(SwitchCase *SC) {
339    if (FirstCase)
340      SC->setNextSwitchCase(FirstCase);
341
342    FirstCase = SC;
343  }
344
345  static bool classof(const Stmt *T) {
346    return T->getStmtClass() == SwitchStmtClass;
347  }
348  static bool classof(const SwitchStmt *) { return true; }
349
350  // Iterators
351  virtual child_iterator child_begin();
352  virtual child_iterator child_end();
353};
354
355
356/// WhileStmt - This represents a 'while' stmt.
357///
358class WhileStmt : public Stmt {
359  enum { COND, BODY, END_EXPR };
360  Stmt* SubExprs[END_EXPR];
361public:
362  WhileStmt(Expr *cond, Stmt *body) : Stmt(WhileStmtClass) {
363    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
364    SubExprs[BODY] = body;
365  }
366
367  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
368  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
369  Stmt *getBody() { return SubExprs[BODY]; }
370  const Stmt *getBody() const { return SubExprs[BODY]; }
371
372  static bool classof(const Stmt *T) {
373    return T->getStmtClass() == WhileStmtClass;
374  }
375  static bool classof(const WhileStmt *) { return true; }
376
377  // Iterators
378  virtual child_iterator child_begin();
379  virtual child_iterator child_end();
380};
381
382/// DoStmt - This represents a 'do/while' stmt.
383///
384class DoStmt : public Stmt {
385  enum { COND, BODY, END_EXPR };
386  Stmt* SubExprs[END_EXPR];
387public:
388  DoStmt(Stmt *body, Expr *cond) : Stmt(DoStmtClass) {
389    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
390    SubExprs[BODY] = body;
391  }
392
393  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
394  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
395  Stmt *getBody() { return SubExprs[BODY]; }
396  const Stmt *getBody() const { return SubExprs[BODY]; }
397
398  static bool classof(const Stmt *T) {
399    return T->getStmtClass() == DoStmtClass;
400  }
401  static bool classof(const DoStmt *) { return true; }
402
403  // Iterators
404  virtual child_iterator child_begin();
405  virtual child_iterator child_end();
406};
407
408
409/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
410/// the init/cond/inc parts of the ForStmt will be null if they were not
411/// specified in the source.
412///
413class ForStmt : public Stmt {
414  enum { INIT, COND, INC, BODY, END_EXPR };
415  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
416public:
417  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body) : Stmt(ForStmtClass) {
418    SubExprs[INIT] = Init;
419    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
420    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
421    SubExprs[BODY] = Body;
422  }
423
424  Stmt *getInit() { return SubExprs[INIT]; }
425  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
426  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
427  Stmt *getBody() { return SubExprs[BODY]; }
428
429  const Stmt *getInit() const { return SubExprs[INIT]; }
430  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
431  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
432  const Stmt *getBody() const { return SubExprs[BODY]; }
433
434  static bool classof(const Stmt *T) {
435    return T->getStmtClass() == ForStmtClass;
436  }
437  static bool classof(const ForStmt *) { return true; }
438
439  // Iterators
440  virtual child_iterator child_begin();
441  virtual child_iterator child_end();
442};
443
444/// GotoStmt - This represents a direct goto.
445///
446class GotoStmt : public Stmt {
447  LabelStmt *Label;
448public:
449  GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {}
450
451  LabelStmt *getLabel() const { return Label; }
452
453  static bool classof(const Stmt *T) {
454    return T->getStmtClass() == GotoStmtClass;
455  }
456  static bool classof(const GotoStmt *) { return true; }
457
458  // Iterators
459  virtual child_iterator child_begin();
460  virtual child_iterator child_end();
461};
462
463/// IndirectGotoStmt - This represents an indirect goto.
464///
465class IndirectGotoStmt : public Stmt {
466  Expr *Target;
467public:
468  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){}
469
470  Expr *getTarget() { return Target; }
471  const Expr *getTarget() const { return Target; }
472
473  static bool classof(const Stmt *T) {
474    return T->getStmtClass() == IndirectGotoStmtClass;
475  }
476  static bool classof(const IndirectGotoStmt *) { return true; }
477
478  // Iterators
479  virtual child_iterator child_begin();
480  virtual child_iterator child_end();
481};
482
483
484/// ContinueStmt - This represents a continue.
485///
486class ContinueStmt : public Stmt {
487public:
488  ContinueStmt() : Stmt(ContinueStmtClass) {}
489  static bool classof(const Stmt *T) {
490    return T->getStmtClass() == ContinueStmtClass;
491  }
492  static bool classof(const ContinueStmt *) { return true; }
493
494  // Iterators
495  virtual child_iterator child_begin();
496  virtual child_iterator child_end();
497};
498
499/// BreakStmt - This represents a break.
500///
501class BreakStmt : public Stmt {
502public:
503  BreakStmt() : Stmt(BreakStmtClass) {}
504  static bool classof(const Stmt *T) {
505    return T->getStmtClass() == BreakStmtClass;
506  }
507  static bool classof(const BreakStmt *) { return true; }
508
509  // Iterators
510  virtual child_iterator child_begin();
511  virtual child_iterator child_end();
512};
513
514
515/// ReturnStmt - This represents a return, optionally of an expression.
516///
517class ReturnStmt : public Stmt {
518  Expr *RetExpr;
519public:
520  ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {}
521
522  const Expr *getRetValue() const { return RetExpr; }
523  Expr *getRetValue() { return RetExpr; }
524
525  static bool classof(const Stmt *T) {
526    return T->getStmtClass() == ReturnStmtClass;
527  }
528  static bool classof(const ReturnStmt *) { return true; }
529
530  // Iterators
531  virtual child_iterator child_begin();
532  virtual child_iterator child_end();
533};
534
535}  // end namespace clang
536
537#endif
538