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