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