Stmt.h revision 54395d440dc82a5e51b945c6c2a7f4bc4bea0358
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 220 SourceLocation getLBracLoc() { return LBracLoc; } 221 SourceLocation getRBracLoc() { return RBracLoc; } 222 223 static bool classof(const Stmt *T) { 224 return T->getStmtClass() == CompoundStmtClass; 225 } 226 static bool classof(const CompoundStmt *) { return true; } 227 228 // Iterators 229 virtual child_iterator child_begin(); 230 virtual child_iterator child_end(); 231}; 232 233// SwitchCase is the base class for CaseStmt and DefaultStmt, 234class SwitchCase : public Stmt { 235 // A pointer to the following CaseStmt or DefaultStmt class, 236 // used by SwitchStmt. 237 SwitchCase *NextSwitchCase; 238protected: 239 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 240 241public: 242 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 243 244 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 245 246 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 247 248 virtual Stmt* v_getSubStmt() = 0; 249 Stmt *getSubStmt() { return v_getSubStmt(); } 250 251 virtual SourceRange getSourceRange() const { return SourceRange(); } 252 253 static bool classof(const Stmt *T) { 254 return T->getStmtClass() == CaseStmtClass || 255 T->getStmtClass() == DefaultStmtClass; 256 } 257 static bool classof(const SwitchCase *) { return true; } 258}; 259 260class CaseStmt : public SwitchCase { 261 enum { SUBSTMT, LHS, RHS, END_EXPR }; 262 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 263 // GNU "case 1 ... 4" extension 264 SourceLocation CaseLoc; 265public: 266 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 267 : SwitchCase(CaseStmtClass) { 268 SubExprs[SUBSTMT] = substmt; 269 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 270 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 271 CaseLoc = caseLoc; 272 } 273 274 SourceLocation getCaseLoc() const { return CaseLoc; } 275 276 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 277 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 278 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 279 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 280 const Expr *getLHS() const { 281 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 282 } 283 const Expr *getRHS() const { 284 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 285 } 286 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 287 288 virtual SourceRange getSourceRange() const { 289 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 290 } 291 static bool classof(const Stmt *T) { 292 return T->getStmtClass() == CaseStmtClass; 293 } 294 static bool classof(const CaseStmt *) { return true; } 295 296 // Iterators 297 virtual child_iterator child_begin(); 298 virtual child_iterator child_end(); 299}; 300 301class DefaultStmt : public SwitchCase { 302 Stmt* SubStmt; 303 SourceLocation DefaultLoc; 304public: 305 DefaultStmt(SourceLocation DL, Stmt *substmt) : 306 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 307 308 Stmt *getSubStmt() { return SubStmt; } 309 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 310 const Stmt *getSubStmt() const { return SubStmt; } 311 312 SourceLocation getDefaultLoc() const { return DefaultLoc; } 313 314 virtual SourceRange getSourceRange() const { 315 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 316 } 317 static bool classof(const Stmt *T) { 318 return T->getStmtClass() == DefaultStmtClass; 319 } 320 static bool classof(const DefaultStmt *) { return true; } 321 322 // Iterators 323 virtual child_iterator child_begin(); 324 virtual child_iterator child_end(); 325}; 326 327class LabelStmt : public Stmt { 328 IdentifierInfo *Label; 329 Stmt *SubStmt; 330 SourceLocation IdentLoc; 331public: 332 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 333 : Stmt(LabelStmtClass), Label(label), 334 SubStmt(substmt), IdentLoc(IL) {} 335 336 SourceLocation getIdentLoc() const { return IdentLoc; } 337 IdentifierInfo *getID() const { return Label; } 338 const char *getName() const; 339 Stmt *getSubStmt() { return SubStmt; } 340 const Stmt *getSubStmt() const { return SubStmt; } 341 342 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 343 void setSubStmt(Stmt *SS) { SubStmt = SS; } 344 345 virtual SourceRange getSourceRange() const { 346 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 347 } 348 static bool classof(const Stmt *T) { 349 return T->getStmtClass() == LabelStmtClass; 350 } 351 static bool classof(const LabelStmt *) { return true; } 352 353 // Iterators 354 virtual child_iterator child_begin(); 355 virtual child_iterator child_end(); 356}; 357 358 359/// IfStmt - This represents an if/then/else. 360/// 361class IfStmt : public Stmt { 362 enum { COND, THEN, ELSE, END_EXPR }; 363 Stmt* SubExprs[END_EXPR]; 364 SourceLocation IfLoc; 365public: 366 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 367 : Stmt(IfStmtClass) { 368 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 369 SubExprs[THEN] = then; 370 SubExprs[ELSE] = elsev; 371 IfLoc = IL; 372 } 373 374 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 375 const Stmt *getThen() const { return SubExprs[THEN]; } 376 const Stmt *getElse() const { return SubExprs[ELSE]; } 377 378 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 379 Stmt *getThen() { return SubExprs[THEN]; } 380 Stmt *getElse() { return SubExprs[ELSE]; } 381 382 virtual SourceRange getSourceRange() const { 383 if (SubExprs[ELSE]) 384 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 385 else 386 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 387 } 388 389 static bool classof(const Stmt *T) { 390 return T->getStmtClass() == IfStmtClass; 391 } 392 static bool classof(const IfStmt *) { return true; } 393 394 // Iterators 395 virtual child_iterator child_begin(); 396 virtual child_iterator child_end(); 397}; 398 399/// SwitchStmt - This represents a 'switch' stmt. 400/// 401class SwitchStmt : public Stmt { 402 enum { COND, BODY, END_EXPR }; 403 Stmt* SubExprs[END_EXPR]; 404 // This points to a linked list of case and default statements. 405 SwitchCase *FirstCase; 406 SourceLocation SwitchLoc; 407public: 408 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 409 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 410 SubExprs[BODY] = NULL; 411 } 412 413 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 414 const Stmt *getBody() const { return SubExprs[BODY]; } 415 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 416 417 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 418 Stmt *getBody() { return SubExprs[BODY]; } 419 SwitchCase *getSwitchCaseList() { return FirstCase; } 420 421 void setBody(Stmt *S, SourceLocation SL) { 422 SubExprs[BODY] = S; 423 SwitchLoc = SL; 424 } 425 void addSwitchCase(SwitchCase *SC) { 426 if (FirstCase) 427 SC->setNextSwitchCase(FirstCase); 428 429 FirstCase = SC; 430 } 431 virtual SourceRange getSourceRange() const { 432 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 433 } 434 static bool classof(const Stmt *T) { 435 return T->getStmtClass() == SwitchStmtClass; 436 } 437 static bool classof(const SwitchStmt *) { return true; } 438 439 // Iterators 440 virtual child_iterator child_begin(); 441 virtual child_iterator child_end(); 442}; 443 444 445/// WhileStmt - This represents a 'while' stmt. 446/// 447class WhileStmt : public Stmt { 448 enum { COND, BODY, END_EXPR }; 449 Stmt* SubExprs[END_EXPR]; 450 SourceLocation WhileLoc; 451public: 452 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 453 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 454 SubExprs[BODY] = body; 455 WhileLoc = WL; 456 } 457 458 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 459 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 460 Stmt *getBody() { return SubExprs[BODY]; } 461 const Stmt *getBody() const { return SubExprs[BODY]; } 462 463 virtual SourceRange getSourceRange() const { 464 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 465 } 466 static bool classof(const Stmt *T) { 467 return T->getStmtClass() == WhileStmtClass; 468 } 469 static bool classof(const WhileStmt *) { return true; } 470 471 // Iterators 472 virtual child_iterator child_begin(); 473 virtual child_iterator child_end(); 474}; 475 476/// DoStmt - This represents a 'do/while' stmt. 477/// 478class DoStmt : public Stmt { 479 enum { COND, BODY, END_EXPR }; 480 Stmt* SubExprs[END_EXPR]; 481 SourceLocation DoLoc; 482public: 483 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 484 : Stmt(DoStmtClass), DoLoc(DL) { 485 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 486 SubExprs[BODY] = body; 487 DoLoc = DL; 488 } 489 490 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 491 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 492 Stmt *getBody() { return SubExprs[BODY]; } 493 const Stmt *getBody() const { return SubExprs[BODY]; } 494 495 virtual SourceRange getSourceRange() const { 496 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 497 } 498 static bool classof(const Stmt *T) { 499 return T->getStmtClass() == DoStmtClass; 500 } 501 static bool classof(const DoStmt *) { return true; } 502 503 // Iterators 504 virtual child_iterator child_begin(); 505 virtual child_iterator child_end(); 506}; 507 508 509/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 510/// the init/cond/inc parts of the ForStmt will be null if they were not 511/// specified in the source. 512/// 513class ForStmt : public Stmt { 514 enum { INIT, COND, INC, BODY, END_EXPR }; 515 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 516 SourceLocation ForLoc; 517public: 518 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 519 : Stmt(ForStmtClass) { 520 SubExprs[INIT] = Init; 521 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 522 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 523 SubExprs[BODY] = Body; 524 ForLoc = FL; 525 } 526 527 Stmt *getInit() { return SubExprs[INIT]; } 528 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 529 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 530 Stmt *getBody() { return SubExprs[BODY]; } 531 532 const Stmt *getInit() const { return SubExprs[INIT]; } 533 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 534 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 535 const Stmt *getBody() const { return SubExprs[BODY]; } 536 537 virtual SourceRange getSourceRange() const { 538 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 539 } 540 static bool classof(const Stmt *T) { 541 return T->getStmtClass() == ForStmtClass; 542 } 543 static bool classof(const ForStmt *) { return true; } 544 545 // Iterators 546 virtual child_iterator child_begin(); 547 virtual child_iterator child_end(); 548}; 549 550/// GotoStmt - This represents a direct goto. 551/// 552class GotoStmt : public Stmt { 553 LabelStmt *Label; 554 SourceLocation GotoLoc; 555 SourceLocation LabelLoc; 556public: 557 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 558 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 559 560 LabelStmt *getLabel() const { return Label; } 561 562 virtual SourceRange getSourceRange() const { 563 return SourceRange(GotoLoc, LabelLoc); 564 } 565 static bool classof(const Stmt *T) { 566 return T->getStmtClass() == GotoStmtClass; 567 } 568 static bool classof(const GotoStmt *) { return true; } 569 570 // Iterators 571 virtual child_iterator child_begin(); 572 virtual child_iterator child_end(); 573}; 574 575/// IndirectGotoStmt - This represents an indirect goto. 576/// 577class IndirectGotoStmt : public Stmt { 578 Expr *Target; 579public: 580 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 581 582 Expr *getTarget() { return Target; } 583 const Expr *getTarget() const { return Target; } 584 585 virtual SourceRange getSourceRange() const { return SourceRange(); } 586 587 static bool classof(const Stmt *T) { 588 return T->getStmtClass() == IndirectGotoStmtClass; 589 } 590 static bool classof(const IndirectGotoStmt *) { return true; } 591 592 // Iterators 593 virtual child_iterator child_begin(); 594 virtual child_iterator child_end(); 595}; 596 597 598/// ContinueStmt - This represents a continue. 599/// 600class ContinueStmt : public Stmt { 601 SourceLocation ContinueLoc; 602public: 603 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 604 605 virtual SourceRange getSourceRange() const { 606 return SourceRange(ContinueLoc); 607 } 608 static bool classof(const Stmt *T) { 609 return T->getStmtClass() == ContinueStmtClass; 610 } 611 static bool classof(const ContinueStmt *) { return true; } 612 613 // Iterators 614 virtual child_iterator child_begin(); 615 virtual child_iterator child_end(); 616}; 617 618/// BreakStmt - This represents a break. 619/// 620class BreakStmt : public Stmt { 621 SourceLocation BreakLoc; 622public: 623 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 624 625 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 626 627 static bool classof(const Stmt *T) { 628 return T->getStmtClass() == BreakStmtClass; 629 } 630 static bool classof(const BreakStmt *) { return true; } 631 632 // Iterators 633 virtual child_iterator child_begin(); 634 virtual child_iterator child_end(); 635}; 636 637 638/// ReturnStmt - This represents a return, optionally of an expression. 639/// 640class ReturnStmt : public Stmt { 641 Expr *RetExpr; 642 SourceLocation RetLoc; 643public: 644 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 645 RetExpr(E), RetLoc(RL) {} 646 647 const Expr *getRetValue() const { return RetExpr; } 648 Expr *getRetValue() { return RetExpr; } 649 650 virtual SourceRange getSourceRange() const; 651 652 static bool classof(const Stmt *T) { 653 return T->getStmtClass() == ReturnStmtClass; 654 } 655 static bool classof(const ReturnStmt *) { return true; } 656 657 // Iterators 658 virtual child_iterator child_begin(); 659 virtual child_iterator child_end(); 660}; 661 662} // end namespace clang 663 664#endif 665