Stmt.h revision 6c36be5b383875b490684bcf439d6d427298c1af
1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//                     The LLVM Compiler Infrastructure
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This file was developed by Chris Lattner and is distributed under
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// the University of Illinois Open Source License. See LICENSE.TXT for details.
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//===----------------------------------------------------------------------===//
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  This file defines the Stmt interface and subclasses.
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//===----------------------------------------------------------------------===//
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef LLVM_CLANG_AST_STMT_H
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define LLVM_CLANG_AST_STMT_H
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "clang/Basic/SourceLocation.h"
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "llvm/ADT/SmallVector.h"
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <iosfwd>
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovnamespace clang {
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  class Expr;
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  class Decl;
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  class IdentifierInfo;
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  class StmtVisitor;
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  class SwitchStmt;
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/// Stmt - This represents one statement.
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov///
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass Stmt {
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  enum StmtClass {
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define STMT(N, CLASS, PARENT) CLASS##Class = N,
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FIRST_STMT(N) firstStmtConstant = N,
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define LAST_STMT(N) lastStmtConstant = N,
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FIRST_EXPR(N) firstExprConstant = N,
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define LAST_EXPR(N) lastExprConstant = N
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "clang/AST/StmtNodes.def"
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovprivate:
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  void dump() const;
57  void print(std::ostream &OS) const;
58
59  // Implement visitor support.
60  virtual void visit(StmtVisitor &Visitor);
61
62  // Implement isa<T> support.
63  static bool classof(const Stmt *) { return true; }
64};
65
66/// DeclStmt - Adaptor class for mixing declarations with statements and
67/// expressions. For example, CompoundStmt mixes statements, expressions
68/// and declarations (variables, types). Another example is ForStmt, where
69/// the first statement can be an expression or a declaration.
70///
71class DeclStmt : public Stmt {
72  Decl *TheDecl;
73public:
74  DeclStmt(Decl *D) : Stmt(DeclStmtClass), TheDecl(D) {}
75
76  const Decl *getDecl() const { return TheDecl; }
77  Decl *getDecl() { return TheDecl; }
78
79  virtual void visit(StmtVisitor &Visitor);
80  static bool classof(const Stmt *T) {
81    return T->getStmtClass() == DeclStmtClass;
82  }
83  static bool classof(const DeclStmt *) { return true; }
84};
85
86/// NullStmt - This is the null statement ";": C99 6.8.3p3.
87///
88class NullStmt : public Stmt {
89  SourceLocation SemiLoc;
90public:
91  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
92
93  SourceLocation getSemiLoc() const { return SemiLoc; }
94
95  virtual void visit(StmtVisitor &Visitor);
96  static bool classof(const Stmt *T) {
97    return T->getStmtClass() == NullStmtClass;
98  }
99  static bool classof(const NullStmt *) { return true; }
100};
101
102/// CompoundStmt - This represents a group of statements like { stmt stmt }.
103///
104class CompoundStmt : public Stmt {
105  llvm::SmallVector<Stmt*, 16> Body;
106public:
107  CompoundStmt(Stmt **StmtStart, unsigned NumStmts)
108    : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts) {}
109
110  typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
111  body_iterator body_begin() { return Body.begin(); }
112  body_iterator body_end() { return Body.end(); }
113
114  typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
115  const_body_iterator body_begin() const { return Body.begin(); }
116  const_body_iterator body_end() const { return Body.end(); }
117
118  void push_back(Stmt *S) { Body.push_back(S); }
119
120  virtual void visit(StmtVisitor &Visitor);
121  static bool classof(const Stmt *T) {
122    return T->getStmtClass() == CompoundStmtClass;
123  }
124  static bool classof(const CompoundStmt *) { return true; }
125};
126
127class CaseStmt : public Stmt {
128  Expr *LHSVal;
129  Expr *RHSVal;  // Non-null for GNU "case 1 ... 4" extension
130  Stmt *SubStmt;
131  SwitchStmt *Switch;
132public:
133  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt)
134    : Stmt(CaseStmtClass), LHSVal(lhs), RHSVal(rhs), SubStmt(substmt),
135    Switch(0) {}
136
137  Expr *getLHS() { return LHSVal; }
138  Expr *getRHS() { return RHSVal; }
139  Stmt *getSubStmt() { return SubStmt; }
140
141  virtual void visit(StmtVisitor &Visitor);
142  static bool classof(const Stmt *T) {
143    return T->getStmtClass() == CaseStmtClass;
144  }
145  static bool classof(const CaseStmt *) { return true; }
146};
147
148class DefaultStmt : public Stmt {
149  SourceLocation DefaultLoc;
150  Stmt *SubStmt;
151public:
152  DefaultStmt(SourceLocation DL, Stmt *substmt) : Stmt(DefaultStmtClass),
153    DefaultLoc(DL), SubStmt(substmt) {}
154
155  SourceLocation getDefaultLoc() const { return DefaultLoc; }
156  Stmt *getSubStmt() { return SubStmt; }
157
158  virtual void visit(StmtVisitor &Visitor);
159  static bool classof(const Stmt *T) {
160    return T->getStmtClass() == DefaultStmtClass;
161  }
162  static bool classof(const DefaultStmt *) { return true; }
163};
164
165class LabelStmt : public Stmt {
166  SourceLocation IdentLoc;
167  IdentifierInfo *Label;
168  Stmt *SubStmt;
169public:
170  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
171    : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {}
172
173  SourceLocation getIdentLoc() const { return IdentLoc; }
174  IdentifierInfo *getID() const { return Label; }
175  const char *getName() const;
176  Stmt *getSubStmt() { return SubStmt; }
177  const Stmt *getSubStmt() const { return SubStmt; }
178
179  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
180  void setSubStmt(Stmt *SS) { SubStmt = SS; }
181
182  virtual void visit(StmtVisitor &Visitor);
183  static bool classof(const Stmt *T) {
184    return T->getStmtClass() == LabelStmtClass;
185  }
186  static bool classof(const LabelStmt *) { return true; }
187};
188
189
190/// IfStmt - This represents an if/then/else.
191///
192class IfStmt : public Stmt {
193  Expr *Cond;
194  Stmt *Then, *Else;
195public:
196  IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0)
197    : Stmt(IfStmtClass), Cond(cond), Then(then), Else(elsev) {}
198
199  const Expr *getCond() const { return Cond; }
200  const Stmt *getThen() const { return Then; }
201  const Stmt *getElse() const { return Else; }
202
203  Expr *getCond() { return Cond; }
204  Stmt *getThen() { return Then; }
205  Stmt *getElse() { return Else; }
206
207  virtual void visit(StmtVisitor &Visitor);
208  static bool classof(const Stmt *T) {
209    return T->getStmtClass() == IfStmtClass;
210  }
211  static bool classof(const IfStmt *) { return true; }
212};
213
214/// SwitchStmt - This represents a 'switch' stmt.
215///
216class SwitchStmt : public Stmt {
217  Expr *Cond;
218  Stmt *Body;
219public:
220  SwitchStmt(Expr *cond, Stmt *body)
221    : Stmt(SwitchStmtClass), Cond(cond), Body(body) {}
222
223  Expr *getCond() { return Cond; }
224  Stmt *getBody() { return Body; }
225
226  virtual void visit(StmtVisitor &Visitor);
227  static bool classof(const Stmt *T) {
228    return T->getStmtClass() == SwitchStmtClass;
229  }
230  static bool classof(const SwitchStmt *) { return true; }
231};
232
233
234/// WhileStmt - This represents a 'while' stmt.
235///
236class WhileStmt : public Stmt {
237  Expr *Cond;
238  Stmt *Body;
239public:
240  WhileStmt(Expr *cond, Stmt *body)
241    : Stmt(WhileStmtClass), Cond(cond), Body(body) {}
242
243  Expr *getCond() { return Cond; }
244  const Expr *getCond() const { return Cond; }
245  Stmt *getBody() { return Body; }
246  const Stmt *getBody() const { return Body; }
247
248  virtual void visit(StmtVisitor &Visitor);
249  static bool classof(const Stmt *T) {
250    return T->getStmtClass() == WhileStmtClass;
251  }
252  static bool classof(const WhileStmt *) { return true; }
253};
254
255/// DoStmt - This represents a 'do/while' stmt.
256///
257class DoStmt : public Stmt {
258  Stmt *Body;
259  Expr *Cond;
260public:
261  DoStmt(Stmt *body, Expr *cond)
262    : Stmt(DoStmtClass), Body(body), Cond(cond) {}
263
264  Stmt *getBody() { return Body; }
265  const Stmt *getBody() const { return Body; }
266  Expr *getCond() { return Cond; }
267  const Expr *getCond() const { return Cond; }
268
269  virtual void visit(StmtVisitor &Visitor);
270  static bool classof(const Stmt *T) {
271    return T->getStmtClass() == DoStmtClass;
272  }
273  static bool classof(const DoStmt *) { return true; }
274};
275
276
277/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
278/// the init/cond/inc parts of the ForStmt will be null if they were not
279/// specified in the source.
280///
281class ForStmt : public Stmt {
282  Stmt *Init;  // Expression or declstmt.
283  Expr *Cond, *Inc;
284  Stmt *Body;
285public:
286  ForStmt(Stmt *init, Expr *cond, Expr *inc, Stmt *body)
287    : Stmt(ForStmtClass), Init(init), Cond(cond), Inc(inc), Body(body) {}
288
289  Stmt *getInit() { return Init; }
290  Expr *getCond() { return Cond; }
291  Expr *getInc()  { return Inc; }
292  Stmt *getBody() { return Body; }
293
294  const Stmt *getInit() const { return Init; }
295  const Expr *getCond() const { return Cond; }
296  const Expr *getInc()  const { return Inc; }
297  const Stmt *getBody() const { return Body; }
298
299  virtual void visit(StmtVisitor &Visitor);
300  static bool classof(const Stmt *T) {
301    return T->getStmtClass() == ForStmtClass;
302  }
303  static bool classof(const ForStmt *) { return true; }
304};
305
306/// GotoStmt - This represents a direct goto.
307///
308class GotoStmt : public Stmt {
309  LabelStmt *Label;
310public:
311  GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {}
312
313  LabelStmt *getLabel() const { return Label; }
314
315  virtual void visit(StmtVisitor &Visitor);
316  static bool classof(const Stmt *T) {
317    return T->getStmtClass() == GotoStmtClass;
318  }
319  static bool classof(const GotoStmt *) { return true; }
320};
321
322/// IndirectGotoStmt - This represents an indirect goto.
323///
324class IndirectGotoStmt : public Stmt {
325  Expr *Target;
326public:
327  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass),
328                                   Target(target) {}
329
330  Expr *getTarget() { return Target; }
331
332  virtual void visit(StmtVisitor &Visitor);
333  static bool classof(const Stmt *T) {
334    return T->getStmtClass() == IndirectGotoStmtClass;
335  }
336  static bool classof(const IndirectGotoStmt *) { return true; }
337};
338
339
340/// ContinueStmt - This represents a continue.
341///
342class ContinueStmt : public Stmt {
343public:
344  ContinueStmt() : Stmt(ContinueStmtClass) {}
345  virtual void visit(StmtVisitor &Visitor);
346  static bool classof(const Stmt *T) {
347    return T->getStmtClass() == ContinueStmtClass;
348  }
349  static bool classof(const ContinueStmt *) { return true; }
350};
351
352/// BreakStmt - This represents a break.
353///
354class BreakStmt : public Stmt {
355public:
356  BreakStmt() : Stmt(BreakStmtClass) {}
357  virtual void visit(StmtVisitor &Visitor);
358  static bool classof(const Stmt *T) {
359    return T->getStmtClass() == BreakStmtClass;
360  }
361  static bool classof(const BreakStmt *) { return true; }
362};
363
364
365/// ReturnStmt - This represents a return, optionally of an expression.
366///
367class ReturnStmt : public Stmt {
368  Expr *RetExpr;
369public:
370  ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {}
371
372  const Expr *getRetValue() const { return RetExpr; }
373  Expr *getRetValue() { return RetExpr; }
374
375  virtual void visit(StmtVisitor &Visitor);
376  static bool classof(const Stmt *T) {
377    return T->getStmtClass() == ReturnStmtClass;
378  }
379  static bool classof(const ReturnStmt *) { return true; }
380};
381
382}  // end namespace clang
383
384#endif
385