Stmt.h revision ec0aa78745f7b3bc96c20fffd1115bf26aaa0ead
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 EmitImpl(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 EmitImpl(llvm::Serializer& S) const; 151 static DeclStmt* CreateImpl(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 EmitImpl(llvm::Serializer& S) const; 175 static NullStmt* CreateImpl(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 EmitImpl(llvm::Serializer& S) const; 229 static CompoundStmt* CreateImpl(llvm::Deserializer& D); 230}; 231 232// SwitchCase is the base class for CaseStmt and DefaultStmt, 233class SwitchCase : public Stmt { 234protected: 235 // A pointer to the following CaseStmt or DefaultStmt class, 236 // used by SwitchStmt. 237 SwitchCase *NextSwitchCase; 238 239 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 240 241public: 242 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 243 244 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 245 246 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 247 248 virtual Stmt* v_getSubStmt() = 0; 249 Stmt *getSubStmt() { return v_getSubStmt(); } 250 251 virtual SourceRange getSourceRange() const { return SourceRange(); } 252 253 static bool classof(const Stmt *T) { 254 return T->getStmtClass() == CaseStmtClass || 255 T->getStmtClass() == DefaultStmtClass; 256 } 257 static bool classof(const SwitchCase *) { return true; } 258}; 259 260class CaseStmt : public SwitchCase { 261 enum { SUBSTMT, LHS, RHS, END_EXPR }; 262 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 263 // GNU "case 1 ... 4" extension 264 SourceLocation CaseLoc; 265public: 266 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 267 : SwitchCase(CaseStmtClass) { 268 SubExprs[SUBSTMT] = substmt; 269 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 270 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 271 CaseLoc = caseLoc; 272 } 273 274 SourceLocation getCaseLoc() const { return CaseLoc; } 275 276 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 277 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 278 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 279 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 280 const Expr *getLHS() const { 281 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 282 } 283 const Expr *getRHS() const { 284 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 285 } 286 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 287 288 virtual SourceRange getSourceRange() const { 289 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 290 } 291 static bool classof(const Stmt *T) { 292 return T->getStmtClass() == CaseStmtClass; 293 } 294 static bool classof(const CaseStmt *) { return true; } 295 296 // Iterators 297 virtual child_iterator child_begin(); 298 virtual child_iterator child_end(); 299 300 virtual void EmitImpl(llvm::Serializer& S) const; 301 static CaseStmt* CreateImpl(llvm::Deserializer& D); 302}; 303 304class DefaultStmt : public SwitchCase { 305 Stmt* SubStmt; 306 SourceLocation DefaultLoc; 307public: 308 DefaultStmt(SourceLocation DL, Stmt *substmt) : 309 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 310 311 Stmt *getSubStmt() { return SubStmt; } 312 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 313 const Stmt *getSubStmt() const { return SubStmt; } 314 315 SourceLocation getDefaultLoc() const { return DefaultLoc; } 316 317 virtual SourceRange getSourceRange() const { 318 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 319 } 320 static bool classof(const Stmt *T) { 321 return T->getStmtClass() == DefaultStmtClass; 322 } 323 static bool classof(const DefaultStmt *) { return true; } 324 325 // Iterators 326 virtual child_iterator child_begin(); 327 virtual child_iterator child_end(); 328 329 virtual void EmitImpl(llvm::Serializer& S) const; 330 static DefaultStmt* CreateImpl(llvm::Deserializer& D); 331}; 332 333class LabelStmt : public Stmt { 334 IdentifierInfo *Label; 335 Stmt *SubStmt; 336 SourceLocation IdentLoc; 337public: 338 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 339 : Stmt(LabelStmtClass), Label(label), 340 SubStmt(substmt), IdentLoc(IL) {} 341 342 SourceLocation getIdentLoc() const { return IdentLoc; } 343 IdentifierInfo *getID() const { return Label; } 344 const char *getName() const; 345 Stmt *getSubStmt() { return SubStmt; } 346 const Stmt *getSubStmt() const { return SubStmt; } 347 348 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 349 void setSubStmt(Stmt *SS) { SubStmt = SS; } 350 351 virtual SourceRange getSourceRange() const { 352 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 353 } 354 static bool classof(const Stmt *T) { 355 return T->getStmtClass() == LabelStmtClass; 356 } 357 static bool classof(const LabelStmt *) { return true; } 358 359 // Iterators 360 virtual child_iterator child_begin(); 361 virtual child_iterator child_end(); 362 363 virtual void EmitImpl(llvm::Serializer& S) const; 364 static LabelStmt* CreateImpl(llvm::Deserializer& D); 365}; 366 367 368/// IfStmt - This represents an if/then/else. 369/// 370class IfStmt : public Stmt { 371 enum { COND, THEN, ELSE, END_EXPR }; 372 Stmt* SubExprs[END_EXPR]; 373 SourceLocation IfLoc; 374public: 375 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 376 : Stmt(IfStmtClass) { 377 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 378 SubExprs[THEN] = then; 379 SubExprs[ELSE] = elsev; 380 IfLoc = IL; 381 } 382 383 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 384 const Stmt *getThen() const { return SubExprs[THEN]; } 385 const Stmt *getElse() const { return SubExprs[ELSE]; } 386 387 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 388 Stmt *getThen() { return SubExprs[THEN]; } 389 Stmt *getElse() { return SubExprs[ELSE]; } 390 391 virtual SourceRange getSourceRange() const { 392 if (SubExprs[ELSE]) 393 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 394 else 395 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 396 } 397 398 static bool classof(const Stmt *T) { 399 return T->getStmtClass() == IfStmtClass; 400 } 401 static bool classof(const IfStmt *) { return true; } 402 403 // Iterators 404 virtual child_iterator child_begin(); 405 virtual child_iterator child_end(); 406 407 virtual void EmitImpl(llvm::Serializer& S) const; 408 static IfStmt* CreateImpl(llvm::Deserializer& D); 409}; 410 411/// SwitchStmt - This represents a 'switch' stmt. 412/// 413class SwitchStmt : public Stmt { 414 enum { COND, BODY, END_EXPR }; 415 Stmt* SubExprs[END_EXPR]; 416 // This points to a linked list of case and default statements. 417 SwitchCase *FirstCase; 418 SourceLocation SwitchLoc; 419public: 420 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 421 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 422 SubExprs[BODY] = NULL; 423 } 424 425 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 426 const Stmt *getBody() const { return SubExprs[BODY]; } 427 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 428 429 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 430 Stmt *getBody() { return SubExprs[BODY]; } 431 SwitchCase *getSwitchCaseList() { return FirstCase; } 432 433 void setBody(Stmt *S, SourceLocation SL) { 434 SubExprs[BODY] = S; 435 SwitchLoc = SL; 436 } 437 void addSwitchCase(SwitchCase *SC) { 438 if (FirstCase) 439 SC->setNextSwitchCase(FirstCase); 440 441 FirstCase = SC; 442 } 443 virtual SourceRange getSourceRange() const { 444 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 445 } 446 static bool classof(const Stmt *T) { 447 return T->getStmtClass() == SwitchStmtClass; 448 } 449 static bool classof(const SwitchStmt *) { return true; } 450 451 // Iterators 452 virtual child_iterator child_begin(); 453 virtual child_iterator child_end(); 454 455 virtual void EmitImpl(llvm::Serializer& S) const; 456 static SwitchStmt* CreateImpl(llvm::Deserializer& D); 457}; 458 459 460/// WhileStmt - This represents a 'while' stmt. 461/// 462class WhileStmt : public Stmt { 463 enum { COND, BODY, END_EXPR }; 464 Stmt* SubExprs[END_EXPR]; 465 SourceLocation WhileLoc; 466public: 467 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 468 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 469 SubExprs[BODY] = body; 470 WhileLoc = WL; 471 } 472 473 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 474 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 475 Stmt *getBody() { return SubExprs[BODY]; } 476 const Stmt *getBody() const { return SubExprs[BODY]; } 477 478 virtual SourceRange getSourceRange() const { 479 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 480 } 481 static bool classof(const Stmt *T) { 482 return T->getStmtClass() == WhileStmtClass; 483 } 484 static bool classof(const WhileStmt *) { return true; } 485 486 // Iterators 487 virtual child_iterator child_begin(); 488 virtual child_iterator child_end(); 489 490 virtual void EmitImpl(llvm::Serializer& S) const; 491 static WhileStmt* CreateImpl(llvm::Deserializer& D); 492}; 493 494/// DoStmt - This represents a 'do/while' stmt. 495/// 496class DoStmt : public Stmt { 497 enum { COND, BODY, END_EXPR }; 498 Stmt* SubExprs[END_EXPR]; 499 SourceLocation DoLoc; 500public: 501 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 502 : Stmt(DoStmtClass), DoLoc(DL) { 503 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 504 SubExprs[BODY] = body; 505 DoLoc = DL; 506 } 507 508 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 509 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 510 Stmt *getBody() { return SubExprs[BODY]; } 511 const Stmt *getBody() const { return SubExprs[BODY]; } 512 513 virtual SourceRange getSourceRange() const { 514 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 515 } 516 static bool classof(const Stmt *T) { 517 return T->getStmtClass() == DoStmtClass; 518 } 519 static bool classof(const DoStmt *) { return true; } 520 521 // Iterators 522 virtual child_iterator child_begin(); 523 virtual child_iterator child_end(); 524 525 virtual void EmitImpl(llvm::Serializer& S) const; 526 static DoStmt* CreateImpl(llvm::Deserializer& D); 527}; 528 529 530/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 531/// the init/cond/inc parts of the ForStmt will be null if they were not 532/// specified in the source. 533/// 534class ForStmt : public Stmt { 535 enum { INIT, COND, INC, BODY, END_EXPR }; 536 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 537 SourceLocation ForLoc; 538public: 539 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 540 : Stmt(ForStmtClass) { 541 SubExprs[INIT] = Init; 542 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 543 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 544 SubExprs[BODY] = Body; 545 ForLoc = FL; 546 } 547 548 Stmt *getInit() { return SubExprs[INIT]; } 549 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 550 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 551 Stmt *getBody() { return SubExprs[BODY]; } 552 553 const Stmt *getInit() const { return SubExprs[INIT]; } 554 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 555 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 556 const Stmt *getBody() const { return SubExprs[BODY]; } 557 558 virtual SourceRange getSourceRange() const { 559 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 560 } 561 static bool classof(const Stmt *T) { 562 return T->getStmtClass() == ForStmtClass; 563 } 564 static bool classof(const ForStmt *) { return true; } 565 566 // Iterators 567 virtual child_iterator child_begin(); 568 virtual child_iterator child_end(); 569 570 virtual void EmitImpl(llvm::Serializer& S) const; 571 static ForStmt* CreateImpl(llvm::Deserializer& D); 572}; 573 574/// GotoStmt - This represents a direct goto. 575/// 576class GotoStmt : public Stmt { 577 LabelStmt *Label; 578 SourceLocation GotoLoc; 579 SourceLocation LabelLoc; 580public: 581 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 582 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 583 584 LabelStmt *getLabel() const { return Label; } 585 586 virtual SourceRange getSourceRange() const { 587 return SourceRange(GotoLoc, LabelLoc); 588 } 589 static bool classof(const Stmt *T) { 590 return T->getStmtClass() == GotoStmtClass; 591 } 592 static bool classof(const GotoStmt *) { return true; } 593 594 // Iterators 595 virtual child_iterator child_begin(); 596 virtual child_iterator child_end(); 597 598 virtual void EmitImpl(llvm::Serializer& S) const; 599 static GotoStmt* CreateImpl(llvm::Deserializer& D); 600}; 601 602/// IndirectGotoStmt - This represents an indirect goto. 603/// 604class IndirectGotoStmt : public Stmt { 605 Expr *Target; 606 // FIXME: Add location information (e.g. SourceLocation objects). 607 // When doing so, update the serialization routines. 608public: 609 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 610 611 Expr *getTarget() { return Target; } 612 const Expr *getTarget() const { return Target; } 613 614 virtual SourceRange getSourceRange() const { return SourceRange(); } 615 616 static bool classof(const Stmt *T) { 617 return T->getStmtClass() == IndirectGotoStmtClass; 618 } 619 static bool classof(const IndirectGotoStmt *) { return true; } 620 621 // Iterators 622 virtual child_iterator child_begin(); 623 virtual child_iterator child_end(); 624 625 virtual void EmitImpl(llvm::Serializer& S) const; 626 static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D); 627}; 628 629 630/// ContinueStmt - This represents a continue. 631/// 632class ContinueStmt : public Stmt { 633 SourceLocation ContinueLoc; 634public: 635 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 636 637 virtual SourceRange getSourceRange() const { 638 return SourceRange(ContinueLoc); 639 } 640 static bool classof(const Stmt *T) { 641 return T->getStmtClass() == ContinueStmtClass; 642 } 643 static bool classof(const ContinueStmt *) { return true; } 644 645 // Iterators 646 virtual child_iterator child_begin(); 647 virtual child_iterator child_end(); 648 649 virtual void EmitImpl(llvm::Serializer& S) const; 650 static ContinueStmt* CreateImpl(llvm::Deserializer& D); 651}; 652 653/// BreakStmt - This represents a break. 654/// 655class BreakStmt : public Stmt { 656 SourceLocation BreakLoc; 657public: 658 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 659 660 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 661 662 static bool classof(const Stmt *T) { 663 return T->getStmtClass() == BreakStmtClass; 664 } 665 static bool classof(const BreakStmt *) { return true; } 666 667 // Iterators 668 virtual child_iterator child_begin(); 669 virtual child_iterator child_end(); 670 671 virtual void EmitImpl(llvm::Serializer& S) const; 672 static BreakStmt* CreateImpl(llvm::Deserializer& D); 673}; 674 675 676/// ReturnStmt - This represents a return, optionally of an expression. 677/// 678class ReturnStmt : public Stmt { 679 Expr *RetExpr; 680 SourceLocation RetLoc; 681public: 682 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 683 RetExpr(E), RetLoc(RL) {} 684 685 const Expr *getRetValue() const { return RetExpr; } 686 Expr *getRetValue() { return RetExpr; } 687 688 virtual SourceRange getSourceRange() const; 689 690 static bool classof(const Stmt *T) { 691 return T->getStmtClass() == ReturnStmtClass; 692 } 693 static bool classof(const ReturnStmt *) { return true; } 694 695 // Iterators 696 virtual child_iterator child_begin(); 697 virtual child_iterator child_end(); 698 699 virtual void EmitImpl(llvm::Serializer& S) const; 700 static ReturnStmt* CreateImpl(llvm::Deserializer& D); 701}; 702 703/// AsmStmt - This represents a GNU inline-assembly statement extension. 704/// 705class AsmStmt : public Stmt { 706 SourceLocation AsmLoc, RParenLoc; 707 // FIXME: This doesn't capture most of the interesting pieces. 708public: 709 AsmStmt(SourceLocation asmloc, SourceLocation rparenloc) 710 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc) {} 711 712 virtual SourceRange getSourceRange() const { 713 return SourceRange(AsmLoc, RParenLoc); 714 } 715 716 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 717 static bool classof(const AsmStmt *) { return true; } 718 719 virtual child_iterator child_begin(); 720 virtual child_iterator child_end(); 721}; 722 723/// ObjcAtCatchStmt - This represents objective-c's @catch statement. 724class ObjcAtCatchStmt : public Stmt { 725private: 726 // Points to next @catch statement, or null 727 ObjcAtCatchStmt *NextAtCatchStmt; 728 enum { SELECTOR, BODY, END_EXPR }; 729 Stmt *SubExprs[END_EXPR]; 730 SourceLocation AtCatchLoc, RParenLoc; 731 732public: 733 ObjcAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 734 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList) 735 : Stmt(ObjcAtCatchStmtClass) { 736 SubExprs[SELECTOR] = catchVarStmtDecl; 737 SubExprs[BODY] = atCatchStmt; 738 if (!atCatchList) 739 NextAtCatchStmt = NULL; 740 else { 741 ObjcAtCatchStmt *AtCatchList = 742 static_cast<ObjcAtCatchStmt*>(atCatchList); 743 while (AtCatchList->NextAtCatchStmt) 744 AtCatchList = AtCatchList->NextAtCatchStmt; 745 AtCatchList->NextAtCatchStmt = this; 746 } 747 AtCatchLoc = atCatchLoc; 748 RParenLoc = rparenloc; 749 } 750 751 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 752 Stmt *getCatchBody() { return SubExprs[BODY]; } 753 const ObjcAtCatchStmt *getNextCatchStmt() const { return NextAtCatchStmt; } 754 ObjcAtCatchStmt *getNextCatchStmt() { return NextAtCatchStmt; } 755 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 756 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 757 758 SourceLocation getRParenLoc() const { return RParenLoc; } 759 760 virtual SourceRange getSourceRange() const { 761 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 762 } 763 764 static bool classof(const Stmt *T) { 765 return T->getStmtClass() == ObjcAtCatchStmtClass; 766 } 767 static bool classof(const ObjcAtCatchStmt *) { return true; } 768 769 virtual child_iterator child_begin(); 770 virtual child_iterator child_end(); 771 772}; 773 774/// ObjcAtFinallyStmt - This represent objective-c's @finally Statement 775class ObjcAtFinallyStmt : public Stmt { 776 private: 777 Stmt *AtFinallyStmt; 778 SourceLocation AtFinallyLoc; 779 780 public: 781 ObjcAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 782 : Stmt(ObjcAtFinallyStmtClass), 783 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 784 785 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 786 Stmt *getFinallyBody () { return AtFinallyStmt; } 787 788 virtual SourceRange getSourceRange() const { 789 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 790 } 791 792 static bool classof(const Stmt *T) { 793 return T->getStmtClass() == ObjcAtFinallyStmtClass; 794 } 795 static bool classof(const ObjcAtFinallyStmt *) { return true; } 796 797 virtual child_iterator child_begin(); 798 virtual child_iterator child_end(); 799 800}; 801 802/// ObjcAtTryStmt - This represent objective-c's over-all 803/// @try ... @catch ... @finally statement. 804class ObjcAtTryStmt : public Stmt { 805private: 806 enum { TRY, CATCH, FINALLY, END_EXPR }; 807 Stmt* SubStmts[END_EXPR]; 808 809 SourceLocation AtTryLoc; 810 811public: 812 ObjcAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 813 Stmt *atCatchStmt, 814 Stmt *atFinallyStmt) 815 : Stmt(ObjcAtTryStmtClass) { 816 SubStmts[TRY] = atTryStmt; 817 SubStmts[CATCH] = atCatchStmt; 818 SubStmts[FINALLY] = atFinallyStmt; 819 AtTryLoc = atTryLoc; 820 } 821 822 const Stmt *getTryBody() const { return SubStmts[TRY]; } 823 Stmt *getTryBody() { return SubStmts[TRY]; } 824 const ObjcAtCatchStmt *getCatchStmts() const { 825 return dyn_cast_or_null<ObjcAtCatchStmt>(SubStmts[CATCH]); 826 } 827 ObjcAtCatchStmt *getCatchStmts() { 828 return dyn_cast_or_null<ObjcAtCatchStmt>(SubStmts[CATCH]); 829 } 830 const ObjcAtFinallyStmt *getFinallyStmt() const { 831 return dyn_cast_or_null<ObjcAtFinallyStmt>(SubStmts[FINALLY]); 832 } 833 ObjcAtFinallyStmt *getFinallyStmt() { 834 return dyn_cast_or_null<ObjcAtFinallyStmt>(SubStmts[FINALLY]); 835 } 836 virtual SourceRange getSourceRange() const { 837 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 838 } 839 840 static bool classof(const Stmt *T) { 841 return T->getStmtClass() == ObjcAtTryStmtClass; 842 } 843 static bool classof(const ObjcAtTryStmt *) { return true; } 844 845 virtual child_iterator child_begin(); 846 virtual child_iterator child_end(); 847 848}; 849 850/// ObjcAtThrowStmt - This represents objective-c's @throw statement. 851class ObjcAtThrowStmt : public Stmt { 852private: 853 Stmt *Throw; 854 SourceLocation AtThrowLoc; 855 856public: 857 ObjcAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 858 : Stmt(ObjcAtThrowStmtClass), Throw(throwExpr) { 859 AtThrowLoc = atThrowLoc; 860 } 861 862 Expr *const getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 863 864 virtual SourceRange getSourceRange() const { 865 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 866 } 867 868 static bool classof(const Stmt *T) { 869 return T->getStmtClass() == ObjcAtThrowStmtClass; 870 } 871 static bool classof(const ObjcAtThrowStmt *) { return true; } 872 873 virtual child_iterator child_begin(); 874 virtual child_iterator child_end(); 875}; 876 877} // end namespace clang 878 879#endif 880