Stmt.h revision 3f0767b74b16b37bcce60ff457609161a0665784
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 "llvm/Support/Casting.h" 18#include "clang/Basic/SourceLocation.h" 19#include "clang/AST/StmtIterator.h" 20#include "llvm/ADT/SmallVector.h" 21#include "llvm/ADT/iterator" 22#include "llvm/Bitcode/SerializationFwd.h" 23#include <iosfwd> 24 25using llvm::dyn_cast_or_null; 26 27namespace clang { 28 class Expr; 29 class Decl; 30 class ScopedDecl; 31 class IdentifierInfo; 32 class SourceManager; 33 class SwitchStmt; 34 class PrinterHelper; 35 36/// Stmt - This represents one statement. 37/// 38class Stmt { 39public: 40 enum StmtClass { 41#define STMT(N, CLASS, PARENT) CLASS##Class = N, 42#define FIRST_STMT(N) firstStmtConstant = N, 43#define LAST_STMT(N) lastStmtConstant = N, 44#define FIRST_EXPR(N) firstExprConstant = N, 45#define LAST_EXPR(N) lastExprConstant = N 46#include "clang/AST/StmtNodes.def" 47}; 48private: 49 const StmtClass sClass; 50public: 51 Stmt(StmtClass SC) : sClass(SC) { 52 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 53 } 54 virtual ~Stmt() {} 55 56 StmtClass getStmtClass() const { return sClass; } 57 const char *getStmtClassName() const; 58 59 /// SourceLocation tokens are not useful in isolation - they are low level 60 /// value objects created/interpreted by SourceManager. We assume AST 61 /// clients will have a pointer to the respective SourceManager. 62 virtual SourceRange getSourceRange() const = 0; 63 SourceLocation getLocStart() const { return getSourceRange().getBegin(); } 64 SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } 65 66 // global temp stats (until we have a per-module visitor) 67 static void addStmtClass(const StmtClass s); 68 static bool CollectingStats(bool enable=false); 69 static void PrintStats(); 70 71 /// dump - This does a local dump of the specified AST fragment. It dumps the 72 /// specified node and a few nodes underneath it, but not the whole subtree. 73 /// This is useful in a debugger. 74 void dump() const; 75 void dump(SourceManager &SM) const; 76 77 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 78 void dumpAll() const; 79 void dumpAll(SourceManager &SM) const; 80 81 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 82 /// back to its original source language syntax. 83 void dumpPretty() const; 84 void printPretty(std::ostream &OS, PrinterHelper* = NULL) const; 85 86 /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 87 /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 88 void viewAST() const; 89 90 // Implement isa<T> support. 91 static bool classof(const Stmt *) { return true; } 92 93 /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) 94 /// contain implicit control-flow in the order their subexpressions 95 /// are evaluated. This predicate returns true if this statement has 96 /// such implicit control-flow. Such statements are also specially handled 97 /// within CFGs. 98 bool hasImplicitControlFlow() const; 99 100 /// Child Iterators: All subclasses must implement child_begin and child_end 101 /// to permit easy iteration over the substatements/subexpessions of an 102 /// AST node. This permits easy iteration over all nodes in the AST. 103 typedef StmtIterator child_iterator; 104 typedef ConstStmtIterator const_child_iterator; 105 106 virtual child_iterator child_begin() = 0; 107 virtual child_iterator child_end() = 0; 108 109 const_child_iterator child_begin() const { 110 return const_child_iterator(const_cast<Stmt*>(this)->child_begin()); 111 } 112 113 const_child_iterator child_end() const { 114 return const_child_iterator(const_cast<Stmt*>(this)->child_end()); 115 } 116 117 void Emit(llvm::Serializer& S) const; 118 static Stmt* Materialize(llvm::Deserializer& D); 119 120 virtual void directEmit(llvm::Serializer& S) const { 121 // This method will eventually be a pure-virtual function. 122 assert (false && "Not implemented."); 123 } 124}; 125 126/// DeclStmt - Adaptor class for mixing declarations with statements and 127/// expressions. For example, CompoundStmt mixes statements, expressions 128/// and declarations (variables, types). Another example is ForStmt, where 129/// the first statement can be an expression or a declaration. 130/// 131class DeclStmt : public Stmt { 132 ScopedDecl *TheDecl; 133public: 134 DeclStmt(ScopedDecl *D) : Stmt(DeclStmtClass), TheDecl(D) {} 135 136 const ScopedDecl *getDecl() const { return TheDecl; } 137 ScopedDecl *getDecl() { return TheDecl; } 138 139 virtual SourceRange getSourceRange() const { return SourceRange(); } 140 141 static bool classof(const Stmt *T) { 142 return T->getStmtClass() == DeclStmtClass; 143 } 144 static bool classof(const DeclStmt *) { return true; } 145 146 // Iterators 147 virtual child_iterator child_begin(); 148 virtual child_iterator child_end(); 149 150 virtual void directEmit(llvm::Serializer& S) const; 151 static DeclStmt* directMaterialize(llvm::Deserializer& D); 152}; 153 154/// NullStmt - This is the null statement ";": C99 6.8.3p3. 155/// 156class NullStmt : public Stmt { 157 SourceLocation SemiLoc; 158public: 159 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 160 161 SourceLocation getSemiLoc() const { return SemiLoc; } 162 163 virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 164 165 static bool classof(const Stmt *T) { 166 return T->getStmtClass() == NullStmtClass; 167 } 168 static bool classof(const NullStmt *) { return true; } 169 170 // Iterators 171 virtual child_iterator child_begin(); 172 virtual child_iterator child_end(); 173 174 virtual void directEmit(llvm::Serializer& S) const; 175 static NullStmt* directMaterialize(llvm::Deserializer& D); 176}; 177 178/// CompoundStmt - This represents a group of statements like { stmt stmt }. 179/// 180class CompoundStmt : public Stmt { 181 llvm::SmallVector<Stmt*, 16> Body; 182 SourceLocation LBracLoc, RBracLoc; 183public: 184 CompoundStmt(Stmt **StmtStart, unsigned NumStmts, 185 SourceLocation LB, SourceLocation RB) 186 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts), 187 LBracLoc(LB), RBracLoc(RB) {} 188 189 bool body_empty() const { return Body.empty(); } 190 191 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 192 body_iterator body_begin() { return Body.begin(); } 193 body_iterator body_end() { return Body.end(); } 194 Stmt *body_back() { return Body.back(); } 195 196 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 197 const_body_iterator body_begin() const { return Body.begin(); } 198 const_body_iterator body_end() const { return Body.end(); } 199 const Stmt *body_back() const { return Body.back(); } 200 201 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 202 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 203 reverse_body_iterator body_rend() { return Body.rend(); } 204 205 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 206 const_reverse_body_iterator; 207 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 208 const_reverse_body_iterator body_rend() const { return Body.rend(); } 209 210 void push_back(Stmt *S) { Body.push_back(S); } 211 212 virtual SourceRange getSourceRange() const { 213 return SourceRange(LBracLoc, RBracLoc); 214 } 215 216 SourceLocation getLBracLoc() const { return LBracLoc; } 217 SourceLocation getRBracLoc() const { return 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 virtual void directEmit(llvm::Serializer& S) const; 229 static CompoundStmt* directMaterialize(llvm::Deserializer& D); 230}; 231 232// SwitchCase is the base class for CaseStmt and DefaultStmt, 233class SwitchCase : public Stmt { 234 // A pointer to the following CaseStmt or DefaultStmt class, 235 // used by SwitchStmt. 236 SwitchCase *NextSwitchCase; 237protected: 238 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 239 240public: 241 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 242 243 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 244 245 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 246 247 virtual Stmt* v_getSubStmt() = 0; 248 Stmt *getSubStmt() { return v_getSubStmt(); } 249 250 virtual SourceRange getSourceRange() const { return SourceRange(); } 251 252 static bool classof(const Stmt *T) { 253 return T->getStmtClass() == CaseStmtClass || 254 T->getStmtClass() == DefaultStmtClass; 255 } 256 static bool classof(const SwitchCase *) { return true; } 257}; 258 259class CaseStmt : public SwitchCase { 260 enum { SUBSTMT, LHS, RHS, END_EXPR }; 261 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 262 // GNU "case 1 ... 4" extension 263 SourceLocation CaseLoc; 264public: 265 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 266 : SwitchCase(CaseStmtClass) { 267 SubExprs[SUBSTMT] = substmt; 268 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 269 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 270 CaseLoc = caseLoc; 271 } 272 273 SourceLocation getCaseLoc() const { return CaseLoc; } 274 275 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 276 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 277 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 278 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 279 const Expr *getLHS() const { 280 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 281 } 282 const Expr *getRHS() const { 283 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 284 } 285 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 286 287 virtual SourceRange getSourceRange() const { 288 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 289 } 290 static bool classof(const Stmt *T) { 291 return T->getStmtClass() == CaseStmtClass; 292 } 293 static bool classof(const CaseStmt *) { return true; } 294 295 // Iterators 296 virtual child_iterator child_begin(); 297 virtual child_iterator child_end(); 298 299 virtual void directEmit(llvm::Serializer& S) const; 300 static CaseStmt* directMaterialize(llvm::Deserializer& D); 301}; 302 303class DefaultStmt : public SwitchCase { 304 Stmt* SubStmt; 305 SourceLocation DefaultLoc; 306public: 307 DefaultStmt(SourceLocation DL, Stmt *substmt) : 308 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 309 310 Stmt *getSubStmt() { return SubStmt; } 311 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 312 const Stmt *getSubStmt() const { return SubStmt; } 313 314 SourceLocation getDefaultLoc() const { return DefaultLoc; } 315 316 virtual SourceRange getSourceRange() const { 317 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 318 } 319 static bool classof(const Stmt *T) { 320 return T->getStmtClass() == DefaultStmtClass; 321 } 322 static bool classof(const DefaultStmt *) { return true; } 323 324 // Iterators 325 virtual child_iterator child_begin(); 326 virtual child_iterator child_end(); 327 328 virtual void directEmit(llvm::Serializer& S) const; 329 static DefaultStmt* directMaterialize(llvm::Deserializer& D); 330}; 331 332class LabelStmt : public Stmt { 333 IdentifierInfo *Label; 334 Stmt *SubStmt; 335 SourceLocation IdentLoc; 336public: 337 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 338 : Stmt(LabelStmtClass), Label(label), 339 SubStmt(substmt), IdentLoc(IL) {} 340 341 SourceLocation getIdentLoc() const { return IdentLoc; } 342 IdentifierInfo *getID() const { return Label; } 343 const char *getName() const; 344 Stmt *getSubStmt() { return SubStmt; } 345 const Stmt *getSubStmt() const { return SubStmt; } 346 347 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 348 void setSubStmt(Stmt *SS) { SubStmt = SS; } 349 350 virtual SourceRange getSourceRange() const { 351 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 352 } 353 static bool classof(const Stmt *T) { 354 return T->getStmtClass() == LabelStmtClass; 355 } 356 static bool classof(const LabelStmt *) { return true; } 357 358 // Iterators 359 virtual child_iterator child_begin(); 360 virtual child_iterator child_end(); 361 362 virtual void directEmit(llvm::Serializer& S) const; 363 static LabelStmt* directMaterialize(llvm::Deserializer& D); 364}; 365 366 367/// IfStmt - This represents an if/then/else. 368/// 369class IfStmt : public Stmt { 370 enum { COND, THEN, ELSE, END_EXPR }; 371 Stmt* SubExprs[END_EXPR]; 372 SourceLocation IfLoc; 373public: 374 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 375 : Stmt(IfStmtClass) { 376 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 377 SubExprs[THEN] = then; 378 SubExprs[ELSE] = elsev; 379 IfLoc = IL; 380 } 381 382 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 383 const Stmt *getThen() const { return SubExprs[THEN]; } 384 const Stmt *getElse() const { return SubExprs[ELSE]; } 385 386 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 387 Stmt *getThen() { return SubExprs[THEN]; } 388 Stmt *getElse() { return SubExprs[ELSE]; } 389 390 virtual SourceRange getSourceRange() const { 391 if (SubExprs[ELSE]) 392 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 393 else 394 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 395 } 396 397 static bool classof(const Stmt *T) { 398 return T->getStmtClass() == IfStmtClass; 399 } 400 static bool classof(const IfStmt *) { return true; } 401 402 // Iterators 403 virtual child_iterator child_begin(); 404 virtual child_iterator child_end(); 405 406 virtual void directEmit(llvm::Serializer& S) const; 407 static IfStmt* directMaterialize(llvm::Deserializer& D); 408}; 409 410/// SwitchStmt - This represents a 'switch' stmt. 411/// 412class SwitchStmt : public Stmt { 413 enum { COND, BODY, END_EXPR }; 414 Stmt* SubExprs[END_EXPR]; 415 // This points to a linked list of case and default statements. 416 SwitchCase *FirstCase; 417 SourceLocation SwitchLoc; 418public: 419 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 420 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 421 SubExprs[BODY] = NULL; 422 } 423 424 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 425 const Stmt *getBody() const { return SubExprs[BODY]; } 426 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 427 428 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 429 Stmt *getBody() { return SubExprs[BODY]; } 430 SwitchCase *getSwitchCaseList() { return FirstCase; } 431 432 void setBody(Stmt *S, SourceLocation SL) { 433 SubExprs[BODY] = S; 434 SwitchLoc = SL; 435 } 436 void addSwitchCase(SwitchCase *SC) { 437 if (FirstCase) 438 SC->setNextSwitchCase(FirstCase); 439 440 FirstCase = SC; 441 } 442 virtual SourceRange getSourceRange() const { 443 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 444 } 445 static bool classof(const Stmt *T) { 446 return T->getStmtClass() == SwitchStmtClass; 447 } 448 static bool classof(const SwitchStmt *) { return true; } 449 450 // Iterators 451 virtual child_iterator child_begin(); 452 virtual child_iterator child_end(); 453 454 virtual void directEmit(llvm::Serializer& S) const; 455 static SwitchStmt* directMaterialize(llvm::Deserializer& D); 456}; 457 458 459/// WhileStmt - This represents a 'while' stmt. 460/// 461class WhileStmt : public Stmt { 462 enum { COND, BODY, END_EXPR }; 463 Stmt* SubExprs[END_EXPR]; 464 SourceLocation WhileLoc; 465public: 466 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 467 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 468 SubExprs[BODY] = body; 469 WhileLoc = WL; 470 } 471 472 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 473 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 474 Stmt *getBody() { return SubExprs[BODY]; } 475 const Stmt *getBody() const { return SubExprs[BODY]; } 476 477 virtual SourceRange getSourceRange() const { 478 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 479 } 480 static bool classof(const Stmt *T) { 481 return T->getStmtClass() == WhileStmtClass; 482 } 483 static bool classof(const WhileStmt *) { return true; } 484 485 // Iterators 486 virtual child_iterator child_begin(); 487 virtual child_iterator child_end(); 488 489 virtual void directEmit(llvm::Serializer& S) const; 490 static WhileStmt* directMaterialize(llvm::Deserializer& D); 491}; 492 493/// DoStmt - This represents a 'do/while' stmt. 494/// 495class DoStmt : public Stmt { 496 enum { COND, BODY, END_EXPR }; 497 Stmt* SubExprs[END_EXPR]; 498 SourceLocation DoLoc; 499public: 500 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 501 : Stmt(DoStmtClass), DoLoc(DL) { 502 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 503 SubExprs[BODY] = body; 504 DoLoc = DL; 505 } 506 507 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 508 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 509 Stmt *getBody() { return SubExprs[BODY]; } 510 const Stmt *getBody() const { return SubExprs[BODY]; } 511 512 virtual SourceRange getSourceRange() const { 513 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 514 } 515 static bool classof(const Stmt *T) { 516 return T->getStmtClass() == DoStmtClass; 517 } 518 static bool classof(const DoStmt *) { return true; } 519 520 // Iterators 521 virtual child_iterator child_begin(); 522 virtual child_iterator child_end(); 523 524 virtual void directEmit(llvm::Serializer& S) const; 525 static DoStmt* directMaterialize(llvm::Deserializer& D); 526}; 527 528 529/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 530/// the init/cond/inc parts of the ForStmt will be null if they were not 531/// specified in the source. 532/// 533class ForStmt : public Stmt { 534 enum { INIT, COND, INC, BODY, END_EXPR }; 535 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 536 SourceLocation ForLoc; 537public: 538 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 539 : Stmt(ForStmtClass) { 540 SubExprs[INIT] = Init; 541 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 542 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 543 SubExprs[BODY] = Body; 544 ForLoc = FL; 545 } 546 547 Stmt *getInit() { return SubExprs[INIT]; } 548 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 549 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 550 Stmt *getBody() { return SubExprs[BODY]; } 551 552 const Stmt *getInit() const { return SubExprs[INIT]; } 553 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 554 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 555 const Stmt *getBody() const { return SubExprs[BODY]; } 556 557 virtual SourceRange getSourceRange() const { 558 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 559 } 560 static bool classof(const Stmt *T) { 561 return T->getStmtClass() == ForStmtClass; 562 } 563 static bool classof(const ForStmt *) { return true; } 564 565 // Iterators 566 virtual child_iterator child_begin(); 567 virtual child_iterator child_end(); 568 569 virtual void directEmit(llvm::Serializer& S) const; 570 static ForStmt* directMaterialize(llvm::Deserializer& D); 571}; 572 573/// GotoStmt - This represents a direct goto. 574/// 575class GotoStmt : public Stmt { 576 LabelStmt *Label; 577 SourceLocation GotoLoc; 578 SourceLocation LabelLoc; 579public: 580 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 581 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 582 583 LabelStmt *getLabel() const { return Label; } 584 585 virtual SourceRange getSourceRange() const { 586 return SourceRange(GotoLoc, LabelLoc); 587 } 588 static bool classof(const Stmt *T) { 589 return T->getStmtClass() == GotoStmtClass; 590 } 591 static bool classof(const GotoStmt *) { return true; } 592 593 // Iterators 594 virtual child_iterator child_begin(); 595 virtual child_iterator child_end(); 596 597 virtual void directEmit(llvm::Serializer& S) const; 598 static GotoStmt* directMaterialize(llvm::Deserializer& D); 599}; 600 601/// IndirectGotoStmt - This represents an indirect goto. 602/// 603class IndirectGotoStmt : public Stmt { 604 Expr *Target; 605public: 606 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 607 608 Expr *getTarget() { return Target; } 609 const Expr *getTarget() const { return Target; } 610 611 virtual SourceRange getSourceRange() const { return SourceRange(); } 612 613 static bool classof(const Stmt *T) { 614 return T->getStmtClass() == IndirectGotoStmtClass; 615 } 616 static bool classof(const IndirectGotoStmt *) { return true; } 617 618 // Iterators 619 virtual child_iterator child_begin(); 620 virtual child_iterator child_end(); 621}; 622 623 624/// ContinueStmt - This represents a continue. 625/// 626class ContinueStmt : public Stmt { 627 SourceLocation ContinueLoc; 628public: 629 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 630 631 virtual SourceRange getSourceRange() const { 632 return SourceRange(ContinueLoc); 633 } 634 static bool classof(const Stmt *T) { 635 return T->getStmtClass() == ContinueStmtClass; 636 } 637 static bool classof(const ContinueStmt *) { return true; } 638 639 // Iterators 640 virtual child_iterator child_begin(); 641 virtual child_iterator child_end(); 642}; 643 644/// BreakStmt - This represents a break. 645/// 646class BreakStmt : public Stmt { 647 SourceLocation BreakLoc; 648public: 649 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 650 651 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 652 653 static bool classof(const Stmt *T) { 654 return T->getStmtClass() == BreakStmtClass; 655 } 656 static bool classof(const BreakStmt *) { return true; } 657 658 // Iterators 659 virtual child_iterator child_begin(); 660 virtual child_iterator child_end(); 661 662 virtual void directEmit(llvm::Serializer& S) const; 663 static BreakStmt* directMaterialize(llvm::Deserializer& D); 664}; 665 666 667/// ReturnStmt - This represents a return, optionally of an expression. 668/// 669class ReturnStmt : public Stmt { 670 Expr *RetExpr; 671 SourceLocation RetLoc; 672public: 673 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 674 RetExpr(E), RetLoc(RL) {} 675 676 const Expr *getRetValue() const { return RetExpr; } 677 Expr *getRetValue() { return RetExpr; } 678 679 virtual SourceRange getSourceRange() const; 680 681 static bool classof(const Stmt *T) { 682 return T->getStmtClass() == ReturnStmtClass; 683 } 684 static bool classof(const ReturnStmt *) { return true; } 685 686 // Iterators 687 virtual child_iterator child_begin(); 688 virtual child_iterator child_end(); 689 690 virtual void directEmit(llvm::Serializer& S) const; 691 static ReturnStmt* directMaterialize(llvm::Deserializer& D); 692}; 693 694/// AsmStmt - This represents a GNU inline-assembly statement extension. 695/// 696class AsmStmt : public Stmt { 697 SourceLocation AsmLoc, RParenLoc; 698 // FIXME: This doesn't capture most of the interesting pieces. 699public: 700 AsmStmt(SourceLocation asmloc, SourceLocation rparenloc) 701 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {} 702 703 virtual SourceRange getSourceRange() const { 704 return SourceRange(AsmLoc, RParenLoc); 705 } 706 707 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 708 static bool classof(const AsmStmt *) { return true; } 709 710 virtual child_iterator child_begin(); 711 virtual child_iterator child_end(); 712}; 713 714/// ObjcAtCatchStmt - This represents objective-c's @catch statement. 715class ObjcAtCatchStmt : public Stmt { 716private: 717 // Points to next @catch statement, or null 718 ObjcAtCatchStmt *NextAtCatchStmt; 719 enum { SELECTOR, BODY, END_EXPR }; 720 Stmt *SubExprs[END_EXPR]; 721 SourceLocation AtCatchLoc, RParenLoc; 722 723public: 724 ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 725 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList) 726 : Stmt(ObjcAtCatchStmtClass) { 727 SubExprs[SELECTOR] = catchVarStmtDecl; 728 SubExprs[BODY] = atCatchStmt; 729 SubExprs[END_EXPR] = NULL; 730 if (!atCatchList) 731 NextAtCatchStmt = NULL; 732 else { 733 ObjcAtCatchStmt *AtCatchList = 734 static_cast<ObjcAtCatchStmt*>(atCatchList); 735 while (AtCatchList->NextAtCatchStmt) 736 AtCatchList = AtCatchList->NextAtCatchStmt; 737 AtCatchList->NextAtCatchStmt = this; 738 } 739 AtCatchLoc = atCatchLoc; 740 RParenLoc = rparenloc; 741 } 742 743 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 744 Stmt *getCatchBody() { return SubExprs[BODY]; } 745 const ObjcAtCatchStmt *getNextCatchStmt() const { return NextAtCatchStmt; } 746 ObjcAtCatchStmt *getNextCatchStmt() { return NextAtCatchStmt; } 747 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 748 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 749 750 SourceLocation getRParenLoc() const { return RParenLoc; } 751 752 virtual SourceRange getSourceRange() const { 753 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 754 } 755 756 static bool classof(const Stmt *T) { 757 return T->getStmtClass() == ObjcAtCatchStmtClass; 758 } 759 static bool classof(const ObjcAtCatchStmt *) { return true; } 760 761 virtual child_iterator child_begin(); 762 virtual child_iterator child_end(); 763 764}; 765 766/// ObjcAtFinallyStmt - This represent objective-c's @finally Statement 767class ObjcAtFinallyStmt : public Stmt { 768 private: 769 Stmt *AtFinallyStmt; 770 SourceLocation AtFinallyLoc; 771 772 public: 773 ObjcAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 774 : Stmt(ObjcAtFinallyStmtClass), 775 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 776 777 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 778 Stmt *getFinallyBody () { return AtFinallyStmt; } 779 780 virtual SourceRange getSourceRange() const { 781 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 782 } 783 784 static bool classof(const Stmt *T) { 785 return T->getStmtClass() == ObjcAtFinallyStmtClass; 786 } 787 static bool classof(const ObjcAtFinallyStmt *) { return true; } 788 789 virtual child_iterator child_begin(); 790 virtual child_iterator child_end(); 791 792}; 793 794/// ObjcAtTryStmt - This represent objective-c's over-all 795/// @try ... @catch ... @finally statement. 796class ObjcAtTryStmt : public Stmt { 797private: 798 enum { TRY, CATCH, FINALLY, END_TRY }; 799 Stmt* SubStmts[END_TRY]; 800 801 SourceLocation AtTryLoc; 802 803public: 804 ObjcAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 805 Stmt *atCatchStmt, 806 Stmt *atFinallyStmt) 807 : Stmt(ObjcAtTryStmtClass) { 808 SubStmts[TRY] = atTryStmt; 809 SubStmts[CATCH] = atCatchStmt; 810 SubStmts[FINALLY] = atFinallyStmt; 811 SubStmts[END_TRY] = NULL; 812 AtTryLoc = atTryLoc; 813 } 814 815 const Stmt *getTryBody() const { return SubStmts[TRY]; } 816 Stmt *getTryBody() { return SubStmts[TRY]; } 817 const ObjcAtCatchStmt *getCatchStmts() const { 818 return dyn_cast_or_null<ObjcAtCatchStmt>(SubStmts[CATCH]); 819 } 820 ObjcAtCatchStmt *getCatchStmts() { 821 return dyn_cast_or_null<ObjcAtCatchStmt>(SubStmts[CATCH]); 822 } 823 const ObjcAtFinallyStmt *getFinallyStmt() const { 824 return dyn_cast_or_null<ObjcAtFinallyStmt>(SubStmts[FINALLY]); 825 } 826 ObjcAtFinallyStmt *getFinallyStmt() { 827 return dyn_cast_or_null<ObjcAtFinallyStmt>(SubStmts[FINALLY]); 828 } 829 virtual SourceRange getSourceRange() const { 830 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 831 } 832 833 static bool classof(const Stmt *T) { 834 return T->getStmtClass() == ObjcAtTryStmtClass; 835 } 836 static bool classof(const ObjcAtTryStmt *) { return true; } 837 838 virtual child_iterator child_begin(); 839 virtual child_iterator child_end(); 840 841}; 842 843/// ObjcAtThrowStmt - This represents objective-c's @throw statement. 844class ObjcAtThrowStmt : public Stmt { 845private: 846 Stmt *Throw; 847 SourceLocation AtThrowLoc; 848 849public: 850 ObjcAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 851 : Stmt(ObjcAtThrowStmtClass), Throw(throwExpr) { 852 AtThrowLoc = atThrowLoc; 853 } 854 855 Expr *const getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 856 857 virtual SourceRange getSourceRange() const { 858 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 859 } 860 861 static bool classof(const Stmt *T) { 862 return T->getStmtClass() == ObjcAtThrowStmtClass; 863 } 864 static bool classof(const ObjcAtThrowStmt *) { return true; } 865 866 virtual child_iterator child_begin(); 867 virtual child_iterator child_end(); 868}; 869 870} // end namespace clang 871 872#endif 873