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