Stmt.h revision 6000dace22f110d8768476989313e9d981d690d0
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 <iosfwd>
20
21namespace clang {
22  class Expr;
23  class Decl;
24  class IdentifierInfo;
25  class StmtVisitor;
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 visitor support.
70  virtual void visit(StmtVisitor &Visitor);
71
72  // Implement isa<T> support.
73  static bool classof(const Stmt *) { return true; }
74};
75
76/// DeclStmt - Adaptor class for mixing declarations with statements and
77/// expressions. For example, CompoundStmt mixes statements, expressions
78/// and declarations (variables, types). Another example is ForStmt, where
79/// the first statement can be an expression or a declaration.
80///
81class DeclStmt : public Stmt {
82  Decl *TheDecl;
83public:
84  DeclStmt(Decl *D) : Stmt(DeclStmtClass), TheDecl(D) {}
85
86  const Decl *getDecl() const { return TheDecl; }
87  Decl *getDecl() { return TheDecl; }
88
89  virtual void visit(StmtVisitor &Visitor);
90  static bool classof(const Stmt *T) {
91    return T->getStmtClass() == DeclStmtClass;
92  }
93  static bool classof(const DeclStmt *) { return true; }
94};
95
96/// NullStmt - This is the null statement ";": C99 6.8.3p3.
97///
98class NullStmt : public Stmt {
99  SourceLocation SemiLoc;
100public:
101  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
102
103  SourceLocation getSemiLoc() const { return SemiLoc; }
104
105  virtual void visit(StmtVisitor &Visitor);
106  static bool classof(const Stmt *T) {
107    return T->getStmtClass() == NullStmtClass;
108  }
109  static bool classof(const NullStmt *) { return true; }
110};
111
112/// CompoundStmt - This represents a group of statements like { stmt stmt }.
113///
114class CompoundStmt : public Stmt {
115  llvm::SmallVector<Stmt*, 16> Body;
116public:
117  CompoundStmt(Stmt **StmtStart, unsigned NumStmts)
118    : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts) {}
119
120  bool body_empty() const { return Body.empty(); }
121
122  typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
123  body_iterator body_begin() { return Body.begin(); }
124  body_iterator body_end() { return Body.end(); }
125  Stmt *body_back() { return Body.back(); }
126
127  typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
128  const_body_iterator body_begin() const { return Body.begin(); }
129  const_body_iterator body_end() const { return Body.end(); }
130  const Stmt *body_back() const { return Body.back(); }
131
132  void push_back(Stmt *S) { Body.push_back(S); }
133
134  virtual void visit(StmtVisitor &Visitor);
135  static bool classof(const Stmt *T) {
136    return T->getStmtClass() == CompoundStmtClass;
137  }
138  static bool classof(const CompoundStmt *) { return true; }
139};
140
141// SwitchCase is the base class for CaseStmt and DefaultStmt,
142class SwitchCase : public Stmt {
143  // A pointer to the following CaseStmt or DefaultStmt class,
144  // used by SwitchStmt.
145  SwitchCase *NextSwitchCase;
146protected:
147  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
148
149public:
150  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
151
152  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
153
154  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
155
156  static bool classof(const Stmt *T) {
157    return T->getStmtClass() == CaseStmtClass ||
158    T->getStmtClass() == DefaultStmtClass;
159  }
160  static bool classof(const SwitchCase *) { return true; }
161
162  virtual void visit(StmtVisitor &Visitor) = 0;
163};
164
165class CaseStmt : public SwitchCase {
166  Expr *LHSVal;
167  Expr *RHSVal;  // Non-null for GNU "case 1 ... 4" extension
168  Stmt *SubStmt;
169public:
170  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt)
171    : SwitchCase(CaseStmtClass), LHSVal(lhs), RHSVal(rhs), SubStmt(substmt) {}
172
173  Expr *getLHS() { return LHSVal; }
174  Expr *getRHS() { return RHSVal; }
175  Stmt *getSubStmt() { return SubStmt; }
176
177  virtual void visit(StmtVisitor &Visitor);
178  static bool classof(const Stmt *T) {
179    return T->getStmtClass() == CaseStmtClass;
180  }
181  static bool classof(const CaseStmt *) { return true; }
182};
183
184class DefaultStmt : public SwitchCase {
185  SourceLocation DefaultLoc;
186  Stmt *SubStmt;
187public:
188  DefaultStmt(SourceLocation DL, Stmt *substmt) : SwitchCase(DefaultStmtClass),
189    DefaultLoc(DL), SubStmt(substmt) {}
190
191  SourceLocation getDefaultLoc() const { return DefaultLoc; }
192  Stmt *getSubStmt() { return SubStmt; }
193
194  virtual void visit(StmtVisitor &Visitor);
195  static bool classof(const Stmt *T) {
196    return T->getStmtClass() == DefaultStmtClass;
197  }
198  static bool classof(const DefaultStmt *) { return true; }
199};
200
201class LabelStmt : public Stmt {
202  SourceLocation IdentLoc;
203  IdentifierInfo *Label;
204  Stmt *SubStmt;
205public:
206  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
207    : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {}
208
209  SourceLocation getIdentLoc() const { return IdentLoc; }
210  IdentifierInfo *getID() const { return Label; }
211  const char *getName() const;
212  Stmt *getSubStmt() { return SubStmt; }
213  const Stmt *getSubStmt() const { return SubStmt; }
214
215  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
216  void setSubStmt(Stmt *SS) { SubStmt = SS; }
217
218  virtual void visit(StmtVisitor &Visitor);
219  static bool classof(const Stmt *T) {
220    return T->getStmtClass() == LabelStmtClass;
221  }
222  static bool classof(const LabelStmt *) { return true; }
223};
224
225
226/// IfStmt - This represents an if/then/else.
227///
228class IfStmt : public Stmt {
229  Expr *Cond;
230  Stmt *Then, *Else;
231public:
232  IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0)
233    : Stmt(IfStmtClass), Cond(cond), Then(then), Else(elsev) {}
234
235  const Expr *getCond() const { return Cond; }
236  const Stmt *getThen() const { return Then; }
237  const Stmt *getElse() const { return Else; }
238
239  Expr *getCond() { return Cond; }
240  Stmt *getThen() { return Then; }
241  Stmt *getElse() { return Else; }
242
243  virtual void visit(StmtVisitor &Visitor);
244  static bool classof(const Stmt *T) {
245    return T->getStmtClass() == IfStmtClass;
246  }
247  static bool classof(const IfStmt *) { return true; }
248};
249
250/// SwitchStmt - This represents a 'switch' stmt.
251///
252class SwitchStmt : public Stmt {
253  Expr *Cond;
254  Stmt *Body;
255
256  // This points to a linked list of case and default statements.
257  SwitchCase *FirstCase;
258public:
259  SwitchStmt(Expr *cond)
260    : Stmt(SwitchStmtClass), Cond(cond), Body(0), FirstCase(0) {}
261
262  const Expr *getCond() const { return Cond; }
263  const Stmt *getBody() const { return Body; }
264  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
265
266  Expr *getCond() { return Cond; }
267  Stmt *getBody() { return Body; }
268  SwitchCase *getSwitchCaseList() { return FirstCase; }
269
270  void setBody(Stmt *S) { Body = S; }
271
272  void addSwitchCase(SwitchCase *SC) {
273    if (FirstCase)
274      SC->setNextSwitchCase(FirstCase);
275
276    FirstCase = SC;
277  }
278
279  virtual void visit(StmtVisitor &Visitor);
280  static bool classof(const Stmt *T) {
281    return T->getStmtClass() == SwitchStmtClass;
282  }
283  static bool classof(const SwitchStmt *) { return true; }
284};
285
286
287/// WhileStmt - This represents a 'while' stmt.
288///
289class WhileStmt : public Stmt {
290  Expr *Cond;
291  Stmt *Body;
292public:
293  WhileStmt(Expr *cond, Stmt *body)
294    : Stmt(WhileStmtClass), Cond(cond), Body(body) {}
295
296  Expr *getCond() { return Cond; }
297  const Expr *getCond() const { return Cond; }
298  Stmt *getBody() { return Body; }
299  const Stmt *getBody() const { return Body; }
300
301  virtual void visit(StmtVisitor &Visitor);
302  static bool classof(const Stmt *T) {
303    return T->getStmtClass() == WhileStmtClass;
304  }
305  static bool classof(const WhileStmt *) { return true; }
306};
307
308/// DoStmt - This represents a 'do/while' stmt.
309///
310class DoStmt : public Stmt {
311  Stmt *Body;
312  Expr *Cond;
313public:
314  DoStmt(Stmt *body, Expr *cond)
315    : Stmt(DoStmtClass), Body(body), Cond(cond) {}
316
317  Stmt *getBody() { return Body; }
318  const Stmt *getBody() const { return Body; }
319  Expr *getCond() { return Cond; }
320  const Expr *getCond() const { return Cond; }
321
322  virtual void visit(StmtVisitor &Visitor);
323  static bool classof(const Stmt *T) {
324    return T->getStmtClass() == DoStmtClass;
325  }
326  static bool classof(const DoStmt *) { return true; }
327};
328
329
330/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
331/// the init/cond/inc parts of the ForStmt will be null if they were not
332/// specified in the source.
333///
334class ForStmt : public Stmt {
335  Stmt *Init;  // Expression or declstmt.
336  Expr *Cond, *Inc;
337  Stmt *Body;
338public:
339  ForStmt(Stmt *init, Expr *cond, Expr *inc, Stmt *body)
340    : Stmt(ForStmtClass), Init(init), Cond(cond), Inc(inc), Body(body) {}
341
342  Stmt *getInit() { return Init; }
343  Expr *getCond() { return Cond; }
344  Expr *getInc()  { return Inc; }
345  Stmt *getBody() { return Body; }
346
347  const Stmt *getInit() const { return Init; }
348  const Expr *getCond() const { return Cond; }
349  const Expr *getInc()  const { return Inc; }
350  const Stmt *getBody() const { return Body; }
351
352  virtual void visit(StmtVisitor &Visitor);
353  static bool classof(const Stmt *T) {
354    return T->getStmtClass() == ForStmtClass;
355  }
356  static bool classof(const ForStmt *) { return true; }
357};
358
359/// GotoStmt - This represents a direct goto.
360///
361class GotoStmt : public Stmt {
362  LabelStmt *Label;
363public:
364  GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {}
365
366  LabelStmt *getLabel() const { return Label; }
367
368  virtual void visit(StmtVisitor &Visitor);
369  static bool classof(const Stmt *T) {
370    return T->getStmtClass() == GotoStmtClass;
371  }
372  static bool classof(const GotoStmt *) { return true; }
373};
374
375/// IndirectGotoStmt - This represents an indirect goto.
376///
377class IndirectGotoStmt : public Stmt {
378  Expr *Target;
379public:
380  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){}
381
382  Expr *getTarget() { return Target; }
383  const Expr *getTarget() const { return Target; }
384
385  virtual void visit(StmtVisitor &Visitor);
386  static bool classof(const Stmt *T) {
387    return T->getStmtClass() == IndirectGotoStmtClass;
388  }
389  static bool classof(const IndirectGotoStmt *) { return true; }
390};
391
392
393/// ContinueStmt - This represents a continue.
394///
395class ContinueStmt : public Stmt {
396public:
397  ContinueStmt() : Stmt(ContinueStmtClass) {}
398  virtual void visit(StmtVisitor &Visitor);
399  static bool classof(const Stmt *T) {
400    return T->getStmtClass() == ContinueStmtClass;
401  }
402  static bool classof(const ContinueStmt *) { return true; }
403};
404
405/// BreakStmt - This represents a break.
406///
407class BreakStmt : public Stmt {
408public:
409  BreakStmt() : Stmt(BreakStmtClass) {}
410  virtual void visit(StmtVisitor &Visitor);
411  static bool classof(const Stmt *T) {
412    return T->getStmtClass() == BreakStmtClass;
413  }
414  static bool classof(const BreakStmt *) { return true; }
415};
416
417
418/// ReturnStmt - This represents a return, optionally of an expression.
419///
420class ReturnStmt : public Stmt {
421  Expr *RetExpr;
422public:
423  ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {}
424
425  const Expr *getRetValue() const { return RetExpr; }
426  Expr *getRetValue() { return RetExpr; }
427
428  virtual void visit(StmtVisitor &Visitor);
429  static bool classof(const Stmt *T) {
430    return T->getStmtClass() == ReturnStmtClass;
431  }
432  static bool classof(const ReturnStmt *) { return true; }
433};
434
435}  // end namespace clang
436
437#endif
438