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