Stmt.h revision 8aab17e82aab6b3f266ef1884253226d2cb8b8d8
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 "clang/AST/StmtIterator.h" 19#include "llvm/ADT/SmallVector.h" 20#include "llvm/ADT/iterator" 21#include "llvm/Bitcode/SerializationFwd.h" 22#include <iosfwd> 23 24namespace clang { 25 class Expr; 26 class Decl; 27 class ScopedDecl; 28 class IdentifierInfo; 29 class SourceManager; 30 class SwitchStmt; 31 class PrinterHelper; 32 33/// Stmt - This represents one statement. 34/// 35class Stmt { 36public: 37 enum StmtClass { 38#define STMT(N, CLASS, PARENT) CLASS##Class = N, 39#define FIRST_STMT(N) firstStmtConstant = N, 40#define LAST_STMT(N) lastStmtConstant = N, 41#define FIRST_EXPR(N) firstExprConstant = N, 42#define LAST_EXPR(N) lastExprConstant = N 43#include "clang/AST/StmtNodes.def" 44}; 45private: 46 const StmtClass sClass; 47public: 48 Stmt(StmtClass SC) : sClass(SC) { 49 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 50 } 51 virtual ~Stmt() {} 52 53 StmtClass getStmtClass() const { return sClass; } 54 const char *getStmtClassName() const; 55 56 /// SourceLocation tokens are not useful in isolation - they are low level 57 /// value objects created/interpreted by SourceManager. We assume AST 58 /// clients will have a pointer to the respective SourceManager. 59 virtual SourceRange getSourceRange() const = 0; 60 SourceLocation getLocStart() const { return getSourceRange().getBegin(); } 61 SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } 62 63 // global temp stats (until we have a per-module visitor) 64 static void addStmtClass(const StmtClass s); 65 static bool CollectingStats(bool enable=false); 66 static void PrintStats(); 67 68 /// dump - This does a local dump of the specified AST fragment. It dumps the 69 /// specified node and a few nodes underneath it, but not the whole subtree. 70 /// This is useful in a debugger. 71 void dump() const; 72 void dump(SourceManager &SM) const; 73 74 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 75 void dumpAll() const; 76 void dumpAll(SourceManager &SM) const; 77 78 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 79 /// back to its original source language syntax. 80 void dumpPretty() const; 81 void printPretty(std::ostream &OS, PrinterHelper* = NULL) const; 82 83 /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 84 /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 85 void viewAST() const; 86 87 // Implement isa<T> support. 88 static bool classof(const Stmt *) { return true; } 89 90 /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) 91 /// contain implicit control-flow in the order their subexpressions 92 /// are evaluated. This predicate returns true if this statement has 93 /// such implicit control-flow. Such statements are also specially handled 94 /// within CFGs. 95 bool hasImplicitControlFlow() const; 96 97 /// Child Iterators: All subclasses must implement child_begin and child_end 98 /// to permit easy iteration over the substatements/subexpessions of an 99 /// AST node. This permits easy iteration over all nodes in the AST. 100 typedef StmtIterator child_iterator; 101 typedef ConstStmtIterator const_child_iterator; 102 103 virtual child_iterator child_begin() = 0; 104 virtual child_iterator child_end() = 0; 105 106 const_child_iterator child_begin() const { 107 return const_child_iterator(const_cast<Stmt*>(this)->child_begin()); 108 } 109 110 const_child_iterator child_end() const { 111 return const_child_iterator(const_cast<Stmt*>(this)->child_end()); 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 ScopedDecl *TheDecl; 122public: 123 DeclStmt(ScopedDecl *D) : Stmt(DeclStmtClass), TheDecl(D) {} 124 125 const ScopedDecl *getDecl() const { return TheDecl; } 126 ScopedDecl *getDecl() { return TheDecl; } 127 128 virtual SourceRange getSourceRange() const { return SourceRange(); } 129 130 static bool classof(const Stmt *T) { 131 return T->getStmtClass() == DeclStmtClass; 132 } 133 static bool classof(const DeclStmt *) { return true; } 134 135 // Iterators 136 virtual child_iterator child_begin(); 137 virtual child_iterator child_end(); 138}; 139 140/// NullStmt - This is the null statement ";": C99 6.8.3p3. 141/// 142class NullStmt : public Stmt { 143 SourceLocation SemiLoc; 144public: 145 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 146 147 SourceLocation getSemiLoc() const { return SemiLoc; } 148 149 virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 150 151 static bool classof(const Stmt *T) { 152 return T->getStmtClass() == NullStmtClass; 153 } 154 static bool classof(const NullStmt *) { return true; } 155 156 // Iterators 157 virtual child_iterator child_begin(); 158 virtual child_iterator child_end(); 159}; 160 161/// CompoundStmt - This represents a group of statements like { stmt stmt }. 162/// 163class CompoundStmt : public Stmt { 164 llvm::SmallVector<Stmt*, 16> Body; 165 SourceLocation LBracLoc, RBracLoc; 166public: 167 CompoundStmt(Stmt **StmtStart, unsigned NumStmts, 168 SourceLocation LB, SourceLocation RB) 169 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts), 170 LBracLoc(LB), RBracLoc(RB) {} 171 172 bool body_empty() const { return Body.empty(); } 173 174 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 175 body_iterator body_begin() { return Body.begin(); } 176 body_iterator body_end() { return Body.end(); } 177 Stmt *body_back() { return Body.back(); } 178 179 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 180 const_body_iterator body_begin() const { return Body.begin(); } 181 const_body_iterator body_end() const { return Body.end(); } 182 const Stmt *body_back() const { return Body.back(); } 183 184 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 185 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 186 reverse_body_iterator body_rend() { return Body.rend(); } 187 188 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 189 const_reverse_body_iterator; 190 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 191 const_reverse_body_iterator body_rend() const { return Body.rend(); } 192 193 void push_back(Stmt *S) { Body.push_back(S); } 194 195 virtual SourceRange getSourceRange() const { 196 return SourceRange(LBracLoc, RBracLoc); 197 } 198 199 SourceLocation getLBracLoc() const { return LBracLoc; } 200 SourceLocation getRBracLoc() const { return RBracLoc; } 201 202 static bool classof(const Stmt *T) { 203 return T->getStmtClass() == CompoundStmtClass; 204 } 205 static bool classof(const CompoundStmt *) { return true; } 206 207 // Iterators 208 virtual child_iterator child_begin(); 209 virtual child_iterator child_end(); 210}; 211 212// SwitchCase is the base class for CaseStmt and DefaultStmt, 213class SwitchCase : public Stmt { 214 // A pointer to the following CaseStmt or DefaultStmt class, 215 // used by SwitchStmt. 216 SwitchCase *NextSwitchCase; 217protected: 218 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 219 220public: 221 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 222 223 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 224 225 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 226 227 virtual Stmt* v_getSubStmt() = 0; 228 Stmt *getSubStmt() { return v_getSubStmt(); } 229 230 virtual SourceRange getSourceRange() const { return SourceRange(); } 231 232 static bool classof(const Stmt *T) { 233 return T->getStmtClass() == CaseStmtClass || 234 T->getStmtClass() == DefaultStmtClass; 235 } 236 static bool classof(const SwitchCase *) { return true; } 237}; 238 239class CaseStmt : public SwitchCase { 240 enum { SUBSTMT, LHS, RHS, END_EXPR }; 241 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 242 // GNU "case 1 ... 4" extension 243 SourceLocation CaseLoc; 244public: 245 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 246 : SwitchCase(CaseStmtClass) { 247 SubExprs[SUBSTMT] = substmt; 248 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 249 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 250 CaseLoc = caseLoc; 251 } 252 253 SourceLocation getCaseLoc() const { return CaseLoc; } 254 255 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 256 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 257 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 258 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 259 const Expr *getLHS() const { 260 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 261 } 262 const Expr *getRHS() const { 263 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 264 } 265 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 266 267 virtual SourceRange getSourceRange() const { 268 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 269 } 270 static bool classof(const Stmt *T) { 271 return T->getStmtClass() == CaseStmtClass; 272 } 273 static bool classof(const CaseStmt *) { return true; } 274 275 // Iterators 276 virtual child_iterator child_begin(); 277 virtual child_iterator child_end(); 278}; 279 280class DefaultStmt : public SwitchCase { 281 Stmt* SubStmt; 282 SourceLocation DefaultLoc; 283public: 284 DefaultStmt(SourceLocation DL, Stmt *substmt) : 285 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 286 287 Stmt *getSubStmt() { return SubStmt; } 288 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 289 const Stmt *getSubStmt() const { return SubStmt; } 290 291 SourceLocation getDefaultLoc() const { return DefaultLoc; } 292 293 virtual SourceRange getSourceRange() const { 294 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 295 } 296 static bool classof(const Stmt *T) { 297 return T->getStmtClass() == DefaultStmtClass; 298 } 299 static bool classof(const DefaultStmt *) { return true; } 300 301 // Iterators 302 virtual child_iterator child_begin(); 303 virtual child_iterator child_end(); 304}; 305 306class LabelStmt : public Stmt { 307 IdentifierInfo *Label; 308 Stmt *SubStmt; 309 SourceLocation IdentLoc; 310public: 311 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 312 : Stmt(LabelStmtClass), Label(label), 313 SubStmt(substmt), IdentLoc(IL) {} 314 315 SourceLocation getIdentLoc() const { return IdentLoc; } 316 IdentifierInfo *getID() const { return Label; } 317 const char *getName() const; 318 Stmt *getSubStmt() { return SubStmt; } 319 const Stmt *getSubStmt() const { return SubStmt; } 320 321 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 322 void setSubStmt(Stmt *SS) { SubStmt = SS; } 323 324 virtual SourceRange getSourceRange() const { 325 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 326 } 327 static bool classof(const Stmt *T) { 328 return T->getStmtClass() == LabelStmtClass; 329 } 330 static bool classof(const LabelStmt *) { return true; } 331 332 // Iterators 333 virtual child_iterator child_begin(); 334 virtual child_iterator child_end(); 335}; 336 337 338/// IfStmt - This represents an if/then/else. 339/// 340class IfStmt : public Stmt { 341 enum { COND, THEN, ELSE, END_EXPR }; 342 Stmt* SubExprs[END_EXPR]; 343 SourceLocation IfLoc; 344public: 345 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 346 : Stmt(IfStmtClass) { 347 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 348 SubExprs[THEN] = then; 349 SubExprs[ELSE] = elsev; 350 IfLoc = IL; 351 } 352 353 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 354 const Stmt *getThen() const { return SubExprs[THEN]; } 355 const Stmt *getElse() const { return SubExprs[ELSE]; } 356 357 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 358 Stmt *getThen() { return SubExprs[THEN]; } 359 Stmt *getElse() { return SubExprs[ELSE]; } 360 361 virtual SourceRange getSourceRange() const { 362 if (SubExprs[ELSE]) 363 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 364 else 365 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 366 } 367 368 static bool classof(const Stmt *T) { 369 return T->getStmtClass() == IfStmtClass; 370 } 371 static bool classof(const IfStmt *) { return true; } 372 373 // Iterators 374 virtual child_iterator child_begin(); 375 virtual child_iterator child_end(); 376}; 377 378/// SwitchStmt - This represents a 'switch' stmt. 379/// 380class SwitchStmt : public Stmt { 381 enum { COND, BODY, END_EXPR }; 382 Stmt* SubExprs[END_EXPR]; 383 // This points to a linked list of case and default statements. 384 SwitchCase *FirstCase; 385 SourceLocation SwitchLoc; 386public: 387 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 388 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 389 SubExprs[BODY] = NULL; 390 } 391 392 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 393 const Stmt *getBody() const { return SubExprs[BODY]; } 394 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 395 396 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 397 Stmt *getBody() { return SubExprs[BODY]; } 398 SwitchCase *getSwitchCaseList() { return FirstCase; } 399 400 void setBody(Stmt *S, SourceLocation SL) { 401 SubExprs[BODY] = S; 402 SwitchLoc = SL; 403 } 404 void addSwitchCase(SwitchCase *SC) { 405 if (FirstCase) 406 SC->setNextSwitchCase(FirstCase); 407 408 FirstCase = SC; 409 } 410 virtual SourceRange getSourceRange() const { 411 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 412 } 413 static bool classof(const Stmt *T) { 414 return T->getStmtClass() == SwitchStmtClass; 415 } 416 static bool classof(const SwitchStmt *) { return true; } 417 418 // Iterators 419 virtual child_iterator child_begin(); 420 virtual child_iterator child_end(); 421}; 422 423 424/// WhileStmt - This represents a 'while' stmt. 425/// 426class WhileStmt : public Stmt { 427 enum { COND, BODY, END_EXPR }; 428 Stmt* SubExprs[END_EXPR]; 429 SourceLocation WhileLoc; 430public: 431 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 432 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 433 SubExprs[BODY] = body; 434 WhileLoc = WL; 435 } 436 437 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 438 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 439 Stmt *getBody() { return SubExprs[BODY]; } 440 const Stmt *getBody() const { return SubExprs[BODY]; } 441 442 virtual SourceRange getSourceRange() const { 443 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 444 } 445 static bool classof(const Stmt *T) { 446 return T->getStmtClass() == WhileStmtClass; 447 } 448 static bool classof(const WhileStmt *) { return true; } 449 450 // Iterators 451 virtual child_iterator child_begin(); 452 virtual child_iterator child_end(); 453}; 454 455/// DoStmt - This represents a 'do/while' stmt. 456/// 457class DoStmt : public Stmt { 458 enum { COND, BODY, END_EXPR }; 459 Stmt* SubExprs[END_EXPR]; 460 SourceLocation DoLoc; 461public: 462 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 463 : Stmt(DoStmtClass), DoLoc(DL) { 464 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 465 SubExprs[BODY] = body; 466 DoLoc = DL; 467 } 468 469 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 470 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 471 Stmt *getBody() { return SubExprs[BODY]; } 472 const Stmt *getBody() const { return SubExprs[BODY]; } 473 474 virtual SourceRange getSourceRange() const { 475 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 476 } 477 static bool classof(const Stmt *T) { 478 return T->getStmtClass() == DoStmtClass; 479 } 480 static bool classof(const DoStmt *) { return true; } 481 482 // Iterators 483 virtual child_iterator child_begin(); 484 virtual child_iterator child_end(); 485}; 486 487 488/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 489/// the init/cond/inc parts of the ForStmt will be null if they were not 490/// specified in the source. 491/// 492class ForStmt : public Stmt { 493 enum { INIT, COND, INC, BODY, END_EXPR }; 494 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 495 SourceLocation ForLoc; 496public: 497 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 498 : Stmt(ForStmtClass) { 499 SubExprs[INIT] = Init; 500 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 501 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 502 SubExprs[BODY] = Body; 503 ForLoc = FL; 504 } 505 506 Stmt *getInit() { return SubExprs[INIT]; } 507 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 508 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 509 Stmt *getBody() { return SubExprs[BODY]; } 510 511 const Stmt *getInit() const { return SubExprs[INIT]; } 512 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 513 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 514 const Stmt *getBody() const { return SubExprs[BODY]; } 515 516 virtual SourceRange getSourceRange() const { 517 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 518 } 519 static bool classof(const Stmt *T) { 520 return T->getStmtClass() == ForStmtClass; 521 } 522 static bool classof(const ForStmt *) { return true; } 523 524 // Iterators 525 virtual child_iterator child_begin(); 526 virtual child_iterator child_end(); 527}; 528 529/// GotoStmt - This represents a direct goto. 530/// 531class GotoStmt : public Stmt { 532 LabelStmt *Label; 533 SourceLocation GotoLoc; 534 SourceLocation LabelLoc; 535public: 536 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 537 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 538 539 LabelStmt *getLabel() const { return Label; } 540 541 virtual SourceRange getSourceRange() const { 542 return SourceRange(GotoLoc, LabelLoc); 543 } 544 static bool classof(const Stmt *T) { 545 return T->getStmtClass() == GotoStmtClass; 546 } 547 static bool classof(const GotoStmt *) { return true; } 548 549 // Iterators 550 virtual child_iterator child_begin(); 551 virtual child_iterator child_end(); 552}; 553 554/// IndirectGotoStmt - This represents an indirect goto. 555/// 556class IndirectGotoStmt : public Stmt { 557 Expr *Target; 558public: 559 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 560 561 Expr *getTarget() { return Target; } 562 const Expr *getTarget() const { return Target; } 563 564 virtual SourceRange getSourceRange() const { return SourceRange(); } 565 566 static bool classof(const Stmt *T) { 567 return T->getStmtClass() == IndirectGotoStmtClass; 568 } 569 static bool classof(const IndirectGotoStmt *) { return true; } 570 571 // Iterators 572 virtual child_iterator child_begin(); 573 virtual child_iterator child_end(); 574}; 575 576 577/// ContinueStmt - This represents a continue. 578/// 579class ContinueStmt : public Stmt { 580 SourceLocation ContinueLoc; 581public: 582 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 583 584 virtual SourceRange getSourceRange() const { 585 return SourceRange(ContinueLoc); 586 } 587 static bool classof(const Stmt *T) { 588 return T->getStmtClass() == ContinueStmtClass; 589 } 590 static bool classof(const ContinueStmt *) { return true; } 591 592 // Iterators 593 virtual child_iterator child_begin(); 594 virtual child_iterator child_end(); 595}; 596 597/// BreakStmt - This represents a break. 598/// 599class BreakStmt : public Stmt { 600 SourceLocation BreakLoc; 601public: 602 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 603 604 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 605 606 static bool classof(const Stmt *T) { 607 return T->getStmtClass() == BreakStmtClass; 608 } 609 static bool classof(const BreakStmt *) { return true; } 610 611 // Iterators 612 virtual child_iterator child_begin(); 613 virtual child_iterator child_end(); 614}; 615 616 617/// ReturnStmt - This represents a return, optionally of an expression. 618/// 619class ReturnStmt : public Stmt { 620 Expr *RetExpr; 621 SourceLocation RetLoc; 622public: 623 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 624 RetExpr(E), RetLoc(RL) {} 625 626 const Expr *getRetValue() const { return RetExpr; } 627 Expr *getRetValue() { return RetExpr; } 628 629 virtual SourceRange getSourceRange() const; 630 631 static bool classof(const Stmt *T) { 632 return T->getStmtClass() == ReturnStmtClass; 633 } 634 static bool classof(const ReturnStmt *) { return true; } 635 636 // Iterators 637 virtual child_iterator child_begin(); 638 virtual child_iterator child_end(); 639}; 640 641/// AsmStmt - This represents a GNU inline-assembly statement extension. 642/// 643class AsmStmt : public Stmt { 644 SourceLocation AsmLoc, RParenLoc; 645 // FIXME: This doesn't capture most of the interesting pieces. 646public: 647 AsmStmt(SourceLocation asmloc, SourceLocation rparenloc) 648 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {} 649 650 virtual SourceRange getSourceRange() const { 651 return SourceRange(AsmLoc, RParenLoc); 652 } 653 654 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 655 static bool classof(const AsmStmt *) { return true; } 656 657 virtual child_iterator child_begin(); 658 virtual child_iterator child_end(); 659}; 660 661/// ObjcAtCatchStmt - This represents objective-c's @catch statement. 662class ObjcAtCatchStmt : public Stmt { 663private: 664 // Points to next @catch statement, or null 665 ObjcAtCatchStmt *NextAtCatchStmt; 666 enum { SELECTOR, BODY, END_EXPR }; 667 Stmt *SubExprs[END_EXPR]; 668 SourceLocation AtCatchLoc, RParenLoc; 669 670public: 671 ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 672 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList) 673 : Stmt(ObjcAtCatchStmtClass), 674 AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { 675 SubExprs[SELECTOR] = catchVarStmtDecl; 676 SubExprs[BODY] = atCatchStmt; 677 SubExprs[END_EXPR] = NULL; 678 if (!atCatchList) 679 NextAtCatchStmt = NULL; 680 else { 681 ObjcAtCatchStmt *AtCatchList = 682 static_cast<ObjcAtCatchStmt*>(atCatchList); 683 while (AtCatchList->NextAtCatchStmt) 684 AtCatchList = AtCatchList->NextAtCatchStmt; 685 AtCatchList->NextAtCatchStmt = this; 686 } 687 } 688 689 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 690 Stmt *getCatchBody() { return SubExprs[BODY]; } 691 const Stmt *getNextCatchStmt() const { return NextAtCatchStmt; } 692 Stmt *getNextCatchStmt() { return NextAtCatchStmt; } 693 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 694 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 695 696 virtual SourceRange getSourceRange() const { 697 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 698 } 699 700 static bool classof(const Stmt *T) { 701 return T->getStmtClass() == ObjcAtCatchStmtClass; 702 } 703 static bool classof(const ObjcAtCatchStmt *) { return true; } 704 705 virtual child_iterator child_begin(); 706 virtual child_iterator child_end(); 707 708}; 709 710/// ObjcAtFinallyStmt - This represent objective-c's @finally Statement 711class ObjcAtFinallyStmt : public Stmt { 712 private: 713 Stmt *AtFinallyStmt; 714 SourceLocation AtFinallyLoc; 715 716 public: 717 ObjcAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 718 : Stmt(ObjcAtFinallyStmtClass), 719 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 720 721 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 722 Stmt *getFinallyBody () { return AtFinallyStmt; } 723 724 virtual SourceRange getSourceRange() const { 725 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 726 } 727 728 static bool classof(const Stmt *T) { 729 return T->getStmtClass() == ObjcAtFinallyStmtClass; 730 } 731 static bool classof(const ObjcAtFinallyStmt *) { return true; } 732 733 virtual child_iterator child_begin(); 734 virtual child_iterator child_end(); 735 736}; 737 738/// ObjcAtTryStmt - This represent objective-c's over-all 739/// @try ... @catch ... @finally statement. 740class ObjcAtTryStmt : public Stmt { 741private: 742 enum { TRY, CATCH, FINALLY, END_TRY }; 743 Stmt* SubStmts[END_TRY]; 744 745 SourceLocation AtTryLoc; 746 747public: 748 ObjcAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 749 Stmt *atCatchStmt, 750 Stmt *atFinallyStmt) 751 : Stmt(ObjcAtTryStmtClass), AtTryLoc(atTryLoc) { 752 SubStmts[TRY] = atTryStmt; 753 SubStmts[CATCH] = atCatchStmt; 754 SubStmts[FINALLY] = atFinallyStmt; 755 SubStmts[END_TRY] = NULL; 756 } 757 758 const Stmt *getTryBody() const { return SubStmts[TRY]; } 759 Stmt *getTryBody() { return SubStmts[TRY]; } 760 const Stmt *getCatchStmts() const { return SubStmts[CATCH]; } 761 Stmt *getCatchStmts() { return SubStmts[CATCH]; } 762 const Stmt *getFinallyStmt() const { return SubStmts[FINALLY]; } 763 Stmt *getFinallyStmt() { return SubStmts[FINALLY]; } 764 765 virtual SourceRange getSourceRange() const { 766 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 767 } 768 769 static bool classof(const Stmt *T) { 770 return T->getStmtClass() == ObjcAtTryStmtClass; 771 } 772 static bool classof(const ObjcAtTryStmt *) { return true; } 773 774 virtual child_iterator child_begin(); 775 virtual child_iterator child_end(); 776 777}; 778 779} // end namespace clang 780 781//===----------------------------------------------------------------------===// 782// For Stmt serialization. 783//===----------------------------------------------------------------------===// 784 785namespace llvm { 786 787template<> struct SerializeTrait<clang::Stmt> { 788 static void Emit(Serializer& S, const clang::Stmt& stmt); 789 static clang::Stmt* Materialize(Deserializer& D); 790}; 791 792} // end namespace llvm 793 794#endif 795