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