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