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