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