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