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