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