Stmt.h revision 24e1e707b4c362f18e371e2bbf054a8345b57bfa
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 virtual Stmt* v_getSubStmt() = 0; 426 Stmt *getSubStmt() { return v_getSubStmt(); } 427 428 virtual SourceRange getSourceRange() const { return SourceRange(); } 429 430 static bool classof(const Stmt *T) { 431 return T->getStmtClass() == CaseStmtClass || 432 T->getStmtClass() == DefaultStmtClass; 433 } 434 static bool classof(const SwitchCase *) { return true; } 435}; 436 437class CaseStmt : public SwitchCase { 438 enum { SUBSTMT, LHS, RHS, END_EXPR }; 439 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 440 // GNU "case 1 ... 4" extension 441 SourceLocation CaseLoc; 442public: 443 CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc) 444 : SwitchCase(CaseStmtClass) { 445 SubExprs[SUBSTMT] = 0; 446 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 447 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 448 CaseLoc = caseLoc; 449 } 450 451 SourceLocation getCaseLoc() const { return CaseLoc; } 452 453 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 454 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 455 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 456 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 457 const Expr *getLHS() const { 458 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 459 } 460 const Expr *getRHS() const { 461 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 462 } 463 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 464 465 void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; } 466 void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } 467 void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } 468 469 470 virtual SourceRange getSourceRange() const { 471 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 472 } 473 static bool classof(const Stmt *T) { 474 return T->getStmtClass() == CaseStmtClass; 475 } 476 static bool classof(const CaseStmt *) { return true; } 477 478 // Iterators 479 virtual child_iterator child_begin(); 480 virtual child_iterator child_end(); 481 482 virtual void EmitImpl(llvm::Serializer& S) const; 483 static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 484}; 485 486class DefaultStmt : public SwitchCase { 487 Stmt* SubStmt; 488 SourceLocation DefaultLoc; 489public: 490 DefaultStmt(SourceLocation DL, Stmt *substmt) : 491 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 492 493 Stmt *getSubStmt() { return SubStmt; } 494 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 495 const Stmt *getSubStmt() const { return SubStmt; } 496 497 SourceLocation getDefaultLoc() const { return DefaultLoc; } 498 499 virtual SourceRange getSourceRange() const { 500 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 501 } 502 static bool classof(const Stmt *T) { 503 return T->getStmtClass() == DefaultStmtClass; 504 } 505 static bool classof(const DefaultStmt *) { return true; } 506 507 // Iterators 508 virtual child_iterator child_begin(); 509 virtual child_iterator child_end(); 510 511 virtual void EmitImpl(llvm::Serializer& S) const; 512 static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 513}; 514 515class LabelStmt : public Stmt { 516 IdentifierInfo *Label; 517 Stmt *SubStmt; 518 SourceLocation IdentLoc; 519public: 520 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 521 : Stmt(LabelStmtClass), Label(label), 522 SubStmt(substmt), IdentLoc(IL) {} 523 524 SourceLocation getIdentLoc() const { return IdentLoc; } 525 IdentifierInfo *getID() const { return Label; } 526 const char *getName() const; 527 Stmt *getSubStmt() { return SubStmt; } 528 const Stmt *getSubStmt() const { return SubStmt; } 529 530 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 531 void setSubStmt(Stmt *SS) { SubStmt = SS; } 532 533 virtual SourceRange getSourceRange() const { 534 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 535 } 536 static bool classof(const Stmt *T) { 537 return T->getStmtClass() == LabelStmtClass; 538 } 539 static bool classof(const LabelStmt *) { return true; } 540 541 // Iterators 542 virtual child_iterator child_begin(); 543 virtual child_iterator child_end(); 544 545 virtual void EmitImpl(llvm::Serializer& S) const; 546 static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 547}; 548 549 550/// IfStmt - This represents an if/then/else. 551/// 552class IfStmt : public Stmt { 553 enum { COND, THEN, ELSE, END_EXPR }; 554 Stmt* SubExprs[END_EXPR]; 555 SourceLocation IfLoc; 556public: 557 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 558 : Stmt(IfStmtClass) { 559 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 560 SubExprs[THEN] = then; 561 SubExprs[ELSE] = elsev; 562 IfLoc = IL; 563 } 564 565 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 566 const Stmt *getThen() const { return SubExprs[THEN]; } 567 const Stmt *getElse() const { return SubExprs[ELSE]; } 568 569 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 570 Stmt *getThen() { return SubExprs[THEN]; } 571 Stmt *getElse() { return SubExprs[ELSE]; } 572 573 virtual SourceRange getSourceRange() const { 574 if (SubExprs[ELSE]) 575 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 576 else 577 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 578 } 579 580 static bool classof(const Stmt *T) { 581 return T->getStmtClass() == IfStmtClass; 582 } 583 static bool classof(const IfStmt *) { return true; } 584 585 // Iterators 586 virtual child_iterator child_begin(); 587 virtual child_iterator child_end(); 588 589 virtual void EmitImpl(llvm::Serializer& S) const; 590 static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 591}; 592 593/// SwitchStmt - This represents a 'switch' stmt. 594/// 595class SwitchStmt : public Stmt { 596 enum { COND, BODY, END_EXPR }; 597 Stmt* SubExprs[END_EXPR]; 598 // This points to a linked list of case and default statements. 599 SwitchCase *FirstCase; 600 SourceLocation SwitchLoc; 601public: 602 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 603 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 604 SubExprs[BODY] = NULL; 605 } 606 607 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 608 const Stmt *getBody() const { return SubExprs[BODY]; } 609 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 610 611 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 612 Stmt *getBody() { return SubExprs[BODY]; } 613 SwitchCase *getSwitchCaseList() { return FirstCase; } 614 615 void setBody(Stmt *S, SourceLocation SL) { 616 SubExprs[BODY] = S; 617 SwitchLoc = SL; 618 } 619 void addSwitchCase(SwitchCase *SC) { 620 if (FirstCase) 621 SC->setNextSwitchCase(FirstCase); 622 623 FirstCase = SC; 624 } 625 virtual SourceRange getSourceRange() const { 626 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 627 } 628 static bool classof(const Stmt *T) { 629 return T->getStmtClass() == SwitchStmtClass; 630 } 631 static bool classof(const SwitchStmt *) { return true; } 632 633 // Iterators 634 virtual child_iterator child_begin(); 635 virtual child_iterator child_end(); 636 637 virtual void EmitImpl(llvm::Serializer& S) const; 638 static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 639}; 640 641 642/// WhileStmt - This represents a 'while' stmt. 643/// 644class WhileStmt : public Stmt { 645 enum { COND, BODY, END_EXPR }; 646 Stmt* SubExprs[END_EXPR]; 647 SourceLocation WhileLoc; 648public: 649 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 650 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 651 SubExprs[BODY] = body; 652 WhileLoc = WL; 653 } 654 655 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 656 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 657 Stmt *getBody() { return SubExprs[BODY]; } 658 const Stmt *getBody() const { return SubExprs[BODY]; } 659 660 virtual SourceRange getSourceRange() const { 661 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 662 } 663 static bool classof(const Stmt *T) { 664 return T->getStmtClass() == WhileStmtClass; 665 } 666 static bool classof(const WhileStmt *) { return true; } 667 668 // Iterators 669 virtual child_iterator child_begin(); 670 virtual child_iterator child_end(); 671 672 virtual void EmitImpl(llvm::Serializer& S) const; 673 static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 674}; 675 676/// DoStmt - This represents a 'do/while' stmt. 677/// 678class DoStmt : public Stmt { 679 enum { COND, BODY, END_EXPR }; 680 Stmt* SubExprs[END_EXPR]; 681 SourceLocation DoLoc; 682public: 683 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 684 : Stmt(DoStmtClass), DoLoc(DL) { 685 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 686 SubExprs[BODY] = body; 687 DoLoc = DL; 688 } 689 690 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 691 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 692 Stmt *getBody() { return SubExprs[BODY]; } 693 const Stmt *getBody() const { return SubExprs[BODY]; } 694 695 virtual SourceRange getSourceRange() const { 696 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 697 } 698 static bool classof(const Stmt *T) { 699 return T->getStmtClass() == DoStmtClass; 700 } 701 static bool classof(const DoStmt *) { return true; } 702 703 // Iterators 704 virtual child_iterator child_begin(); 705 virtual child_iterator child_end(); 706 707 virtual void EmitImpl(llvm::Serializer& S) const; 708 static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 709}; 710 711 712/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 713/// the init/cond/inc parts of the ForStmt will be null if they were not 714/// specified in the source. 715/// 716class ForStmt : public Stmt { 717 enum { INIT, COND, INC, BODY, END_EXPR }; 718 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 719 SourceLocation ForLoc; 720public: 721 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 722 : Stmt(ForStmtClass) { 723 SubExprs[INIT] = Init; 724 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 725 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 726 SubExprs[BODY] = Body; 727 ForLoc = FL; 728 } 729 730 Stmt *getInit() { return SubExprs[INIT]; } 731 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 732 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 733 Stmt *getBody() { return SubExprs[BODY]; } 734 735 const Stmt *getInit() const { return SubExprs[INIT]; } 736 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 737 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 738 const Stmt *getBody() const { return SubExprs[BODY]; } 739 740 virtual SourceRange getSourceRange() const { 741 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 742 } 743 static bool classof(const Stmt *T) { 744 return T->getStmtClass() == ForStmtClass; 745 } 746 static bool classof(const ForStmt *) { return true; } 747 748 // Iterators 749 virtual child_iterator child_begin(); 750 virtual child_iterator child_end(); 751 752 virtual void EmitImpl(llvm::Serializer& S) const; 753 static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 754}; 755 756/// GotoStmt - This represents a direct goto. 757/// 758class GotoStmt : public Stmt { 759 LabelStmt *Label; 760 SourceLocation GotoLoc; 761 SourceLocation LabelLoc; 762public: 763 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 764 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 765 766 LabelStmt *getLabel() const { return Label; } 767 768 virtual SourceRange getSourceRange() const { 769 return SourceRange(GotoLoc, LabelLoc); 770 } 771 static bool classof(const Stmt *T) { 772 return T->getStmtClass() == GotoStmtClass; 773 } 774 static bool classof(const GotoStmt *) { return true; } 775 776 // Iterators 777 virtual child_iterator child_begin(); 778 virtual child_iterator child_end(); 779 780 virtual void EmitImpl(llvm::Serializer& S) const; 781 static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 782}; 783 784/// IndirectGotoStmt - This represents an indirect goto. 785/// 786class IndirectGotoStmt : public Stmt { 787 Stmt *Target; 788 // FIXME: Add location information (e.g. SourceLocation objects). 789 // When doing so, update the serialization routines. 790public: 791 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), 792 Target((Stmt*)target){} 793 794 Expr *getTarget(); 795 const Expr *getTarget() const; 796 797 virtual SourceRange getSourceRange() const { return SourceRange(); } 798 799 static bool classof(const Stmt *T) { 800 return T->getStmtClass() == IndirectGotoStmtClass; 801 } 802 static bool classof(const IndirectGotoStmt *) { return true; } 803 804 // Iterators 805 virtual child_iterator child_begin(); 806 virtual child_iterator child_end(); 807 808 virtual void EmitImpl(llvm::Serializer& S) const; 809 static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 810}; 811 812 813/// ContinueStmt - This represents a continue. 814/// 815class ContinueStmt : public Stmt { 816 SourceLocation ContinueLoc; 817public: 818 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 819 820 virtual SourceRange getSourceRange() const { 821 return SourceRange(ContinueLoc); 822 } 823 static bool classof(const Stmt *T) { 824 return T->getStmtClass() == ContinueStmtClass; 825 } 826 static bool classof(const ContinueStmt *) { return true; } 827 828 // Iterators 829 virtual child_iterator child_begin(); 830 virtual child_iterator child_end(); 831 832 virtual void EmitImpl(llvm::Serializer& S) const; 833 static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 834}; 835 836/// BreakStmt - This represents a break. 837/// 838class BreakStmt : public Stmt { 839 SourceLocation BreakLoc; 840public: 841 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 842 843 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 844 845 static bool classof(const Stmt *T) { 846 return T->getStmtClass() == BreakStmtClass; 847 } 848 static bool classof(const BreakStmt *) { return true; } 849 850 // Iterators 851 virtual child_iterator child_begin(); 852 virtual child_iterator child_end(); 853 854 virtual void EmitImpl(llvm::Serializer& S) const; 855 static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 856}; 857 858 859/// ReturnStmt - This represents a return, optionally of an expression: 860/// return; 861/// return 4; 862/// 863/// Note that GCC allows return with no argument in a function declared to 864/// return a value, and it allows returning a value in functions declared to 865/// return void. We explicitly model this in the AST, which means you can't 866/// depend on the return type of the function and the presence of an argument. 867/// 868class ReturnStmt : public Stmt { 869 Stmt *RetExpr; 870 SourceLocation RetLoc; 871public: 872 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 873 RetExpr((Stmt*) E), RetLoc(RL) {} 874 875 const Expr *getRetValue() const; 876 Expr *getRetValue(); 877 878 virtual SourceRange getSourceRange() const; 879 880 static bool classof(const Stmt *T) { 881 return T->getStmtClass() == ReturnStmtClass; 882 } 883 static bool classof(const ReturnStmt *) { return true; } 884 885 // Iterators 886 virtual child_iterator child_begin(); 887 virtual child_iterator child_end(); 888 889 virtual void EmitImpl(llvm::Serializer& S) const; 890 static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 891}; 892 893/// AsmStmt - This represents a GNU inline-assembly statement extension. 894/// 895class AsmStmt : public Stmt { 896 SourceLocation AsmLoc, RParenLoc; 897 StringLiteral *AsmStr; 898 899 bool IsSimple; 900 bool IsVolatile; 901 902 unsigned NumOutputs; 903 unsigned NumInputs; 904 905 llvm::SmallVector<std::string, 4> Names; 906 llvm::SmallVector<StringLiteral*, 4> Constraints; 907 llvm::SmallVector<Stmt*, 4> Exprs; 908 909 llvm::SmallVector<StringLiteral*, 4> Clobbers; 910public: 911 AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 912 unsigned numoutputs, unsigned numinputs, 913 std::string *names, StringLiteral **constraints, 914 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 915 StringLiteral **clobbers, SourceLocation rparenloc); 916 917 bool isVolatile() const { return IsVolatile; } 918 bool isSimple() const { return IsSimple; } 919 920 unsigned getNumOutputs() const { return NumOutputs; } 921 922 const std::string &getOutputName(unsigned i) const { 923 return Names[i]; 924 } 925 926 const StringLiteral *getOutputConstraint(unsigned i) const { 927 return Constraints[i]; 928 } 929 930 StringLiteral *getOutputConstraint(unsigned i) 931 { return Constraints[i]; } 932 933 const Expr *getOutputExpr(unsigned i) const; 934 Expr *getOutputExpr(unsigned i); 935 936 unsigned getNumInputs() const { return NumInputs; } 937 938 const std::string &getInputName(unsigned i) const { 939 return Names[i + NumOutputs]; 940 } 941 StringLiteral *getInputConstraint(unsigned i) { 942 return Constraints[i + NumOutputs]; 943 } 944 const StringLiteral *getInputConstraint(unsigned i) const { 945 return Constraints[i + NumOutputs]; 946 } 947 948 Expr *getInputExpr(unsigned i); 949 const Expr *getInputExpr(unsigned i) const; 950 951 const StringLiteral *getAsmString() const { return AsmStr; } 952 StringLiteral *getAsmString() { return AsmStr; } 953 954 unsigned getNumClobbers() const { return Clobbers.size(); } 955 StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } 956 const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } 957 958 virtual SourceRange getSourceRange() const { 959 return SourceRange(AsmLoc, RParenLoc); 960 } 961 962 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 963 static bool classof(const AsmStmt *) { return true; } 964 965 // Input expr iterators. 966 967 typedef ExprIterator inputs_iterator; 968 typedef ConstExprIterator const_inputs_iterator; 969 970 inputs_iterator begin_inputs() { 971 return &Exprs[0] + NumOutputs; 972 } 973 974 inputs_iterator end_inputs() { 975 return &Exprs[0] + NumOutputs + NumInputs; 976 } 977 978 const_inputs_iterator begin_inputs() const { 979 return &Exprs[0] + NumOutputs; 980 } 981 982 const_inputs_iterator end_inputs() const { 983 return &Exprs[0] + NumOutputs + NumInputs;} 984 985 // Output expr iterators. 986 987 typedef ExprIterator outputs_iterator; 988 typedef ConstExprIterator const_outputs_iterator; 989 990 outputs_iterator begin_outputs() { return &Exprs[0]; } 991 outputs_iterator end_outputs() { return &Exprs[0] + NumOutputs; } 992 993 const_outputs_iterator begin_outputs() const { return &Exprs[0]; } 994 const_outputs_iterator end_outputs() const { return &Exprs[0] + NumOutputs; } 995 996 // Input name iterator. 997 998 const std::string *begin_output_names() const { 999 return &Names[0]; 1000 } 1001 1002 const std::string *end_output_names() const { 1003 return &Names[0] + NumOutputs; 1004 } 1005 1006 // Child iterators 1007 1008 virtual child_iterator child_begin(); 1009 virtual child_iterator child_end(); 1010 1011 virtual void EmitImpl(llvm::Serializer& S) const; 1012 static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1013}; 1014 1015/// ObjCForCollectionStmt - This represents Objective-c's collection statement; 1016/// represented as 'for (element 'in' collection-expression)' stmt. 1017/// 1018class ObjCForCollectionStmt : public Stmt { 1019 enum { ELEM, COLLECTION, BODY, END_EXPR }; 1020 Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt. 1021 SourceLocation ForLoc; 1022 SourceLocation RParenLoc; 1023public: 1024 ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, 1025 SourceLocation FCL, SourceLocation RPL); 1026 1027 Stmt *getElement() { return SubExprs[ELEM]; } 1028 Expr *getCollection() { 1029 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 1030 } 1031 Stmt *getBody() { return SubExprs[BODY]; } 1032 1033 const Stmt *getElement() const { return SubExprs[ELEM]; } 1034 const Expr *getCollection() const { 1035 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 1036 } 1037 const Stmt *getBody() const { return SubExprs[BODY]; } 1038 1039 SourceLocation getRParenLoc() const { return RParenLoc; } 1040 1041 virtual SourceRange getSourceRange() const { 1042 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 1043 } 1044 static bool classof(const Stmt *T) { 1045 return T->getStmtClass() == ObjCForCollectionStmtClass; 1046 } 1047 static bool classof(const ObjCForCollectionStmt *) { return true; } 1048 1049 // Iterators 1050 virtual child_iterator child_begin(); 1051 virtual child_iterator child_end(); 1052 1053 virtual void EmitImpl(llvm::Serializer& S) const; 1054 static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1055}; 1056 1057/// ObjCAtCatchStmt - This represents objective-c's @catch statement. 1058class ObjCAtCatchStmt : public Stmt { 1059private: 1060 enum { BODY, NEXT_CATCH, END_EXPR }; 1061 ParmVarDecl *ExceptionDecl; 1062 Stmt *SubExprs[END_EXPR]; 1063 SourceLocation AtCatchLoc, RParenLoc; 1064 1065 // Used by deserialization. 1066 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc) 1067 : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {} 1068 1069public: 1070 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 1071 ParmVarDecl *catchVarDecl, 1072 Stmt *atCatchStmt, Stmt *atCatchList); 1073 1074 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 1075 Stmt *getCatchBody() { return SubExprs[BODY]; } 1076 1077 const ObjCAtCatchStmt *getNextCatchStmt() const { 1078 return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 1079 } 1080 ObjCAtCatchStmt *getNextCatchStmt() { 1081 return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 1082 } 1083 1084 const ParmVarDecl *getCatchParamDecl() const { 1085 return ExceptionDecl; 1086 } 1087 ParmVarDecl *getCatchParamDecl() { 1088 return ExceptionDecl; 1089 } 1090 1091 SourceLocation getRParenLoc() const { return RParenLoc; } 1092 1093 virtual SourceRange getSourceRange() const { 1094 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 1095 } 1096 1097 bool hasEllipsis() const { return getCatchParamDecl() == 0; } 1098 1099 static bool classof(const Stmt *T) { 1100 return T->getStmtClass() == ObjCAtCatchStmtClass; 1101 } 1102 static bool classof(const ObjCAtCatchStmt *) { return true; } 1103 1104 virtual child_iterator child_begin(); 1105 virtual child_iterator child_end(); 1106 1107 virtual void EmitImpl(llvm::Serializer& S) const; 1108 static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1109}; 1110 1111/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement 1112class ObjCAtFinallyStmt : public Stmt { 1113 Stmt *AtFinallyStmt; 1114 SourceLocation AtFinallyLoc; 1115public: 1116 ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 1117 : Stmt(ObjCAtFinallyStmtClass), 1118 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 1119 1120 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 1121 Stmt *getFinallyBody () { return AtFinallyStmt; } 1122 1123 virtual SourceRange getSourceRange() const { 1124 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 1125 } 1126 1127 static bool classof(const Stmt *T) { 1128 return T->getStmtClass() == ObjCAtFinallyStmtClass; 1129 } 1130 static bool classof(const ObjCAtFinallyStmt *) { return true; } 1131 1132 virtual child_iterator child_begin(); 1133 virtual child_iterator child_end(); 1134 1135 virtual void EmitImpl(llvm::Serializer& S) const; 1136 static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1137}; 1138 1139/// ObjCAtTryStmt - This represent objective-c's over-all 1140/// @try ... @catch ... @finally statement. 1141class ObjCAtTryStmt : public Stmt { 1142private: 1143 enum { TRY, CATCH, FINALLY, END_EXPR }; 1144 Stmt* SubStmts[END_EXPR]; 1145 1146 SourceLocation AtTryLoc; 1147public: 1148 ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 1149 Stmt *atCatchStmt, 1150 Stmt *atFinallyStmt) 1151 : Stmt(ObjCAtTryStmtClass) { 1152 SubStmts[TRY] = atTryStmt; 1153 SubStmts[CATCH] = atCatchStmt; 1154 SubStmts[FINALLY] = atFinallyStmt; 1155 AtTryLoc = atTryLoc; 1156 } 1157 1158 const Stmt *getTryBody() const { return SubStmts[TRY]; } 1159 Stmt *getTryBody() { return SubStmts[TRY]; } 1160 const ObjCAtCatchStmt *getCatchStmts() const { 1161 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 1162 } 1163 ObjCAtCatchStmt *getCatchStmts() { 1164 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 1165 } 1166 const ObjCAtFinallyStmt *getFinallyStmt() const { 1167 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 1168 } 1169 ObjCAtFinallyStmt *getFinallyStmt() { 1170 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 1171 } 1172 virtual SourceRange getSourceRange() const { 1173 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 1174 } 1175 1176 static bool classof(const Stmt *T) { 1177 return T->getStmtClass() == ObjCAtTryStmtClass; 1178 } 1179 static bool classof(const ObjCAtTryStmt *) { return true; } 1180 1181 virtual child_iterator child_begin(); 1182 virtual child_iterator child_end(); 1183 1184 virtual void EmitImpl(llvm::Serializer& S) const; 1185 static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1186}; 1187 1188/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement. 1189/// Example: @synchronized (sem) { 1190/// do-something; 1191/// } 1192/// 1193class ObjCAtSynchronizedStmt : public Stmt { 1194private: 1195 enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; 1196 Stmt* SubStmts[END_EXPR]; 1197 SourceLocation AtSynchronizedLoc; 1198 1199public: 1200 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, 1201 Stmt *synchBody) 1202 : Stmt(ObjCAtSynchronizedStmtClass) { 1203 SubStmts[SYNC_EXPR] = synchExpr; 1204 SubStmts[SYNC_BODY] = synchBody; 1205 AtSynchronizedLoc = atSynchronizedLoc; 1206 } 1207 1208 const CompoundStmt *getSynchBody() const { 1209 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1210 } 1211 CompoundStmt *getSynchBody() { 1212 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1213 } 1214 1215 const Expr *getSynchExpr() const { 1216 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1217 } 1218 Expr *getSynchExpr() { 1219 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1220 } 1221 1222 virtual SourceRange getSourceRange() const { 1223 return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd()); 1224 } 1225 1226 static bool classof(const Stmt *T) { 1227 return T->getStmtClass() == ObjCAtSynchronizedStmtClass; 1228 } 1229 static bool classof(const ObjCAtSynchronizedStmt *) { return true; } 1230 1231 virtual child_iterator child_begin(); 1232 virtual child_iterator child_end(); 1233 1234 virtual void EmitImpl(llvm::Serializer& S) const; 1235 static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D, 1236 ASTContext& C); 1237}; 1238 1239/// ObjCAtThrowStmt - This represents objective-c's @throw statement. 1240class ObjCAtThrowStmt : public Stmt { 1241 Stmt *Throw; 1242 SourceLocation AtThrowLoc; 1243public: 1244 ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 1245 : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { 1246 AtThrowLoc = atThrowLoc; 1247 } 1248 1249 const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 1250 Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } 1251 1252 virtual SourceRange getSourceRange() const { 1253 if (Throw) 1254 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 1255 else 1256 return SourceRange(AtThrowLoc); 1257 } 1258 1259 static bool classof(const Stmt *T) { 1260 return T->getStmtClass() == ObjCAtThrowStmtClass; 1261 } 1262 static bool classof(const ObjCAtThrowStmt *) { return true; } 1263 1264 virtual child_iterator child_begin(); 1265 virtual child_iterator child_end(); 1266 1267 virtual void EmitImpl(llvm::Serializer& S) const; 1268 static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1269}; 1270 1271/// CXXCatchStmt - This represents a C++ catch block. 1272class CXXCatchStmt : public Stmt { 1273 SourceLocation CatchLoc; 1274 /// The exception-declaration of the type. 1275 Decl *ExceptionDecl; 1276 /// The handler block. 1277 Stmt *HandlerBlock; 1278 1279public: 1280 CXXCatchStmt(SourceLocation catchLoc, Decl *exDecl, Stmt *handlerBlock) 1281 : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl), 1282 HandlerBlock(handlerBlock) {} 1283 1284 virtual void Destroy(ASTContext& Ctx); 1285 1286 virtual SourceRange getSourceRange() const { 1287 return SourceRange(CatchLoc, HandlerBlock->getLocEnd()); 1288 } 1289 1290 Decl *getExceptionDecl() { return ExceptionDecl; } 1291 QualType getCaughtType(); 1292 Stmt *getHandlerBlock() { return HandlerBlock; } 1293 1294 static bool classof(const Stmt *T) { 1295 return T->getStmtClass() == CXXCatchStmtClass; 1296 } 1297 static bool classof(const CXXCatchStmt *) { return true; } 1298 1299 virtual child_iterator child_begin(); 1300 virtual child_iterator child_end(); 1301 1302 virtual void EmitImpl(llvm::Serializer& S) const; 1303 static CXXCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1304}; 1305 1306/// CXXTryStmt - A C++ try block, including all handlers. 1307class CXXTryStmt : public Stmt { 1308 SourceLocation TryLoc; 1309 // First place is the guarded CompoundStatement. Subsequent are the handlers. 1310 // More than three handlers should be rare. 1311 llvm::SmallVector<Stmt*, 4> Stmts; 1312 1313public: 1314 CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, 1315 Stmt **handlers, unsigned numHandlers); 1316 1317 virtual SourceRange getSourceRange() const { 1318 return SourceRange(TryLoc, Stmts.back()->getLocEnd()); 1319 } 1320 1321 CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); } 1322 const CompoundStmt *getTryBlock() const { 1323 return llvm::cast<CompoundStmt>(Stmts[0]); 1324 } 1325 1326 unsigned getNumHandlers() const { return Stmts.size() - 1; } 1327 CXXCatchStmt *getHandler(unsigned i) { 1328 return llvm::cast<CXXCatchStmt>(Stmts[i + 1]); 1329 } 1330 const CXXCatchStmt *getHandler(unsigned i) const { 1331 return llvm::cast<CXXCatchStmt>(Stmts[i + 1]); 1332 } 1333 1334 static bool classof(const Stmt *T) { 1335 return T->getStmtClass() == CXXTryStmtClass; 1336 } 1337 static bool classof(const CXXTryStmt *) { return true; } 1338 1339 virtual child_iterator child_begin(); 1340 virtual child_iterator child_end(); 1341 1342 virtual void EmitImpl(llvm::Serializer& S) const; 1343 static CXXTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1344}; 1345 1346} // end namespace clang 1347 1348#endif 1349