Stmt.h revision 39f8f159c488a900e5958d5aab3e467af9ec8a2b
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 virtual void directEmit(llvm::Serializer& S) const; 172 static NullStmt* directMaterialize(llvm::Deserializer& D); 173}; 174 175/// CompoundStmt - This represents a group of statements like { stmt stmt }. 176/// 177class CompoundStmt : public Stmt { 178 llvm::SmallVector<Stmt*, 16> Body; 179 SourceLocation LBracLoc, RBracLoc; 180public: 181 CompoundStmt(Stmt **StmtStart, unsigned NumStmts, 182 SourceLocation LB, SourceLocation RB) 183 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts), 184 LBracLoc(LB), RBracLoc(RB) {} 185 186 bool body_empty() const { return Body.empty(); } 187 188 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 189 body_iterator body_begin() { return Body.begin(); } 190 body_iterator body_end() { return Body.end(); } 191 Stmt *body_back() { return Body.back(); } 192 193 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 194 const_body_iterator body_begin() const { return Body.begin(); } 195 const_body_iterator body_end() const { return Body.end(); } 196 const Stmt *body_back() const { return Body.back(); } 197 198 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 199 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 200 reverse_body_iterator body_rend() { return Body.rend(); } 201 202 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 203 const_reverse_body_iterator; 204 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 205 const_reverse_body_iterator body_rend() const { return Body.rend(); } 206 207 void push_back(Stmt *S) { Body.push_back(S); } 208 209 virtual SourceRange getSourceRange() const { 210 return SourceRange(LBracLoc, RBracLoc); 211 } 212 213 SourceLocation getLBracLoc() const { return LBracLoc; } 214 SourceLocation getRBracLoc() const { return RBracLoc; } 215 216 static bool classof(const Stmt *T) { 217 return T->getStmtClass() == CompoundStmtClass; 218 } 219 static bool classof(const CompoundStmt *) { return true; } 220 221 // Iterators 222 virtual child_iterator child_begin(); 223 virtual child_iterator child_end(); 224 225 virtual void directEmit(llvm::Serializer& S) const; 226 static CompoundStmt* directMaterialize(llvm::Deserializer& D); 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 virtual void directEmit(llvm::Serializer& S) const; 354 static LabelStmt* directMaterialize(llvm::Deserializer& D); 355}; 356 357 358/// IfStmt - This represents an if/then/else. 359/// 360class IfStmt : public Stmt { 361 enum { COND, THEN, ELSE, END_EXPR }; 362 Stmt* SubExprs[END_EXPR]; 363 SourceLocation IfLoc; 364public: 365 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 366 : Stmt(IfStmtClass) { 367 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 368 SubExprs[THEN] = then; 369 SubExprs[ELSE] = elsev; 370 IfLoc = IL; 371 } 372 373 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 374 const Stmt *getThen() const { return SubExprs[THEN]; } 375 const Stmt *getElse() const { return SubExprs[ELSE]; } 376 377 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 378 Stmt *getThen() { return SubExprs[THEN]; } 379 Stmt *getElse() { return SubExprs[ELSE]; } 380 381 virtual SourceRange getSourceRange() const { 382 if (SubExprs[ELSE]) 383 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 384 else 385 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 386 } 387 388 static bool classof(const Stmt *T) { 389 return T->getStmtClass() == IfStmtClass; 390 } 391 static bool classof(const IfStmt *) { return true; } 392 393 // Iterators 394 virtual child_iterator child_begin(); 395 virtual child_iterator child_end(); 396}; 397 398/// SwitchStmt - This represents a 'switch' stmt. 399/// 400class SwitchStmt : public Stmt { 401 enum { COND, BODY, END_EXPR }; 402 Stmt* SubExprs[END_EXPR]; 403 // This points to a linked list of case and default statements. 404 SwitchCase *FirstCase; 405 SourceLocation SwitchLoc; 406public: 407 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 408 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 409 SubExprs[BODY] = NULL; 410 } 411 412 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 413 const Stmt *getBody() const { return SubExprs[BODY]; } 414 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 415 416 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 417 Stmt *getBody() { return SubExprs[BODY]; } 418 SwitchCase *getSwitchCaseList() { return FirstCase; } 419 420 void setBody(Stmt *S, SourceLocation SL) { 421 SubExprs[BODY] = S; 422 SwitchLoc = SL; 423 } 424 void addSwitchCase(SwitchCase *SC) { 425 if (FirstCase) 426 SC->setNextSwitchCase(FirstCase); 427 428 FirstCase = SC; 429 } 430 virtual SourceRange getSourceRange() const { 431 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 432 } 433 static bool classof(const Stmt *T) { 434 return T->getStmtClass() == SwitchStmtClass; 435 } 436 static bool classof(const SwitchStmt *) { return true; } 437 438 // Iterators 439 virtual child_iterator child_begin(); 440 virtual child_iterator child_end(); 441}; 442 443 444/// WhileStmt - This represents a 'while' stmt. 445/// 446class WhileStmt : public Stmt { 447 enum { COND, BODY, END_EXPR }; 448 Stmt* SubExprs[END_EXPR]; 449 SourceLocation WhileLoc; 450public: 451 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 452 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 453 SubExprs[BODY] = body; 454 WhileLoc = WL; 455 } 456 457 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 458 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 459 Stmt *getBody() { return SubExprs[BODY]; } 460 const Stmt *getBody() const { return SubExprs[BODY]; } 461 462 virtual SourceRange getSourceRange() const { 463 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 464 } 465 static bool classof(const Stmt *T) { 466 return T->getStmtClass() == WhileStmtClass; 467 } 468 static bool classof(const WhileStmt *) { return true; } 469 470 // Iterators 471 virtual child_iterator child_begin(); 472 virtual child_iterator child_end(); 473}; 474 475/// DoStmt - This represents a 'do/while' stmt. 476/// 477class DoStmt : public Stmt { 478 enum { COND, BODY, END_EXPR }; 479 Stmt* SubExprs[END_EXPR]; 480 SourceLocation DoLoc; 481public: 482 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 483 : Stmt(DoStmtClass), DoLoc(DL) { 484 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 485 SubExprs[BODY] = body; 486 DoLoc = DL; 487 } 488 489 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 490 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 491 Stmt *getBody() { return SubExprs[BODY]; } 492 const Stmt *getBody() const { return SubExprs[BODY]; } 493 494 virtual SourceRange getSourceRange() const { 495 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 496 } 497 static bool classof(const Stmt *T) { 498 return T->getStmtClass() == DoStmtClass; 499 } 500 static bool classof(const DoStmt *) { return true; } 501 502 // Iterators 503 virtual child_iterator child_begin(); 504 virtual child_iterator child_end(); 505}; 506 507 508/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 509/// the init/cond/inc parts of the ForStmt will be null if they were not 510/// specified in the source. 511/// 512class ForStmt : public Stmt { 513 enum { INIT, COND, INC, BODY, END_EXPR }; 514 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 515 SourceLocation ForLoc; 516public: 517 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 518 : Stmt(ForStmtClass) { 519 SubExprs[INIT] = Init; 520 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 521 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 522 SubExprs[BODY] = Body; 523 ForLoc = FL; 524 } 525 526 Stmt *getInit() { return SubExprs[INIT]; } 527 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 528 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 529 Stmt *getBody() { return SubExprs[BODY]; } 530 531 const Stmt *getInit() const { return SubExprs[INIT]; } 532 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 533 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 534 const Stmt *getBody() const { return SubExprs[BODY]; } 535 536 virtual SourceRange getSourceRange() const { 537 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 538 } 539 static bool classof(const Stmt *T) { 540 return T->getStmtClass() == ForStmtClass; 541 } 542 static bool classof(const ForStmt *) { return true; } 543 544 // Iterators 545 virtual child_iterator child_begin(); 546 virtual child_iterator child_end(); 547}; 548 549/// GotoStmt - This represents a direct goto. 550/// 551class GotoStmt : public Stmt { 552 LabelStmt *Label; 553 SourceLocation GotoLoc; 554 SourceLocation LabelLoc; 555public: 556 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 557 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 558 559 LabelStmt *getLabel() const { return Label; } 560 561 virtual SourceRange getSourceRange() const { 562 return SourceRange(GotoLoc, LabelLoc); 563 } 564 static bool classof(const Stmt *T) { 565 return T->getStmtClass() == GotoStmtClass; 566 } 567 static bool classof(const GotoStmt *) { return true; } 568 569 // Iterators 570 virtual child_iterator child_begin(); 571 virtual child_iterator child_end(); 572}; 573 574/// IndirectGotoStmt - This represents an indirect goto. 575/// 576class IndirectGotoStmt : public Stmt { 577 Expr *Target; 578public: 579 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 580 581 Expr *getTarget() { return Target; } 582 const Expr *getTarget() const { return Target; } 583 584 virtual SourceRange getSourceRange() const { return SourceRange(); } 585 586 static bool classof(const Stmt *T) { 587 return T->getStmtClass() == IndirectGotoStmtClass; 588 } 589 static bool classof(const IndirectGotoStmt *) { return true; } 590 591 // Iterators 592 virtual child_iterator child_begin(); 593 virtual child_iterator child_end(); 594}; 595 596 597/// ContinueStmt - This represents a continue. 598/// 599class ContinueStmt : public Stmt { 600 SourceLocation ContinueLoc; 601public: 602 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 603 604 virtual SourceRange getSourceRange() const { 605 return SourceRange(ContinueLoc); 606 } 607 static bool classof(const Stmt *T) { 608 return T->getStmtClass() == ContinueStmtClass; 609 } 610 static bool classof(const ContinueStmt *) { return true; } 611 612 // Iterators 613 virtual child_iterator child_begin(); 614 virtual child_iterator child_end(); 615}; 616 617/// BreakStmt - This represents a break. 618/// 619class BreakStmt : public Stmt { 620 SourceLocation BreakLoc; 621public: 622 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 623 624 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 625 626 static bool classof(const Stmt *T) { 627 return T->getStmtClass() == BreakStmtClass; 628 } 629 static bool classof(const BreakStmt *) { return true; } 630 631 // Iterators 632 virtual child_iterator child_begin(); 633 virtual child_iterator child_end(); 634}; 635 636 637/// ReturnStmt - This represents a return, optionally of an expression. 638/// 639class ReturnStmt : public Stmt { 640 Expr *RetExpr; 641 SourceLocation RetLoc; 642public: 643 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 644 RetExpr(E), RetLoc(RL) {} 645 646 const Expr *getRetValue() const { return RetExpr; } 647 Expr *getRetValue() { return RetExpr; } 648 649 virtual SourceRange getSourceRange() const; 650 651 static bool classof(const Stmt *T) { 652 return T->getStmtClass() == ReturnStmtClass; 653 } 654 static bool classof(const ReturnStmt *) { return true; } 655 656 // Iterators 657 virtual child_iterator child_begin(); 658 virtual child_iterator child_end(); 659 660 virtual void directEmit(llvm::Serializer& S) const; 661 static ReturnStmt* directMaterialize(llvm::Deserializer& D); 662}; 663 664/// AsmStmt - This represents a GNU inline-assembly statement extension. 665/// 666class AsmStmt : public Stmt { 667 SourceLocation AsmLoc, RParenLoc; 668 // FIXME: This doesn't capture most of the interesting pieces. 669public: 670 AsmStmt(SourceLocation asmloc, SourceLocation rparenloc) 671 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {} 672 673 virtual SourceRange getSourceRange() const { 674 return SourceRange(AsmLoc, RParenLoc); 675 } 676 677 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 678 static bool classof(const AsmStmt *) { return true; } 679 680 virtual child_iterator child_begin(); 681 virtual child_iterator child_end(); 682}; 683 684/// ObjcAtCatchStmt - This represents objective-c's @catch statement. 685class ObjcAtCatchStmt : public Stmt { 686private: 687 // Points to next @catch statement, or null 688 ObjcAtCatchStmt *NextAtCatchStmt; 689 enum { SELECTOR, BODY, END_EXPR }; 690 Stmt *SubExprs[END_EXPR]; 691 SourceLocation AtCatchLoc, RParenLoc; 692 693public: 694 ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 695 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList) 696 : Stmt(ObjcAtCatchStmtClass), 697 AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { 698 SubExprs[SELECTOR] = catchVarStmtDecl; 699 SubExprs[BODY] = atCatchStmt; 700 SubExprs[END_EXPR] = NULL; 701 if (!atCatchList) 702 NextAtCatchStmt = NULL; 703 else { 704 ObjcAtCatchStmt *AtCatchList = 705 static_cast<ObjcAtCatchStmt*>(atCatchList); 706 while (AtCatchList->NextAtCatchStmt) 707 AtCatchList = AtCatchList->NextAtCatchStmt; 708 AtCatchList->NextAtCatchStmt = this; 709 } 710 } 711 712 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 713 Stmt *getCatchBody() { return SubExprs[BODY]; } 714 const Stmt *getNextCatchStmt() const { return NextAtCatchStmt; } 715 Stmt *getNextCatchStmt() { return NextAtCatchStmt; } 716 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 717 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 718 719 virtual SourceRange getSourceRange() const { 720 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 721 } 722 723 static bool classof(const Stmt *T) { 724 return T->getStmtClass() == ObjcAtCatchStmtClass; 725 } 726 static bool classof(const ObjcAtCatchStmt *) { return true; } 727 728 virtual child_iterator child_begin(); 729 virtual child_iterator child_end(); 730 731}; 732 733/// ObjcAtFinallyStmt - This represent objective-c's @finally Statement 734class ObjcAtFinallyStmt : public Stmt { 735 private: 736 Stmt *AtFinallyStmt; 737 SourceLocation AtFinallyLoc; 738 739 public: 740 ObjcAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 741 : Stmt(ObjcAtFinallyStmtClass), 742 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 743 744 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 745 Stmt *getFinallyBody () { return AtFinallyStmt; } 746 747 virtual SourceRange getSourceRange() const { 748 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 749 } 750 751 static bool classof(const Stmt *T) { 752 return T->getStmtClass() == ObjcAtFinallyStmtClass; 753 } 754 static bool classof(const ObjcAtFinallyStmt *) { return true; } 755 756 virtual child_iterator child_begin(); 757 virtual child_iterator child_end(); 758 759}; 760 761/// ObjcAtTryStmt - This represent objective-c's over-all 762/// @try ... @catch ... @finally statement. 763class ObjcAtTryStmt : public Stmt { 764private: 765 enum { TRY, CATCH, FINALLY, END_TRY }; 766 Stmt* SubStmts[END_TRY]; 767 768 SourceLocation AtTryLoc; 769 770public: 771 ObjcAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 772 Stmt *atCatchStmt, 773 Stmt *atFinallyStmt) 774 : Stmt(ObjcAtTryStmtClass) { 775 SubStmts[TRY] = atTryStmt; 776 SubStmts[CATCH] = atCatchStmt; 777 SubStmts[FINALLY] = atFinallyStmt; 778 SubStmts[END_TRY] = NULL; 779 AtTryLoc = atTryLoc; 780 } 781 782 const Stmt *getTryBody() const { return SubStmts[TRY]; } 783 Stmt *getTryBody() { return SubStmts[TRY]; } 784 const Stmt *getCatchStmts() const { return SubStmts[CATCH]; } 785 Stmt *getCatchStmts() { return SubStmts[CATCH]; } 786 const Stmt *getFinallyStmt() const { return SubStmts[FINALLY]; } 787 Stmt *getFinallyStmt() { return SubStmts[FINALLY]; } 788 789 virtual SourceRange getSourceRange() const { 790 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 791 } 792 793 static bool classof(const Stmt *T) { 794 return T->getStmtClass() == ObjcAtTryStmtClass; 795 } 796 static bool classof(const ObjcAtTryStmt *) { return true; } 797 798 virtual child_iterator child_begin(); 799 virtual child_iterator child_end(); 800 801}; 802 803/// ObjcAtThrowStmt - This represents objective-c's @throw statement. 804class ObjcAtThrowStmt : public Stmt { 805private: 806 Stmt *Throw; 807 SourceLocation AtThrowLoc; 808 809public: 810 ObjcAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 811 : Stmt(ObjcAtThrowStmtClass), Throw(throwExpr) { 812 AtThrowLoc = atThrowLoc; 813 } 814 815 Expr *const getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 816 817 virtual SourceRange getSourceRange() const { 818 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 819 } 820 821 static bool classof(const Stmt *T) { 822 return T->getStmtClass() == ObjcAtThrowStmtClass; 823 } 824 static bool classof(const ObjcAtThrowStmt *) { return true; } 825 826 virtual child_iterator child_begin(); 827 virtual child_iterator child_end(); 828}; 829 830} // end namespace clang 831 832#endif 833