Stmt.h revision 0965f446e7685dc01fc0b5e718610530eed3cc63
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 void Emit(llvm::Serializer& S) const; 115 static Stmt* Materialize(llvm::Deserializer& D); 116 117 virtual void directEmit(llvm::Serializer& S) const { 118 // This method will eventually be a pure-virtual function. 119 assert (false && "Not implemented."); 120 } 121}; 122 123/// DeclStmt - Adaptor class for mixing declarations with statements and 124/// expressions. For example, CompoundStmt mixes statements, expressions 125/// and declarations (variables, types). Another example is ForStmt, where 126/// the first statement can be an expression or a declaration. 127/// 128class DeclStmt : public Stmt { 129 ScopedDecl *TheDecl; 130public: 131 DeclStmt(ScopedDecl *D) : Stmt(DeclStmtClass), TheDecl(D) {} 132 133 const ScopedDecl *getDecl() const { return TheDecl; } 134 ScopedDecl *getDecl() { return TheDecl; } 135 136 virtual SourceRange getSourceRange() const { return SourceRange(); } 137 138 static bool classof(const Stmt *T) { 139 return T->getStmtClass() == DeclStmtClass; 140 } 141 static bool classof(const DeclStmt *) { return true; } 142 143 // Iterators 144 virtual child_iterator child_begin(); 145 virtual child_iterator child_end(); 146 147 virtual void directEmit(llvm::Serializer& S) const; 148 static DeclStmt* directMaterialize(llvm::Deserializer& D); 149}; 150 151/// NullStmt - This is the null statement ";": C99 6.8.3p3. 152/// 153class NullStmt : public Stmt { 154 SourceLocation SemiLoc; 155public: 156 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 157 158 SourceLocation getSemiLoc() const { return SemiLoc; } 159 160 virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 161 162 static bool classof(const Stmt *T) { 163 return T->getStmtClass() == NullStmtClass; 164 } 165 static bool classof(const NullStmt *) { return true; } 166 167 // Iterators 168 virtual child_iterator child_begin(); 169 virtual child_iterator child_end(); 170}; 171 172/// CompoundStmt - This represents a group of statements like { stmt stmt }. 173/// 174class CompoundStmt : public Stmt { 175 llvm::SmallVector<Stmt*, 16> Body; 176 SourceLocation LBracLoc, RBracLoc; 177public: 178 CompoundStmt(Stmt **StmtStart, unsigned NumStmts, 179 SourceLocation LB, SourceLocation RB) 180 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts), 181 LBracLoc(LB), RBracLoc(RB) {} 182 183 bool body_empty() const { return Body.empty(); } 184 185 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 186 body_iterator body_begin() { return Body.begin(); } 187 body_iterator body_end() { return Body.end(); } 188 Stmt *body_back() { return Body.back(); } 189 190 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 191 const_body_iterator body_begin() const { return Body.begin(); } 192 const_body_iterator body_end() const { return Body.end(); } 193 const Stmt *body_back() const { return Body.back(); } 194 195 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 196 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 197 reverse_body_iterator body_rend() { return Body.rend(); } 198 199 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 200 const_reverse_body_iterator; 201 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 202 const_reverse_body_iterator body_rend() const { return Body.rend(); } 203 204 void push_back(Stmt *S) { Body.push_back(S); } 205 206 virtual SourceRange getSourceRange() const { 207 return SourceRange(LBracLoc, RBracLoc); 208 } 209 210 SourceLocation getLBracLoc() const { return LBracLoc; } 211 SourceLocation getRBracLoc() const { return RBracLoc; } 212 213 static bool classof(const Stmt *T) { 214 return T->getStmtClass() == CompoundStmtClass; 215 } 216 static bool classof(const CompoundStmt *) { return true; } 217 218 // Iterators 219 virtual child_iterator child_begin(); 220 virtual child_iterator child_end(); 221 222 virtual void directEmit(llvm::Serializer& S) const; 223 static CompoundStmt* directMaterialize(llvm::Deserializer& D); 224}; 225 226// SwitchCase is the base class for CaseStmt and DefaultStmt, 227class SwitchCase : public Stmt { 228 // A pointer to the following CaseStmt or DefaultStmt class, 229 // used by SwitchStmt. 230 SwitchCase *NextSwitchCase; 231protected: 232 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 233 234public: 235 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 236 237 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 238 239 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 240 241 virtual Stmt* v_getSubStmt() = 0; 242 Stmt *getSubStmt() { return v_getSubStmt(); } 243 244 virtual SourceRange getSourceRange() const { return SourceRange(); } 245 246 static bool classof(const Stmt *T) { 247 return T->getStmtClass() == CaseStmtClass || 248 T->getStmtClass() == DefaultStmtClass; 249 } 250 static bool classof(const SwitchCase *) { return true; } 251}; 252 253class CaseStmt : public SwitchCase { 254 enum { SUBSTMT, LHS, RHS, END_EXPR }; 255 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 256 // GNU "case 1 ... 4" extension 257 SourceLocation CaseLoc; 258public: 259 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 260 : SwitchCase(CaseStmtClass) { 261 SubExprs[SUBSTMT] = substmt; 262 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 263 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 264 CaseLoc = caseLoc; 265 } 266 267 SourceLocation getCaseLoc() const { return CaseLoc; } 268 269 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 270 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 271 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 272 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 273 const Expr *getLHS() const { 274 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 275 } 276 const Expr *getRHS() const { 277 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 278 } 279 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 280 281 virtual SourceRange getSourceRange() const { 282 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 283 } 284 static bool classof(const Stmt *T) { 285 return T->getStmtClass() == CaseStmtClass; 286 } 287 static bool classof(const CaseStmt *) { return true; } 288 289 // Iterators 290 virtual child_iterator child_begin(); 291 virtual child_iterator child_end(); 292}; 293 294class DefaultStmt : public SwitchCase { 295 Stmt* SubStmt; 296 SourceLocation DefaultLoc; 297public: 298 DefaultStmt(SourceLocation DL, Stmt *substmt) : 299 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 300 301 Stmt *getSubStmt() { return SubStmt; } 302 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 303 const Stmt *getSubStmt() const { return SubStmt; } 304 305 SourceLocation getDefaultLoc() const { return DefaultLoc; } 306 307 virtual SourceRange getSourceRange() const { 308 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 309 } 310 static bool classof(const Stmt *T) { 311 return T->getStmtClass() == DefaultStmtClass; 312 } 313 static bool classof(const DefaultStmt *) { return true; } 314 315 // Iterators 316 virtual child_iterator child_begin(); 317 virtual child_iterator child_end(); 318}; 319 320class LabelStmt : public Stmt { 321 IdentifierInfo *Label; 322 Stmt *SubStmt; 323 SourceLocation IdentLoc; 324public: 325 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 326 : Stmt(LabelStmtClass), Label(label), 327 SubStmt(substmt), IdentLoc(IL) {} 328 329 SourceLocation getIdentLoc() const { return IdentLoc; } 330 IdentifierInfo *getID() const { return Label; } 331 const char *getName() const; 332 Stmt *getSubStmt() { return SubStmt; } 333 const Stmt *getSubStmt() const { return SubStmt; } 334 335 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 336 void setSubStmt(Stmt *SS) { SubStmt = SS; } 337 338 virtual SourceRange getSourceRange() const { 339 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 340 } 341 static bool classof(const Stmt *T) { 342 return T->getStmtClass() == LabelStmtClass; 343 } 344 static bool classof(const LabelStmt *) { return true; } 345 346 // Iterators 347 virtual child_iterator child_begin(); 348 virtual child_iterator child_end(); 349}; 350 351 352/// IfStmt - This represents an if/then/else. 353/// 354class IfStmt : public Stmt { 355 enum { COND, THEN, ELSE, END_EXPR }; 356 Stmt* SubExprs[END_EXPR]; 357 SourceLocation IfLoc; 358public: 359 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 360 : Stmt(IfStmtClass) { 361 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 362 SubExprs[THEN] = then; 363 SubExprs[ELSE] = elsev; 364 IfLoc = IL; 365 } 366 367 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 368 const Stmt *getThen() const { return SubExprs[THEN]; } 369 const Stmt *getElse() const { return SubExprs[ELSE]; } 370 371 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 372 Stmt *getThen() { return SubExprs[THEN]; } 373 Stmt *getElse() { return SubExprs[ELSE]; } 374 375 virtual SourceRange getSourceRange() const { 376 if (SubExprs[ELSE]) 377 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 378 else 379 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 380 } 381 382 static bool classof(const Stmt *T) { 383 return T->getStmtClass() == IfStmtClass; 384 } 385 static bool classof(const IfStmt *) { return true; } 386 387 // Iterators 388 virtual child_iterator child_begin(); 389 virtual child_iterator child_end(); 390}; 391 392/// SwitchStmt - This represents a 'switch' stmt. 393/// 394class SwitchStmt : public Stmt { 395 enum { COND, BODY, END_EXPR }; 396 Stmt* SubExprs[END_EXPR]; 397 // This points to a linked list of case and default statements. 398 SwitchCase *FirstCase; 399 SourceLocation SwitchLoc; 400public: 401 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 402 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 403 SubExprs[BODY] = NULL; 404 } 405 406 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 407 const Stmt *getBody() const { return SubExprs[BODY]; } 408 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 409 410 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 411 Stmt *getBody() { return SubExprs[BODY]; } 412 SwitchCase *getSwitchCaseList() { return FirstCase; } 413 414 void setBody(Stmt *S, SourceLocation SL) { 415 SubExprs[BODY] = S; 416 SwitchLoc = SL; 417 } 418 void addSwitchCase(SwitchCase *SC) { 419 if (FirstCase) 420 SC->setNextSwitchCase(FirstCase); 421 422 FirstCase = SC; 423 } 424 virtual SourceRange getSourceRange() const { 425 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 426 } 427 static bool classof(const Stmt *T) { 428 return T->getStmtClass() == SwitchStmtClass; 429 } 430 static bool classof(const SwitchStmt *) { return true; } 431 432 // Iterators 433 virtual child_iterator child_begin(); 434 virtual child_iterator child_end(); 435}; 436 437 438/// WhileStmt - This represents a 'while' stmt. 439/// 440class WhileStmt : public Stmt { 441 enum { COND, BODY, END_EXPR }; 442 Stmt* SubExprs[END_EXPR]; 443 SourceLocation WhileLoc; 444public: 445 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 446 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 447 SubExprs[BODY] = body; 448 WhileLoc = WL; 449 } 450 451 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 452 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 453 Stmt *getBody() { return SubExprs[BODY]; } 454 const Stmt *getBody() const { return SubExprs[BODY]; } 455 456 virtual SourceRange getSourceRange() const { 457 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 458 } 459 static bool classof(const Stmt *T) { 460 return T->getStmtClass() == WhileStmtClass; 461 } 462 static bool classof(const WhileStmt *) { return true; } 463 464 // Iterators 465 virtual child_iterator child_begin(); 466 virtual child_iterator child_end(); 467}; 468 469/// DoStmt - This represents a 'do/while' stmt. 470/// 471class DoStmt : public Stmt { 472 enum { COND, BODY, END_EXPR }; 473 Stmt* SubExprs[END_EXPR]; 474 SourceLocation DoLoc; 475public: 476 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 477 : Stmt(DoStmtClass), DoLoc(DL) { 478 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 479 SubExprs[BODY] = body; 480 DoLoc = DL; 481 } 482 483 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 484 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 485 Stmt *getBody() { return SubExprs[BODY]; } 486 const Stmt *getBody() const { return SubExprs[BODY]; } 487 488 virtual SourceRange getSourceRange() const { 489 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 490 } 491 static bool classof(const Stmt *T) { 492 return T->getStmtClass() == DoStmtClass; 493 } 494 static bool classof(const DoStmt *) { return true; } 495 496 // Iterators 497 virtual child_iterator child_begin(); 498 virtual child_iterator child_end(); 499}; 500 501 502/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 503/// the init/cond/inc parts of the ForStmt will be null if they were not 504/// specified in the source. 505/// 506class ForStmt : public Stmt { 507 enum { INIT, COND, INC, BODY, END_EXPR }; 508 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 509 SourceLocation ForLoc; 510public: 511 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 512 : Stmt(ForStmtClass) { 513 SubExprs[INIT] = Init; 514 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 515 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 516 SubExprs[BODY] = Body; 517 ForLoc = FL; 518 } 519 520 Stmt *getInit() { return SubExprs[INIT]; } 521 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 522 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 523 Stmt *getBody() { return SubExprs[BODY]; } 524 525 const Stmt *getInit() const { return SubExprs[INIT]; } 526 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 527 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 528 const Stmt *getBody() const { return SubExprs[BODY]; } 529 530 virtual SourceRange getSourceRange() const { 531 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 532 } 533 static bool classof(const Stmt *T) { 534 return T->getStmtClass() == ForStmtClass; 535 } 536 static bool classof(const ForStmt *) { return true; } 537 538 // Iterators 539 virtual child_iterator child_begin(); 540 virtual child_iterator child_end(); 541}; 542 543/// GotoStmt - This represents a direct goto. 544/// 545class GotoStmt : public Stmt { 546 LabelStmt *Label; 547 SourceLocation GotoLoc; 548 SourceLocation LabelLoc; 549public: 550 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 551 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 552 553 LabelStmt *getLabel() const { return Label; } 554 555 virtual SourceRange getSourceRange() const { 556 return SourceRange(GotoLoc, LabelLoc); 557 } 558 static bool classof(const Stmt *T) { 559 return T->getStmtClass() == GotoStmtClass; 560 } 561 static bool classof(const GotoStmt *) { return true; } 562 563 // Iterators 564 virtual child_iterator child_begin(); 565 virtual child_iterator child_end(); 566}; 567 568/// IndirectGotoStmt - This represents an indirect goto. 569/// 570class IndirectGotoStmt : public Stmt { 571 Expr *Target; 572public: 573 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 574 575 Expr *getTarget() { return Target; } 576 const Expr *getTarget() const { return Target; } 577 578 virtual SourceRange getSourceRange() const { return SourceRange(); } 579 580 static bool classof(const Stmt *T) { 581 return T->getStmtClass() == IndirectGotoStmtClass; 582 } 583 static bool classof(const IndirectGotoStmt *) { return true; } 584 585 // Iterators 586 virtual child_iterator child_begin(); 587 virtual child_iterator child_end(); 588}; 589 590 591/// ContinueStmt - This represents a continue. 592/// 593class ContinueStmt : public Stmt { 594 SourceLocation ContinueLoc; 595public: 596 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 597 598 virtual SourceRange getSourceRange() const { 599 return SourceRange(ContinueLoc); 600 } 601 static bool classof(const Stmt *T) { 602 return T->getStmtClass() == ContinueStmtClass; 603 } 604 static bool classof(const ContinueStmt *) { return true; } 605 606 // Iterators 607 virtual child_iterator child_begin(); 608 virtual child_iterator child_end(); 609}; 610 611/// BreakStmt - This represents a break. 612/// 613class BreakStmt : public Stmt { 614 SourceLocation BreakLoc; 615public: 616 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 617 618 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 619 620 static bool classof(const Stmt *T) { 621 return T->getStmtClass() == BreakStmtClass; 622 } 623 static bool classof(const BreakStmt *) { return true; } 624 625 // Iterators 626 virtual child_iterator child_begin(); 627 virtual child_iterator child_end(); 628}; 629 630 631/// ReturnStmt - This represents a return, optionally of an expression. 632/// 633class ReturnStmt : public Stmt { 634 Expr *RetExpr; 635 SourceLocation RetLoc; 636public: 637 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 638 RetExpr(E), RetLoc(RL) {} 639 640 const Expr *getRetValue() const { return RetExpr; } 641 Expr *getRetValue() { return RetExpr; } 642 643 virtual SourceRange getSourceRange() const; 644 645 static bool classof(const Stmt *T) { 646 return T->getStmtClass() == ReturnStmtClass; 647 } 648 static bool classof(const ReturnStmt *) { return true; } 649 650 // Iterators 651 virtual child_iterator child_begin(); 652 virtual child_iterator child_end(); 653 654 virtual void directEmit(llvm::Serializer& S) const; 655 static ReturnStmt* directMaterialize(llvm::Deserializer& D); 656}; 657 658/// AsmStmt - This represents a GNU inline-assembly statement extension. 659/// 660class AsmStmt : public Stmt { 661 SourceLocation AsmLoc, RParenLoc; 662 // FIXME: This doesn't capture most of the interesting pieces. 663public: 664 AsmStmt(SourceLocation asmloc, SourceLocation rparenloc) 665 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {} 666 667 virtual SourceRange getSourceRange() const { 668 return SourceRange(AsmLoc, RParenLoc); 669 } 670 671 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 672 static bool classof(const AsmStmt *) { return true; } 673 674 virtual child_iterator child_begin(); 675 virtual child_iterator child_end(); 676}; 677 678/// ObjcAtCatchStmt - This represents objective-c's @catch statement. 679class ObjcAtCatchStmt : public Stmt { 680private: 681 // Points to next @catch statement, or null 682 ObjcAtCatchStmt *NextAtCatchStmt; 683 enum { SELECTOR, BODY, END_EXPR }; 684 Stmt *SubExprs[END_EXPR]; 685 SourceLocation AtCatchLoc, RParenLoc; 686 687public: 688 ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 689 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList) 690 : Stmt(ObjcAtCatchStmtClass), 691 AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { 692 SubExprs[SELECTOR] = catchVarStmtDecl; 693 SubExprs[BODY] = atCatchStmt; 694 SubExprs[END_EXPR] = NULL; 695 if (!atCatchList) 696 NextAtCatchStmt = NULL; 697 else { 698 ObjcAtCatchStmt *AtCatchList = 699 static_cast<ObjcAtCatchStmt*>(atCatchList); 700 while (AtCatchList->NextAtCatchStmt) 701 AtCatchList = AtCatchList->NextAtCatchStmt; 702 AtCatchList->NextAtCatchStmt = this; 703 } 704 } 705 706 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 707 Stmt *getCatchBody() { return SubExprs[BODY]; } 708 const Stmt *getNextCatchStmt() const { return NextAtCatchStmt; } 709 Stmt *getNextCatchStmt() { return NextAtCatchStmt; } 710 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 711 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 712 713 virtual SourceRange getSourceRange() const { 714 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 715 } 716 717 static bool classof(const Stmt *T) { 718 return T->getStmtClass() == ObjcAtCatchStmtClass; 719 } 720 static bool classof(const ObjcAtCatchStmt *) { return true; } 721 722 virtual child_iterator child_begin(); 723 virtual child_iterator child_end(); 724 725}; 726 727/// ObjcAtFinallyStmt - This represent objective-c's @finally Statement 728class ObjcAtFinallyStmt : public Stmt { 729 private: 730 Stmt *AtFinallyStmt; 731 SourceLocation AtFinallyLoc; 732 733 public: 734 ObjcAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 735 : Stmt(ObjcAtFinallyStmtClass), 736 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 737 738 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 739 Stmt *getFinallyBody () { return AtFinallyStmt; } 740 741 virtual SourceRange getSourceRange() const { 742 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 743 } 744 745 static bool classof(const Stmt *T) { 746 return T->getStmtClass() == ObjcAtFinallyStmtClass; 747 } 748 static bool classof(const ObjcAtFinallyStmt *) { return true; } 749 750 virtual child_iterator child_begin(); 751 virtual child_iterator child_end(); 752 753}; 754 755/// ObjcAtTryStmt - This represent objective-c's over-all 756/// @try ... @catch ... @finally statement. 757class ObjcAtTryStmt : public Stmt { 758private: 759 enum { TRY, CATCH, FINALLY, END_TRY }; 760 Stmt* SubStmts[END_TRY]; 761 762 SourceLocation AtTryLoc; 763 764public: 765 ObjcAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 766 Stmt *atCatchStmt, 767 Stmt *atFinallyStmt) 768 : Stmt(ObjcAtTryStmtClass) { 769 SubStmts[TRY] = atTryStmt; 770 SubStmts[CATCH] = atCatchStmt; 771 SubStmts[FINALLY] = atFinallyStmt; 772 SubStmts[END_TRY] = NULL; 773 AtTryLoc = atTryLoc; 774 } 775 776 const Stmt *getTryBody() const { return SubStmts[TRY]; } 777 Stmt *getTryBody() { return SubStmts[TRY]; } 778 const Stmt *getCatchStmts() const { return SubStmts[CATCH]; } 779 Stmt *getCatchStmts() { return SubStmts[CATCH]; } 780 const Stmt *getFinallyStmt() const { return SubStmts[FINALLY]; } 781 Stmt *getFinallyStmt() { return SubStmts[FINALLY]; } 782 783 virtual SourceRange getSourceRange() const { 784 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 785 } 786 787 static bool classof(const Stmt *T) { 788 return T->getStmtClass() == ObjcAtTryStmtClass; 789 } 790 static bool classof(const ObjcAtTryStmt *) { return true; } 791 792 virtual child_iterator child_begin(); 793 virtual child_iterator child_end(); 794 795}; 796 797} // end namespace clang 798 799#endif 800