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