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