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