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