Stmt.h revision d311f376c364e5a6c88b63b1d5c53f560ea5e650
1//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// 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 "llvm/Support/raw_ostream.h" 19#include "clang/Basic/SourceLocation.h" 20#include "clang/AST/StmtIterator.h" 21#include "clang/AST/DeclGroup.h" 22#include "llvm/ADT/SmallVector.h" 23#include "llvm/ADT/iterator.h" 24#include "llvm/Bitcode/SerializationFwd.h" 25#include "clang/AST/ASTContext.h" 26#include <string> 27 28using llvm::dyn_cast_or_null; 29 30namespace clang { 31 class ASTContext; 32 class Expr; 33 class Decl; 34 class QualType; 35 class IdentifierInfo; 36 class SourceManager; 37 class StringLiteral; 38 class SwitchStmt; 39 class PrinterHelper; 40 41 //===----------------------------------------------------------------------===// 42 // ExprIterator - Iterators for iterating over Stmt* arrays that contain 43 // only Expr*. This is needed because AST nodes use Stmt* arrays to store 44 // references to children (to be compatible with StmtIterator). 45 //===----------------------------------------------------------------------===// 46 47 class Stmt; 48 class Expr; 49 50 class ExprIterator { 51 Stmt** I; 52 public: 53 ExprIterator(Stmt** i) : I(i) {} 54 ExprIterator() : I(0) {} 55 ExprIterator& operator++() { ++I; return *this; } 56 ExprIterator operator-(size_t i) { return I-i; } 57 ExprIterator operator+(size_t i) { return I+i; } 58 Expr* operator[](size_t idx); 59 // FIXME: Verify that this will correctly return a signed distance. 60 signed operator-(const ExprIterator& R) const { return I - R.I; } 61 Expr* operator*() const; 62 Expr* operator->() const; 63 bool operator==(const ExprIterator& R) const { return I == R.I; } 64 bool operator!=(const ExprIterator& R) const { return I != R.I; } 65 bool operator>(const ExprIterator& R) const { return I > R.I; } 66 bool operator>=(const ExprIterator& R) const { return I >= R.I; } 67 }; 68 69 class ConstExprIterator { 70 Stmt* const * I; 71 public: 72 ConstExprIterator(Stmt* const* i) : I(i) {} 73 ConstExprIterator() : I(0) {} 74 ConstExprIterator& operator++() { ++I; return *this; } 75 ConstExprIterator operator+(size_t i) { return I+i; } 76 ConstExprIterator operator-(size_t i) { return I-i; } 77 const Expr * operator[](size_t idx) const; 78 signed operator-(const ConstExprIterator& R) const { return I - R.I; } 79 const Expr * operator*() const; 80 const Expr * operator->() const; 81 bool operator==(const ConstExprIterator& R) const { return I == R.I; } 82 bool operator!=(const ConstExprIterator& R) const { return I != R.I; } 83 bool operator>(const ConstExprIterator& R) const { return I > R.I; } 84 bool operator>=(const ConstExprIterator& R) const { return I >= R.I; } 85 }; 86 87//===----------------------------------------------------------------------===// 88// AST classes for statements. 89//===----------------------------------------------------------------------===// 90 91/// Stmt - This represents one statement. 92/// 93class Stmt { 94public: 95 enum StmtClass { 96 NoStmtClass = 0, 97#define STMT(CLASS, PARENT) CLASS##Class, 98#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class, 99#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class, 100#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class, 101#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class 102#include "clang/AST/StmtNodes.def" 103}; 104private: 105 const StmtClass sClass; 106 107 // Make vanilla 'new' and 'delete' illegal for Stmts. 108protected: 109 void* operator new(size_t bytes) throw() { 110 assert(0 && "Stmts cannot be allocated with regular 'new'."); 111 return 0; 112 } 113 void operator delete(void* data) throw() { 114 assert(0 && "Stmts cannot be released with regular 'delete'."); 115 } 116 117public: 118 // Only allow allocation of Stmts using the allocator in ASTContext 119 // or by doing a placement new. 120 void* operator new(size_t bytes, ASTContext& C, 121 unsigned alignment = 16) throw() { 122 return ::operator new(bytes, C, alignment); 123 } 124 125 void* operator new(size_t bytes, ASTContext* C, 126 unsigned alignment = 16) throw() { 127 return ::operator new(bytes, *C, alignment); 128 } 129 130 void* operator new(size_t bytes, void* mem) throw() { 131 return mem; 132 } 133 134 void operator delete(void*, ASTContext& C) throw() { } 135 void operator delete(void*, ASTContext& C, unsigned alignment) throw() { } 136 void operator delete(void*, std::size_t) throw() { } 137 138protected: 139 /// DestroyChildren - Invoked by destructors of subclasses of Stmt to 140 /// recursively release child AST nodes. 141 void DestroyChildren(ASTContext& Ctx); 142 143public: 144 Stmt(StmtClass SC) : sClass(SC) { 145 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 146 } 147 virtual ~Stmt() {} 148 149 virtual void Destroy(ASTContext& Ctx); 150 151 StmtClass getStmtClass() const { return sClass; } 152 const char *getStmtClassName() const; 153 154 /// SourceLocation tokens are not useful in isolation - they are low level 155 /// value objects created/interpreted by SourceManager. We assume AST 156 /// clients will have a pointer to the respective SourceManager. 157 virtual SourceRange getSourceRange() const = 0; 158 SourceLocation getLocStart() const { return getSourceRange().getBegin(); } 159 SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } 160 161 // global temp stats (until we have a per-module visitor) 162 static void addStmtClass(const StmtClass s); 163 static bool CollectingStats(bool enable=false); 164 static void PrintStats(); 165 166 /// dump - This does a local dump of the specified AST fragment. It dumps the 167 /// specified node and a few nodes underneath it, but not the whole subtree. 168 /// This is useful in a debugger. 169 void dump() const; 170 void dump(SourceManager &SM) const; 171 172 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 173 void dumpAll() const; 174 void dumpAll(SourceManager &SM) const; 175 176 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 177 /// back to its original source language syntax. 178 void dumpPretty() const; 179 void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL, unsigned = 0, 180 bool NoIndent=false) const; 181 182 /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 183 /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 184 void viewAST() const; 185 186 // Implement isa<T> support. 187 static bool classof(const Stmt *) { return true; } 188 189 /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) 190 /// contain implicit control-flow in the order their subexpressions 191 /// are evaluated. This predicate returns true if this statement has 192 /// such implicit control-flow. Such statements are also specially handled 193 /// within CFGs. 194 bool hasImplicitControlFlow() const; 195 196 /// Child Iterators: All subclasses must implement child_begin and child_end 197 /// to permit easy iteration over the substatements/subexpessions of an 198 /// AST node. This permits easy iteration over all nodes in the AST. 199 typedef StmtIterator child_iterator; 200 typedef ConstStmtIterator const_child_iterator; 201 202 virtual child_iterator child_begin() = 0; 203 virtual child_iterator child_end() = 0; 204 205 const_child_iterator child_begin() const { 206 return const_child_iterator(const_cast<Stmt*>(this)->child_begin()); 207 } 208 209 const_child_iterator child_end() const { 210 return const_child_iterator(const_cast<Stmt*>(this)->child_end()); 211 } 212 213 void Emit(llvm::Serializer& S) const; 214 static Stmt* Create(llvm::Deserializer& D, ASTContext& C); 215 216 virtual void EmitImpl(llvm::Serializer& S) const { 217 // This method will eventually be a pure-virtual function. 218 assert (false && "Not implemented."); 219 } 220}; 221 222/// DeclStmt - Adaptor class for mixing declarations with statements and 223/// expressions. For example, CompoundStmt mixes statements, expressions 224/// and declarations (variables, types). Another example is ForStmt, where 225/// the first statement can be an expression or a declaration. 226/// 227class DeclStmt : public Stmt { 228protected: 229 DeclGroupRef DG; 230 SourceLocation StartLoc, EndLoc; 231public: 232 DeclStmt(DeclGroupRef dg, SourceLocation startLoc, 233 SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg), 234 StartLoc(startLoc), EndLoc(endLoc) {} 235 236 virtual void Destroy(ASTContext& Ctx); 237 238 // hasSolitaryDecl - This method returns true if this DeclStmt refers 239 // to a single Decl. 240 bool hasSolitaryDecl() const { 241 return DG.hasSolitaryDecl(); 242 } 243 244 const Decl* getSolitaryDecl() const { 245 assert (hasSolitaryDecl() && 246 "Caller assumes this DeclStmt points to one Decl*"); 247 return *DG.begin(); 248 } 249 250 Decl* getSolitaryDecl() { 251 assert (hasSolitaryDecl() && 252 "Caller assumes this DeclStmt points to one Decl*"); 253 return *DG.begin(); 254 } 255 256 SourceLocation getStartLoc() const { return StartLoc; } 257 SourceLocation getEndLoc() const { return EndLoc; } 258 259 SourceRange getSourceRange() const { 260 return SourceRange(StartLoc, EndLoc); 261 } 262 263 static bool classof(const Stmt *T) { 264 return T->getStmtClass() == DeclStmtClass; 265 } 266 static bool classof(const DeclStmt *) { return true; } 267 268 // Iterators over subexpressions. 269 virtual child_iterator child_begin(); 270 virtual child_iterator child_end(); 271 272 class decl_iterator { 273 DeclGroupRef::iterator I; 274 public: 275 decl_iterator(DeclGroupRef::iterator i) : I(i) {} 276 decl_iterator& operator++() { ++I; return *this; } 277 bool operator==(const decl_iterator& R) const { 278 return R.I == I; 279 } 280 bool operator!=(const decl_iterator& R) const { 281 return R.I != I; 282 } 283 Decl* operator*() const { 284 return *I; 285 } 286 }; 287 288 class const_decl_iterator { 289 DeclGroupRef::const_iterator I; 290 public: 291 const_decl_iterator(DeclGroupRef::const_iterator i) : I(i) {} 292 const_decl_iterator& operator++() { ++I; return *this; } 293 bool operator==(const const_decl_iterator& R) const { 294 return R.I == I; 295 } 296 bool operator!=(const const_decl_iterator& R) const { 297 return R.I != I; 298 } 299 Decl* operator*() const { 300 return *I; 301 } 302 }; 303 304 decl_iterator decl_begin() { return DG.begin(); } 305 decl_iterator decl_end() { return DG.end(); } 306 const_decl_iterator decl_begin() const { return DG.begin(); } 307 const_decl_iterator decl_end() const { return DG.end(); } 308 309 // Serialization. 310 virtual void EmitImpl(llvm::Serializer& S) const; 311 static DeclStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 312}; 313 314/// NullStmt - This is the null statement ";": C99 6.8.3p3. 315/// 316class NullStmt : public Stmt { 317 SourceLocation SemiLoc; 318public: 319 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 320 321 SourceLocation getSemiLoc() const { return SemiLoc; } 322 323 virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 324 325 static bool classof(const Stmt *T) { 326 return T->getStmtClass() == NullStmtClass; 327 } 328 static bool classof(const NullStmt *) { return true; } 329 330 // Iterators 331 virtual child_iterator child_begin(); 332 virtual child_iterator child_end(); 333 334 virtual void EmitImpl(llvm::Serializer& S) const; 335 static NullStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 336}; 337 338/// CompoundStmt - This represents a group of statements like { stmt stmt }. 339/// 340class CompoundStmt : public Stmt { 341 Stmt** Body; 342 unsigned NumStmts; 343 SourceLocation LBracLoc, RBracLoc; 344public: 345 CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts, 346 SourceLocation LB, SourceLocation RB) 347 : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) { 348 if (NumStmts == 0) { 349 Body = 0; 350 return; 351 } 352 353 Body = new (C) Stmt*[NumStmts]; 354 memcpy(Body, StmtStart, numStmts * sizeof(*Body)); 355 } 356 357 bool body_empty() const { return NumStmts == 0; } 358 359 typedef Stmt** body_iterator; 360 body_iterator body_begin() { return Body; } 361 body_iterator body_end() { return Body + NumStmts; } 362 Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; } 363 364 typedef Stmt* const * const_body_iterator; 365 const_body_iterator body_begin() const { return Body; } 366 const_body_iterator body_end() const { return Body + NumStmts; } 367 const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; } 368 369 typedef std::reverse_iterator<body_iterator> reverse_body_iterator; 370 reverse_body_iterator body_rbegin() { 371 return reverse_body_iterator(body_end()); 372 } 373 reverse_body_iterator body_rend() { 374 return reverse_body_iterator(body_begin()); 375 } 376 377 typedef std::reverse_iterator<const_body_iterator> 378 const_reverse_body_iterator; 379 380 const_reverse_body_iterator body_rbegin() const { 381 return const_reverse_body_iterator(body_end()); 382 } 383 384 const_reverse_body_iterator body_rend() const { 385 return const_reverse_body_iterator(body_begin()); 386 } 387 388 virtual SourceRange getSourceRange() const { 389 return SourceRange(LBracLoc, RBracLoc); 390 } 391 392 SourceLocation getLBracLoc() const { return LBracLoc; } 393 SourceLocation getRBracLoc() const { return RBracLoc; } 394 395 static bool classof(const Stmt *T) { 396 return T->getStmtClass() == CompoundStmtClass; 397 } 398 static bool classof(const CompoundStmt *) { return true; } 399 400 // Iterators 401 virtual child_iterator child_begin(); 402 virtual child_iterator child_end(); 403 404 virtual void EmitImpl(llvm::Serializer& S) const; 405 static CompoundStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 406}; 407 408// SwitchCase is the base class for CaseStmt and DefaultStmt, 409class SwitchCase : public Stmt { 410protected: 411 // A pointer to the following CaseStmt or DefaultStmt class, 412 // used by SwitchStmt. 413 SwitchCase *NextSwitchCase; 414 415 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 416 417public: 418 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 419 420 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 421 422 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 423 424 virtual Stmt* v_getSubStmt() = 0; 425 Stmt *getSubStmt() { return v_getSubStmt(); } 426 427 virtual SourceRange getSourceRange() const { return SourceRange(); } 428 429 static bool classof(const Stmt *T) { 430 return T->getStmtClass() == CaseStmtClass || 431 T->getStmtClass() == DefaultStmtClass; 432 } 433 static bool classof(const SwitchCase *) { return true; } 434}; 435 436class CaseStmt : public SwitchCase { 437 enum { SUBSTMT, LHS, RHS, END_EXPR }; 438 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 439 // GNU "case 1 ... 4" extension 440 SourceLocation CaseLoc; 441public: 442 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 443 : SwitchCase(CaseStmtClass) { 444 SubExprs[SUBSTMT] = substmt; 445 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 446 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 447 CaseLoc = caseLoc; 448 } 449 450 SourceLocation getCaseLoc() const { return CaseLoc; } 451 452 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 453 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 454 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 455 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 456 const Expr *getLHS() const { 457 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 458 } 459 const Expr *getRHS() const { 460 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 461 } 462 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 463 464 void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; } 465 void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } 466 void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } 467 468 469 virtual SourceRange getSourceRange() const { 470 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 471 } 472 static bool classof(const Stmt *T) { 473 return T->getStmtClass() == CaseStmtClass; 474 } 475 static bool classof(const CaseStmt *) { return true; } 476 477 // Iterators 478 virtual child_iterator child_begin(); 479 virtual child_iterator child_end(); 480 481 virtual void EmitImpl(llvm::Serializer& S) const; 482 static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 483}; 484 485class DefaultStmt : public SwitchCase { 486 Stmt* SubStmt; 487 SourceLocation DefaultLoc; 488public: 489 DefaultStmt(SourceLocation DL, Stmt *substmt) : 490 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 491 492 Stmt *getSubStmt() { return SubStmt; } 493 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 494 const Stmt *getSubStmt() const { return SubStmt; } 495 496 SourceLocation getDefaultLoc() const { return DefaultLoc; } 497 498 virtual SourceRange getSourceRange() const { 499 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 500 } 501 static bool classof(const Stmt *T) { 502 return T->getStmtClass() == DefaultStmtClass; 503 } 504 static bool classof(const DefaultStmt *) { return true; } 505 506 // Iterators 507 virtual child_iterator child_begin(); 508 virtual child_iterator child_end(); 509 510 virtual void EmitImpl(llvm::Serializer& S) const; 511 static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 512}; 513 514class LabelStmt : public Stmt { 515 IdentifierInfo *Label; 516 Stmt *SubStmt; 517 SourceLocation IdentLoc; 518public: 519 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 520 : Stmt(LabelStmtClass), Label(label), 521 SubStmt(substmt), IdentLoc(IL) {} 522 523 SourceLocation getIdentLoc() const { return IdentLoc; } 524 IdentifierInfo *getID() const { return Label; } 525 const char *getName() const; 526 Stmt *getSubStmt() { return SubStmt; } 527 const Stmt *getSubStmt() const { return SubStmt; } 528 529 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 530 void setSubStmt(Stmt *SS) { SubStmt = SS; } 531 532 virtual SourceRange getSourceRange() const { 533 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 534 } 535 static bool classof(const Stmt *T) { 536 return T->getStmtClass() == LabelStmtClass; 537 } 538 static bool classof(const LabelStmt *) { return true; } 539 540 // Iterators 541 virtual child_iterator child_begin(); 542 virtual child_iterator child_end(); 543 544 virtual void EmitImpl(llvm::Serializer& S) const; 545 static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 546}; 547 548 549/// IfStmt - This represents an if/then/else. 550/// 551class IfStmt : public Stmt { 552 enum { COND, THEN, ELSE, END_EXPR }; 553 Stmt* SubExprs[END_EXPR]; 554 SourceLocation IfLoc; 555public: 556 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 557 : Stmt(IfStmtClass) { 558 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 559 SubExprs[THEN] = then; 560 SubExprs[ELSE] = elsev; 561 IfLoc = IL; 562 } 563 564 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 565 const Stmt *getThen() const { return SubExprs[THEN]; } 566 const Stmt *getElse() const { return SubExprs[ELSE]; } 567 568 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 569 Stmt *getThen() { return SubExprs[THEN]; } 570 Stmt *getElse() { return SubExprs[ELSE]; } 571 572 virtual SourceRange getSourceRange() const { 573 if (SubExprs[ELSE]) 574 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 575 else 576 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 577 } 578 579 static bool classof(const Stmt *T) { 580 return T->getStmtClass() == IfStmtClass; 581 } 582 static bool classof(const IfStmt *) { return true; } 583 584 // Iterators 585 virtual child_iterator child_begin(); 586 virtual child_iterator child_end(); 587 588 virtual void EmitImpl(llvm::Serializer& S) const; 589 static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 590}; 591 592/// SwitchStmt - This represents a 'switch' stmt. 593/// 594class SwitchStmt : public Stmt { 595 enum { COND, BODY, END_EXPR }; 596 Stmt* SubExprs[END_EXPR]; 597 // This points to a linked list of case and default statements. 598 SwitchCase *FirstCase; 599 SourceLocation SwitchLoc; 600public: 601 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 602 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 603 SubExprs[BODY] = NULL; 604 } 605 606 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 607 const Stmt *getBody() const { return SubExprs[BODY]; } 608 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 609 610 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 611 Stmt *getBody() { return SubExprs[BODY]; } 612 SwitchCase *getSwitchCaseList() { return FirstCase; } 613 614 void setBody(Stmt *S, SourceLocation SL) { 615 SubExprs[BODY] = S; 616 SwitchLoc = SL; 617 } 618 void addSwitchCase(SwitchCase *SC) { 619 if (FirstCase) 620 SC->setNextSwitchCase(FirstCase); 621 622 FirstCase = SC; 623 } 624 virtual SourceRange getSourceRange() const { 625 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 626 } 627 static bool classof(const Stmt *T) { 628 return T->getStmtClass() == SwitchStmtClass; 629 } 630 static bool classof(const SwitchStmt *) { return true; } 631 632 // Iterators 633 virtual child_iterator child_begin(); 634 virtual child_iterator child_end(); 635 636 virtual void EmitImpl(llvm::Serializer& S) const; 637 static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 638}; 639 640 641/// WhileStmt - This represents a 'while' stmt. 642/// 643class WhileStmt : public Stmt { 644 enum { COND, BODY, END_EXPR }; 645 Stmt* SubExprs[END_EXPR]; 646 SourceLocation WhileLoc; 647public: 648 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 649 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 650 SubExprs[BODY] = body; 651 WhileLoc = WL; 652 } 653 654 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 655 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 656 Stmt *getBody() { return SubExprs[BODY]; } 657 const Stmt *getBody() const { return SubExprs[BODY]; } 658 659 virtual SourceRange getSourceRange() const { 660 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 661 } 662 static bool classof(const Stmt *T) { 663 return T->getStmtClass() == WhileStmtClass; 664 } 665 static bool classof(const WhileStmt *) { 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 WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 673}; 674 675/// DoStmt - This represents a 'do/while' stmt. 676/// 677class DoStmt : public Stmt { 678 enum { COND, BODY, END_EXPR }; 679 Stmt* SubExprs[END_EXPR]; 680 SourceLocation DoLoc; 681public: 682 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 683 : Stmt(DoStmtClass), DoLoc(DL) { 684 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 685 SubExprs[BODY] = body; 686 DoLoc = DL; 687 } 688 689 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 690 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 691 Stmt *getBody() { return SubExprs[BODY]; } 692 const Stmt *getBody() const { return SubExprs[BODY]; } 693 694 virtual SourceRange getSourceRange() const { 695 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 696 } 697 static bool classof(const Stmt *T) { 698 return T->getStmtClass() == DoStmtClass; 699 } 700 static bool classof(const DoStmt *) { return true; } 701 702 // Iterators 703 virtual child_iterator child_begin(); 704 virtual child_iterator child_end(); 705 706 virtual void EmitImpl(llvm::Serializer& S) const; 707 static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 708}; 709 710 711/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 712/// the init/cond/inc parts of the ForStmt will be null if they were not 713/// specified in the source. 714/// 715class ForStmt : public Stmt { 716 enum { INIT, COND, INC, BODY, END_EXPR }; 717 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 718 SourceLocation ForLoc; 719public: 720 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 721 : Stmt(ForStmtClass) { 722 SubExprs[INIT] = Init; 723 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 724 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 725 SubExprs[BODY] = Body; 726 ForLoc = FL; 727 } 728 729 Stmt *getInit() { return SubExprs[INIT]; } 730 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 731 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 732 Stmt *getBody() { return SubExprs[BODY]; } 733 734 const Stmt *getInit() const { return SubExprs[INIT]; } 735 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 736 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 737 const Stmt *getBody() const { return SubExprs[BODY]; } 738 739 virtual SourceRange getSourceRange() const { 740 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 741 } 742 static bool classof(const Stmt *T) { 743 return T->getStmtClass() == ForStmtClass; 744 } 745 static bool classof(const ForStmt *) { return true; } 746 747 // Iterators 748 virtual child_iterator child_begin(); 749 virtual child_iterator child_end(); 750 751 virtual void EmitImpl(llvm::Serializer& S) const; 752 static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 753}; 754 755/// GotoStmt - This represents a direct goto. 756/// 757class GotoStmt : public Stmt { 758 LabelStmt *Label; 759 SourceLocation GotoLoc; 760 SourceLocation LabelLoc; 761public: 762 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 763 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 764 765 LabelStmt *getLabel() const { return Label; } 766 767 virtual SourceRange getSourceRange() const { 768 return SourceRange(GotoLoc, LabelLoc); 769 } 770 static bool classof(const Stmt *T) { 771 return T->getStmtClass() == GotoStmtClass; 772 } 773 static bool classof(const GotoStmt *) { return true; } 774 775 // Iterators 776 virtual child_iterator child_begin(); 777 virtual child_iterator child_end(); 778 779 virtual void EmitImpl(llvm::Serializer& S) const; 780 static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 781}; 782 783/// IndirectGotoStmt - This represents an indirect goto. 784/// 785class IndirectGotoStmt : public Stmt { 786 Stmt *Target; 787 // FIXME: Add location information (e.g. SourceLocation objects). 788 // When doing so, update the serialization routines. 789public: 790 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), 791 Target((Stmt*)target){} 792 793 Expr *getTarget(); 794 const Expr *getTarget() const; 795 796 virtual SourceRange getSourceRange() const { return SourceRange(); } 797 798 static bool classof(const Stmt *T) { 799 return T->getStmtClass() == IndirectGotoStmtClass; 800 } 801 static bool classof(const IndirectGotoStmt *) { return true; } 802 803 // Iterators 804 virtual child_iterator child_begin(); 805 virtual child_iterator child_end(); 806 807 virtual void EmitImpl(llvm::Serializer& S) const; 808 static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 809}; 810 811 812/// ContinueStmt - This represents a continue. 813/// 814class ContinueStmt : public Stmt { 815 SourceLocation ContinueLoc; 816public: 817 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 818 819 virtual SourceRange getSourceRange() const { 820 return SourceRange(ContinueLoc); 821 } 822 static bool classof(const Stmt *T) { 823 return T->getStmtClass() == ContinueStmtClass; 824 } 825 static bool classof(const ContinueStmt *) { return true; } 826 827 // Iterators 828 virtual child_iterator child_begin(); 829 virtual child_iterator child_end(); 830 831 virtual void EmitImpl(llvm::Serializer& S) const; 832 static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 833}; 834 835/// BreakStmt - This represents a break. 836/// 837class BreakStmt : public Stmt { 838 SourceLocation BreakLoc; 839public: 840 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 841 842 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 843 844 static bool classof(const Stmt *T) { 845 return T->getStmtClass() == BreakStmtClass; 846 } 847 static bool classof(const BreakStmt *) { return true; } 848 849 // Iterators 850 virtual child_iterator child_begin(); 851 virtual child_iterator child_end(); 852 853 virtual void EmitImpl(llvm::Serializer& S) const; 854 static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 855}; 856 857 858/// ReturnStmt - This represents a return, optionally of an expression: 859/// return; 860/// return 4; 861/// 862/// Note that GCC allows return with no argument in a function declared to 863/// return a value, and it allows returning a value in functions declared to 864/// return void. We explicitly model this in the AST, which means you can't 865/// depend on the return type of the function and the presence of an argument. 866/// 867class ReturnStmt : public Stmt { 868 Stmt *RetExpr; 869 SourceLocation RetLoc; 870public: 871 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 872 RetExpr((Stmt*) E), RetLoc(RL) {} 873 874 const Expr *getRetValue() const; 875 Expr *getRetValue(); 876 877 virtual SourceRange getSourceRange() const; 878 879 static bool classof(const Stmt *T) { 880 return T->getStmtClass() == ReturnStmtClass; 881 } 882 static bool classof(const ReturnStmt *) { return true; } 883 884 // Iterators 885 virtual child_iterator child_begin(); 886 virtual child_iterator child_end(); 887 888 virtual void EmitImpl(llvm::Serializer& S) const; 889 static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 890}; 891 892/// AsmStmt - This represents a GNU inline-assembly statement extension. 893/// 894class AsmStmt : public Stmt { 895 SourceLocation AsmLoc, RParenLoc; 896 StringLiteral *AsmStr; 897 898 bool IsSimple; 899 bool IsVolatile; 900 901 unsigned NumOutputs; 902 unsigned NumInputs; 903 904 llvm::SmallVector<std::string, 4> Names; 905 llvm::SmallVector<StringLiteral*, 4> Constraints; 906 llvm::SmallVector<Stmt*, 4> Exprs; 907 908 llvm::SmallVector<StringLiteral*, 4> Clobbers; 909public: 910 AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 911 unsigned numoutputs, unsigned numinputs, 912 std::string *names, StringLiteral **constraints, 913 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 914 StringLiteral **clobbers, SourceLocation rparenloc); 915 916 bool isVolatile() const { return IsVolatile; } 917 bool isSimple() const { return IsSimple; } 918 919 unsigned getNumOutputs() const { return NumOutputs; } 920 921 const std::string &getOutputName(unsigned i) const { 922 return Names[i]; 923 } 924 925 const StringLiteral *getOutputConstraint(unsigned i) const { 926 return Constraints[i]; 927 } 928 929 StringLiteral *getOutputConstraint(unsigned i) 930 { return Constraints[i]; } 931 932 const Expr *getOutputExpr(unsigned i) const; 933 Expr *getOutputExpr(unsigned i); 934 935 unsigned getNumInputs() const { return NumInputs; } 936 937 const std::string &getInputName(unsigned i) const { 938 return Names[i + NumOutputs]; 939 } 940 StringLiteral *getInputConstraint(unsigned i) { 941 return Constraints[i + NumOutputs]; 942 } 943 const StringLiteral *getInputConstraint(unsigned i) const { 944 return Constraints[i + NumOutputs]; 945 } 946 947 Expr *getInputExpr(unsigned i); 948 const Expr *getInputExpr(unsigned i) const; 949 950 const StringLiteral *getAsmString() const { return AsmStr; } 951 StringLiteral *getAsmString() { return AsmStr; } 952 953 unsigned getNumClobbers() const { return Clobbers.size(); } 954 StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } 955 const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } 956 957 virtual SourceRange getSourceRange() const { 958 return SourceRange(AsmLoc, RParenLoc); 959 } 960 961 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 962 static bool classof(const AsmStmt *) { return true; } 963 964 // Input expr iterators. 965 966 typedef ExprIterator inputs_iterator; 967 typedef ConstExprIterator const_inputs_iterator; 968 969 inputs_iterator begin_inputs() { 970 return &Exprs[0] + NumOutputs; 971 } 972 973 inputs_iterator end_inputs() { 974 return &Exprs[0] + NumOutputs + NumInputs; 975 } 976 977 const_inputs_iterator begin_inputs() const { 978 return &Exprs[0] + NumOutputs; 979 } 980 981 const_inputs_iterator end_inputs() const { 982 return &Exprs[0] + NumOutputs + NumInputs;} 983 984 // Output expr iterators. 985 986 typedef ExprIterator outputs_iterator; 987 typedef ConstExprIterator const_outputs_iterator; 988 989 outputs_iterator begin_outputs() { return &Exprs[0]; } 990 outputs_iterator end_outputs() { return &Exprs[0] + NumOutputs; } 991 992 const_outputs_iterator begin_outputs() const { return &Exprs[0]; } 993 const_outputs_iterator end_outputs() const { return &Exprs[0] + NumOutputs; } 994 995 // Input name iterator. 996 997 const std::string *begin_output_names() const { 998 return &Names[0]; 999 } 1000 1001 const std::string *end_output_names() const { 1002 return &Names[0] + NumOutputs; 1003 } 1004 1005 // Child iterators 1006 1007 virtual child_iterator child_begin(); 1008 virtual child_iterator child_end(); 1009 1010 virtual void EmitImpl(llvm::Serializer& S) const; 1011 static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1012}; 1013 1014/// ObjCForCollectionStmt - This represents Objective-c's collection statement; 1015/// represented as 'for (element 'in' collection-expression)' stmt. 1016/// 1017class ObjCForCollectionStmt : public Stmt { 1018 enum { ELEM, COLLECTION, BODY, END_EXPR }; 1019 Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt. 1020 SourceLocation ForLoc; 1021 SourceLocation RParenLoc; 1022public: 1023 ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, 1024 SourceLocation FCL, SourceLocation RPL); 1025 1026 Stmt *getElement() { return SubExprs[ELEM]; } 1027 Expr *getCollection() { 1028 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 1029 } 1030 Stmt *getBody() { return SubExprs[BODY]; } 1031 1032 const Stmt *getElement() const { return SubExprs[ELEM]; } 1033 const Expr *getCollection() const { 1034 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 1035 } 1036 const Stmt *getBody() const { return SubExprs[BODY]; } 1037 1038 SourceLocation getRParenLoc() const { return RParenLoc; } 1039 1040 virtual SourceRange getSourceRange() const { 1041 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 1042 } 1043 static bool classof(const Stmt *T) { 1044 return T->getStmtClass() == ObjCForCollectionStmtClass; 1045 } 1046 static bool classof(const ObjCForCollectionStmt *) { return true; } 1047 1048 // Iterators 1049 virtual child_iterator child_begin(); 1050 virtual child_iterator child_end(); 1051 1052 virtual void EmitImpl(llvm::Serializer& S) const; 1053 static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1054}; 1055 1056/// ObjCAtCatchStmt - This represents objective-c's @catch statement. 1057class ObjCAtCatchStmt : public Stmt { 1058private: 1059 enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR }; 1060 Stmt *SubExprs[END_EXPR]; 1061 SourceLocation AtCatchLoc, RParenLoc; 1062 1063 // Used by deserialization. 1064 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc) 1065 : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {} 1066 1067public: 1068 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 1069 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList); 1070 1071 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 1072 Stmt *getCatchBody() { return SubExprs[BODY]; } 1073 1074 const ObjCAtCatchStmt *getNextCatchStmt() const { 1075 return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 1076 } 1077 ObjCAtCatchStmt *getNextCatchStmt() { 1078 return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 1079 } 1080 1081 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 1082 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 1083 1084 SourceLocation getRParenLoc() const { return RParenLoc; } 1085 1086 virtual SourceRange getSourceRange() const { 1087 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 1088 } 1089 1090 bool hasEllipsis() const { return getCatchParamStmt() == 0; } 1091 1092 static bool classof(const Stmt *T) { 1093 return T->getStmtClass() == ObjCAtCatchStmtClass; 1094 } 1095 static bool classof(const ObjCAtCatchStmt *) { return true; } 1096 1097 virtual child_iterator child_begin(); 1098 virtual child_iterator child_end(); 1099 1100 virtual void EmitImpl(llvm::Serializer& S) const; 1101 static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1102}; 1103 1104/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement 1105class ObjCAtFinallyStmt : public Stmt { 1106 Stmt *AtFinallyStmt; 1107 SourceLocation AtFinallyLoc; 1108public: 1109 ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 1110 : Stmt(ObjCAtFinallyStmtClass), 1111 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 1112 1113 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 1114 Stmt *getFinallyBody () { return AtFinallyStmt; } 1115 1116 virtual SourceRange getSourceRange() const { 1117 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 1118 } 1119 1120 static bool classof(const Stmt *T) { 1121 return T->getStmtClass() == ObjCAtFinallyStmtClass; 1122 } 1123 static bool classof(const ObjCAtFinallyStmt *) { return true; } 1124 1125 virtual child_iterator child_begin(); 1126 virtual child_iterator child_end(); 1127 1128 virtual void EmitImpl(llvm::Serializer& S) const; 1129 static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1130}; 1131 1132/// ObjCAtTryStmt - This represent objective-c's over-all 1133/// @try ... @catch ... @finally statement. 1134class ObjCAtTryStmt : public Stmt { 1135private: 1136 enum { TRY, CATCH, FINALLY, END_EXPR }; 1137 Stmt* SubStmts[END_EXPR]; 1138 1139 SourceLocation AtTryLoc; 1140public: 1141 ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 1142 Stmt *atCatchStmt, 1143 Stmt *atFinallyStmt) 1144 : Stmt(ObjCAtTryStmtClass) { 1145 SubStmts[TRY] = atTryStmt; 1146 SubStmts[CATCH] = atCatchStmt; 1147 SubStmts[FINALLY] = atFinallyStmt; 1148 AtTryLoc = atTryLoc; 1149 } 1150 1151 const Stmt *getTryBody() const { return SubStmts[TRY]; } 1152 Stmt *getTryBody() { return SubStmts[TRY]; } 1153 const ObjCAtCatchStmt *getCatchStmts() const { 1154 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 1155 } 1156 ObjCAtCatchStmt *getCatchStmts() { 1157 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 1158 } 1159 const ObjCAtFinallyStmt *getFinallyStmt() const { 1160 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 1161 } 1162 ObjCAtFinallyStmt *getFinallyStmt() { 1163 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 1164 } 1165 virtual SourceRange getSourceRange() const { 1166 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 1167 } 1168 1169 static bool classof(const Stmt *T) { 1170 return T->getStmtClass() == ObjCAtTryStmtClass; 1171 } 1172 static bool classof(const ObjCAtTryStmt *) { return true; } 1173 1174 virtual child_iterator child_begin(); 1175 virtual child_iterator child_end(); 1176 1177 virtual void EmitImpl(llvm::Serializer& S) const; 1178 static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1179}; 1180 1181/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement. 1182/// Example: @synchronized (sem) { 1183/// do-something; 1184/// } 1185/// 1186class ObjCAtSynchronizedStmt : public Stmt { 1187private: 1188 enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; 1189 Stmt* SubStmts[END_EXPR]; 1190 SourceLocation AtSynchronizedLoc; 1191 1192public: 1193 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, 1194 Stmt *synchBody) 1195 : Stmt(ObjCAtSynchronizedStmtClass) { 1196 SubStmts[SYNC_EXPR] = synchExpr; 1197 SubStmts[SYNC_BODY] = synchBody; 1198 AtSynchronizedLoc = atSynchronizedLoc; 1199 } 1200 1201 const CompoundStmt *getSynchBody() const { 1202 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1203 } 1204 CompoundStmt *getSynchBody() { 1205 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1206 } 1207 1208 const Expr *getSynchExpr() const { 1209 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1210 } 1211 Expr *getSynchExpr() { 1212 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1213 } 1214 1215 virtual SourceRange getSourceRange() const { 1216 return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd()); 1217 } 1218 1219 static bool classof(const Stmt *T) { 1220 return T->getStmtClass() == ObjCAtSynchronizedStmtClass; 1221 } 1222 static bool classof(const ObjCAtSynchronizedStmt *) { return true; } 1223 1224 virtual child_iterator child_begin(); 1225 virtual child_iterator child_end(); 1226 1227 virtual void EmitImpl(llvm::Serializer& S) const; 1228 static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D, 1229 ASTContext& C); 1230}; 1231 1232/// ObjCAtThrowStmt - This represents objective-c's @throw statement. 1233class ObjCAtThrowStmt : public Stmt { 1234 Stmt *Throw; 1235 SourceLocation AtThrowLoc; 1236public: 1237 ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 1238 : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { 1239 AtThrowLoc = atThrowLoc; 1240 } 1241 1242 const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 1243 Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } 1244 1245 virtual SourceRange getSourceRange() const { 1246 if (Throw) 1247 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 1248 else 1249 return SourceRange(AtThrowLoc); 1250 } 1251 1252 static bool classof(const Stmt *T) { 1253 return T->getStmtClass() == ObjCAtThrowStmtClass; 1254 } 1255 static bool classof(const ObjCAtThrowStmt *) { return true; } 1256 1257 virtual child_iterator child_begin(); 1258 virtual child_iterator child_end(); 1259 1260 virtual void EmitImpl(llvm::Serializer& S) const; 1261 static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1262}; 1263 1264/// CXXCatchStmt - This represents a C++ catch block. 1265class CXXCatchStmt : public Stmt { 1266 SourceLocation CatchLoc; 1267 /// The exception-declaration of the type. 1268 Decl *ExceptionDecl; 1269 /// The handler block. 1270 Stmt *HandlerBlock; 1271 1272public: 1273 CXXCatchStmt(SourceLocation catchLoc, Decl *exDecl, Stmt *handlerBlock) 1274 : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl), 1275 HandlerBlock(handlerBlock) {} 1276 1277 virtual void Destroy(ASTContext& Ctx); 1278 1279 virtual SourceRange getSourceRange() const { 1280 return SourceRange(CatchLoc, HandlerBlock->getLocEnd()); 1281 } 1282 1283 Decl *getExceptionDecl() { return ExceptionDecl; } 1284 QualType getCaughtType(); 1285 Stmt *getHandlerBlock() { return HandlerBlock; } 1286 1287 static bool classof(const Stmt *T) { 1288 return T->getStmtClass() == CXXCatchStmtClass; 1289 } 1290 static bool classof(const CXXCatchStmt *) { return true; } 1291 1292 virtual child_iterator child_begin(); 1293 virtual child_iterator child_end(); 1294 1295 virtual void EmitImpl(llvm::Serializer& S) const; 1296 static CXXCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1297}; 1298 1299/// CXXTryStmt - A C++ try block, including all handlers. 1300class CXXTryStmt : public Stmt { 1301 SourceLocation TryLoc; 1302 // First place is the guarded CompoundStatement. Subsequent are the handlers. 1303 // More than three handlers should be rare. 1304 llvm::SmallVector<Stmt*, 4> Stmts; 1305 1306public: 1307 CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, 1308 Stmt **handlers, unsigned numHandlers); 1309 1310 virtual SourceRange getSourceRange() const { 1311 return SourceRange(TryLoc, Stmts.back()->getLocEnd()); 1312 } 1313 1314 CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); } 1315 const CompoundStmt *getTryBlock() const { 1316 return llvm::cast<CompoundStmt>(Stmts[0]); 1317 } 1318 1319 unsigned getNumHandlers() const { return Stmts.size() - 1; } 1320 CXXCatchStmt *getHandler(unsigned i) { 1321 return llvm::cast<CXXCatchStmt>(Stmts[i + 1]); 1322 } 1323 const CXXCatchStmt *getHandler(unsigned i) const { 1324 return llvm::cast<CXXCatchStmt>(Stmts[i + 1]); 1325 } 1326 1327 static bool classof(const Stmt *T) { 1328 return T->getStmtClass() == CXXTryStmtClass; 1329 } 1330 static bool classof(const CXXTryStmt *) { return true; } 1331 1332 virtual child_iterator child_begin(); 1333 virtual child_iterator child_end(); 1334 1335 virtual void EmitImpl(llvm::Serializer& S) const; 1336 static CXXTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1337}; 1338 1339} // end namespace clang 1340 1341#endif 1342