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