Stmt.h revision 42a509f6a4f71bb805cc4abbb26722a34dffddde
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 "llvm/ADT/iterator" 20#include <iosfwd> 21 22namespace clang { 23 class Expr; 24 class Decl; 25 class IdentifierInfo; 26 class SourceManager; 27 class SwitchStmt; 28 class PrinterHelper; 29 30/// Stmt - This represents one statement. 31/// 32class Stmt { 33public: 34 enum StmtClass { 35#define STMT(N, CLASS, PARENT) CLASS##Class = N, 36#define FIRST_STMT(N) firstStmtConstant = N, 37#define LAST_STMT(N) lastStmtConstant = N, 38#define FIRST_EXPR(N) firstExprConstant = N, 39#define LAST_EXPR(N) lastExprConstant = N 40#include "clang/AST/StmtNodes.def" 41}; 42private: 43 const StmtClass sClass; 44public: 45 Stmt(StmtClass SC) : sClass(SC) { 46 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 47 } 48 virtual ~Stmt() {} 49 50 StmtClass getStmtClass() const { return sClass; } 51 const char *getStmtClassName() const; 52 53 // global temp stats (until we have a per-module visitor) 54 static void addStmtClass(const StmtClass s); 55 static bool CollectingStats(bool enable=false); 56 static void PrintStats(); 57 58 /// dump - This does a local dump of the specified AST fragment. It dumps the 59 /// specified node and a few nodes underneath it, but not the whole subtree. 60 /// This is useful in a debugger. 61 void dump() const; 62 void dump(SourceManager &SM) const; 63 64 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 65 void dumpAll() const; 66 void dumpAll(SourceManager &SM) const; 67 68 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 69 /// back to its original source language syntax. 70 void dumpPretty() const; 71 void printPretty(std::ostream &OS, PrinterHelper* = NULL) const; 72 73 // Implement isa<T> support. 74 static bool classof(const Stmt *) { return true; } 75 76 /// Child Iterators: All subclasses must implement child_begin and child_end 77 /// to permit easy iteration over the substatements/subexpessions of an 78 /// AST node. This permits easy iteration over all nodes in the AST. 79 typedef Stmt** child_iterator; 80 typedef Stmt* const * const_child_iterator; 81 82 typedef std::reverse_iterator<child_iterator> 83 reverse_child_iterator; 84 typedef std::reverse_iterator<const_child_iterator> 85 const_reverse_child_iterator; 86 87 virtual child_iterator child_begin() = 0; 88 virtual child_iterator child_end() = 0; 89 90 const_child_iterator child_begin() const { 91 return (child_iterator) const_cast<Stmt*>(this)->child_begin(); 92 } 93 94 const_child_iterator child_end() const { 95 return (child_iterator) const_cast<Stmt*>(this)->child_end(); 96 } 97 98 reverse_child_iterator child_rbegin() { 99 return reverse_child_iterator(child_end()); 100 } 101 102 reverse_child_iterator child_rend() { 103 return reverse_child_iterator(child_begin()); 104 } 105 106 const_reverse_child_iterator child_rbegin() const { 107 return const_reverse_child_iterator(child_end()); 108 } 109 110 const_reverse_child_iterator child_rend() const { 111 return const_reverse_child_iterator(child_begin()); 112 } 113}; 114 115/// DeclStmt - Adaptor class for mixing declarations with statements and 116/// expressions. For example, CompoundStmt mixes statements, expressions 117/// and declarations (variables, types). Another example is ForStmt, where 118/// the first statement can be an expression or a declaration. 119/// 120class DeclStmt : public Stmt { 121 Decl *TheDecl; 122public: 123 DeclStmt(Decl *D) : Stmt(DeclStmtClass), TheDecl(D) {} 124 125 const Decl *getDecl() const { return TheDecl; } 126 Decl *getDecl() { return TheDecl; } 127 128 static bool classof(const Stmt *T) { 129 return T->getStmtClass() == DeclStmtClass; 130 } 131 static bool classof(const DeclStmt *) { return true; } 132 133 // Iterators 134 virtual child_iterator child_begin(); 135 virtual child_iterator child_end(); 136}; 137 138/// NullStmt - This is the null statement ";": C99 6.8.3p3. 139/// 140class NullStmt : public Stmt { 141 SourceLocation SemiLoc; 142public: 143 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 144 145 SourceLocation getSemiLoc() const { return SemiLoc; } 146 147 static bool classof(const Stmt *T) { 148 return T->getStmtClass() == NullStmtClass; 149 } 150 static bool classof(const NullStmt *) { return true; } 151 152 // Iterators 153 virtual child_iterator child_begin(); 154 virtual child_iterator child_end(); 155}; 156 157/// CompoundStmt - This represents a group of statements like { stmt stmt }. 158/// 159class CompoundStmt : public Stmt { 160 llvm::SmallVector<Stmt*, 16> Body; 161public: 162 CompoundStmt(Stmt **StmtStart, unsigned NumStmts) 163 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts) {} 164 165 bool body_empty() const { return Body.empty(); } 166 167 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 168 body_iterator body_begin() { return Body.begin(); } 169 body_iterator body_end() { return Body.end(); } 170 Stmt *body_back() { return Body.back(); } 171 172 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 173 const_body_iterator body_begin() const { return Body.begin(); } 174 const_body_iterator body_end() const { return Body.end(); } 175 const Stmt *body_back() const { return Body.back(); } 176 177 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 178 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 179 reverse_body_iterator body_rend() { return Body.rend(); } 180 181 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 182 const_reverse_body_iterator; 183 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 184 const_reverse_body_iterator body_rend() const { return Body.rend(); } 185 186 void push_back(Stmt *S) { Body.push_back(S); } 187 188 static bool classof(const Stmt *T) { 189 return T->getStmtClass() == CompoundStmtClass; 190 } 191 static bool classof(const CompoundStmt *) { return true; } 192 193 // Iterators 194 virtual child_iterator child_begin(); 195 virtual child_iterator child_end(); 196}; 197 198// SwitchCase is the base class for CaseStmt and DefaultStmt, 199class SwitchCase : public Stmt { 200 // A pointer to the following CaseStmt or DefaultStmt class, 201 // used by SwitchStmt. 202 SwitchCase *NextSwitchCase; 203protected: 204 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 205 206public: 207 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 208 209 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 210 211 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 212 213 virtual Stmt* v_getSubStmt() = 0; 214 Stmt *getSubStmt() { return v_getSubStmt(); } 215 216 static bool classof(const Stmt *T) { 217 return T->getStmtClass() == CaseStmtClass || 218 T->getStmtClass() == DefaultStmtClass; 219 } 220 static bool classof(const SwitchCase *) { return true; } 221}; 222 223class CaseStmt : public SwitchCase { 224 enum { SUBSTMT, LHS, RHS, END_EXPR }; 225 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 226 // GNU "case 1 ... 4" extension 227public: 228 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt) 229 : SwitchCase(CaseStmtClass) { 230 SubExprs[SUBSTMT] = substmt; 231 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 232 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 233 } 234 235 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 236 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 237 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 238 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 239 240 static bool classof(const Stmt *T) { 241 return T->getStmtClass() == CaseStmtClass; 242 } 243 static bool classof(const CaseStmt *) { return true; } 244 245 // Iterators 246 virtual child_iterator child_begin(); 247 virtual child_iterator child_end(); 248}; 249 250class DefaultStmt : public SwitchCase { 251 Stmt* SubStmt; 252 SourceLocation DefaultLoc; 253public: 254 DefaultStmt(SourceLocation DL, Stmt *substmt) : 255 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 256 257 Stmt *getSubStmt() { return SubStmt; } 258 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 259 260 SourceLocation getDefaultLoc() const { return DefaultLoc; } 261 262 static bool classof(const Stmt *T) { 263 return T->getStmtClass() == DefaultStmtClass; 264 } 265 static bool classof(const DefaultStmt *) { return true; } 266 267 // Iterators 268 virtual child_iterator child_begin(); 269 virtual child_iterator child_end(); 270}; 271 272class LabelStmt : public Stmt { 273 SourceLocation IdentLoc; 274 IdentifierInfo *Label; 275 Stmt *SubStmt; 276public: 277 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 278 : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {} 279 280 SourceLocation getIdentLoc() const { return IdentLoc; } 281 IdentifierInfo *getID() const { return Label; } 282 const char *getName() const; 283 Stmt *getSubStmt() { return SubStmt; } 284 const Stmt *getSubStmt() const { return SubStmt; } 285 286 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 287 void setSubStmt(Stmt *SS) { SubStmt = SS; } 288 289 static bool classof(const Stmt *T) { 290 return T->getStmtClass() == LabelStmtClass; 291 } 292 static bool classof(const LabelStmt *) { return true; } 293 294 // Iterators 295 virtual child_iterator child_begin(); 296 virtual child_iterator child_end(); 297}; 298 299 300/// IfStmt - This represents an if/then/else. 301/// 302class IfStmt : public Stmt { 303 enum { COND, THEN, ELSE, END_EXPR }; 304 Stmt* SubExprs[END_EXPR]; 305public: 306 IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0) : Stmt(IfStmtClass) { 307 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 308 SubExprs[THEN] = then; 309 SubExprs[ELSE] = elsev; 310 } 311 312 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 313 const Stmt *getThen() const { return SubExprs[THEN]; } 314 const Stmt *getElse() const { return SubExprs[ELSE]; } 315 316 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 317 Stmt *getThen() { return SubExprs[THEN]; } 318 Stmt *getElse() { return SubExprs[ELSE]; } 319 320 static bool classof(const Stmt *T) { 321 return T->getStmtClass() == IfStmtClass; 322 } 323 static bool classof(const IfStmt *) { return true; } 324 325 // Iterators 326 virtual child_iterator child_begin(); 327 virtual child_iterator child_end(); 328}; 329 330/// SwitchStmt - This represents a 'switch' stmt. 331/// 332class SwitchStmt : public Stmt { 333 enum { COND, BODY, END_EXPR }; 334 Stmt* SubExprs[END_EXPR]; 335 // This points to a linked list of case and default statements. 336 SwitchCase *FirstCase; 337public: 338 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 339 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 340 SubExprs[BODY] = NULL; 341 } 342 343 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 344 const Stmt *getBody() const { return SubExprs[BODY]; } 345 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 346 347 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 348 Stmt *getBody() { return SubExprs[BODY]; } 349 SwitchCase *getSwitchCaseList() { return FirstCase; } 350 351 void setBody(Stmt *S) { SubExprs[BODY] = S; } 352 353 void addSwitchCase(SwitchCase *SC) { 354 if (FirstCase) 355 SC->setNextSwitchCase(FirstCase); 356 357 FirstCase = SC; 358 } 359 360 static bool classof(const Stmt *T) { 361 return T->getStmtClass() == SwitchStmtClass; 362 } 363 static bool classof(const SwitchStmt *) { return true; } 364 365 // Iterators 366 virtual child_iterator child_begin(); 367 virtual child_iterator child_end(); 368}; 369 370 371/// WhileStmt - This represents a 'while' stmt. 372/// 373class WhileStmt : public Stmt { 374 enum { COND, BODY, END_EXPR }; 375 Stmt* SubExprs[END_EXPR]; 376public: 377 WhileStmt(Expr *cond, Stmt *body) : Stmt(WhileStmtClass) { 378 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 379 SubExprs[BODY] = body; 380 } 381 382 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 383 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 384 Stmt *getBody() { return SubExprs[BODY]; } 385 const Stmt *getBody() const { return SubExprs[BODY]; } 386 387 static bool classof(const Stmt *T) { 388 return T->getStmtClass() == WhileStmtClass; 389 } 390 static bool classof(const WhileStmt *) { return true; } 391 392 // Iterators 393 virtual child_iterator child_begin(); 394 virtual child_iterator child_end(); 395}; 396 397/// DoStmt - This represents a 'do/while' stmt. 398/// 399class DoStmt : public Stmt { 400 enum { COND, BODY, END_EXPR }; 401 Stmt* SubExprs[END_EXPR]; 402public: 403 DoStmt(Stmt *body, Expr *cond) : Stmt(DoStmtClass) { 404 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 405 SubExprs[BODY] = body; 406 } 407 408 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 409 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 410 Stmt *getBody() { return SubExprs[BODY]; } 411 const Stmt *getBody() const { return SubExprs[BODY]; } 412 413 static bool classof(const Stmt *T) { 414 return T->getStmtClass() == DoStmtClass; 415 } 416 static bool classof(const DoStmt *) { return true; } 417 418 // Iterators 419 virtual child_iterator child_begin(); 420 virtual child_iterator child_end(); 421}; 422 423 424/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 425/// the init/cond/inc parts of the ForStmt will be null if they were not 426/// specified in the source. 427/// 428class ForStmt : public Stmt { 429 enum { INIT, COND, INC, BODY, END_EXPR }; 430 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 431public: 432 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body) : Stmt(ForStmtClass) { 433 SubExprs[INIT] = Init; 434 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 435 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 436 SubExprs[BODY] = Body; 437 } 438 439 Stmt *getInit() { return SubExprs[INIT]; } 440 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 441 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 442 Stmt *getBody() { return SubExprs[BODY]; } 443 444 const Stmt *getInit() const { return SubExprs[INIT]; } 445 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 446 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 447 const Stmt *getBody() const { return SubExprs[BODY]; } 448 449 static bool classof(const Stmt *T) { 450 return T->getStmtClass() == ForStmtClass; 451 } 452 static bool classof(const ForStmt *) { return true; } 453 454 // Iterators 455 virtual child_iterator child_begin(); 456 virtual child_iterator child_end(); 457}; 458 459/// GotoStmt - This represents a direct goto. 460/// 461class GotoStmt : public Stmt { 462 LabelStmt *Label; 463public: 464 GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {} 465 466 LabelStmt *getLabel() const { return Label; } 467 468 static bool classof(const Stmt *T) { 469 return T->getStmtClass() == GotoStmtClass; 470 } 471 static bool classof(const GotoStmt *) { return true; } 472 473 // Iterators 474 virtual child_iterator child_begin(); 475 virtual child_iterator child_end(); 476}; 477 478/// IndirectGotoStmt - This represents an indirect goto. 479/// 480class IndirectGotoStmt : public Stmt { 481 Expr *Target; 482public: 483 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 484 485 Expr *getTarget() { return Target; } 486 const Expr *getTarget() const { return Target; } 487 488 static bool classof(const Stmt *T) { 489 return T->getStmtClass() == IndirectGotoStmtClass; 490 } 491 static bool classof(const IndirectGotoStmt *) { return true; } 492 493 // Iterators 494 virtual child_iterator child_begin(); 495 virtual child_iterator child_end(); 496}; 497 498 499/// ContinueStmt - This represents a continue. 500/// 501class ContinueStmt : public Stmt { 502public: 503 ContinueStmt() : Stmt(ContinueStmtClass) {} 504 static bool classof(const Stmt *T) { 505 return T->getStmtClass() == ContinueStmtClass; 506 } 507 static bool classof(const ContinueStmt *) { return true; } 508 509 // Iterators 510 virtual child_iterator child_begin(); 511 virtual child_iterator child_end(); 512}; 513 514/// BreakStmt - This represents a break. 515/// 516class BreakStmt : public Stmt { 517public: 518 BreakStmt() : Stmt(BreakStmtClass) {} 519 static bool classof(const Stmt *T) { 520 return T->getStmtClass() == BreakStmtClass; 521 } 522 static bool classof(const BreakStmt *) { return true; } 523 524 // Iterators 525 virtual child_iterator child_begin(); 526 virtual child_iterator child_end(); 527}; 528 529 530/// ReturnStmt - This represents a return, optionally of an expression. 531/// 532class ReturnStmt : public Stmt { 533 Expr *RetExpr; 534public: 535 ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {} 536 537 const Expr *getRetValue() const { return RetExpr; } 538 Expr *getRetValue() { return RetExpr; } 539 540 static bool classof(const Stmt *T) { 541 return T->getStmtClass() == ReturnStmtClass; 542 } 543 static bool classof(const ReturnStmt *) { return true; } 544 545 // Iterators 546 virtual child_iterator child_begin(); 547 virtual child_iterator child_end(); 548}; 549 550} // end namespace clang 551 552#endif 553