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