Stmt.h revision 4b07b2968f87f3cd5a3d8c76145f1cbfd718d42d
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 // Child iterators 948 949 virtual child_iterator child_begin(); 950 virtual child_iterator child_end(); 951 952 virtual void EmitImpl(llvm::Serializer& S) const; 953 static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 954}; 955 956/// ObjCForCollectionStmt - This represents Objective-c's collection statement; 957/// represented as 'for (element 'in' collection-expression)' stmt. 958/// 959class ObjCForCollectionStmt : public Stmt { 960 enum { ELEM, COLLECTION, BODY, END_EXPR }; 961 Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt. 962 SourceLocation ForLoc; 963 SourceLocation RParenLoc; 964public: 965 ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, 966 SourceLocation FCL, SourceLocation RPL); 967 968 Stmt *getElement() { return SubExprs[ELEM]; } 969 Expr *getCollection() { 970 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 971 } 972 Stmt *getBody() { return SubExprs[BODY]; } 973 974 const Stmt *getElement() const { return SubExprs[ELEM]; } 975 const Expr *getCollection() const { 976 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 977 } 978 const Stmt *getBody() const { return SubExprs[BODY]; } 979 980 SourceLocation getRParenLoc() const { return RParenLoc; } 981 982 virtual SourceRange getSourceRange() const { 983 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 984 } 985 static bool classof(const Stmt *T) { 986 return T->getStmtClass() == ObjCForCollectionStmtClass; 987 } 988 static bool classof(const ObjCForCollectionStmt *) { return true; } 989 990 // Iterators 991 virtual child_iterator child_begin(); 992 virtual child_iterator child_end(); 993 994 virtual void EmitImpl(llvm::Serializer& S) const; 995 static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 996}; 997 998/// ObjCAtCatchStmt - This represents objective-c's @catch statement. 999class ObjCAtCatchStmt : public Stmt { 1000private: 1001 enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR }; 1002 Stmt *SubExprs[END_EXPR]; 1003 SourceLocation AtCatchLoc, RParenLoc; 1004 1005 // Used by deserialization. 1006 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc) 1007 : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {} 1008 1009public: 1010 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 1011 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList); 1012 1013 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 1014 Stmt *getCatchBody() { return SubExprs[BODY]; } 1015 1016 const ObjCAtCatchStmt *getNextCatchStmt() const { 1017 return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 1018 } 1019 ObjCAtCatchStmt *getNextCatchStmt() { 1020 return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 1021 } 1022 1023 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 1024 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 1025 1026 SourceLocation getRParenLoc() const { return RParenLoc; } 1027 1028 virtual SourceRange getSourceRange() const { 1029 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 1030 } 1031 1032 bool hasEllipsis() const { return getCatchParamStmt() == 0; } 1033 1034 static bool classof(const Stmt *T) { 1035 return T->getStmtClass() == ObjCAtCatchStmtClass; 1036 } 1037 static bool classof(const ObjCAtCatchStmt *) { return true; } 1038 1039 virtual child_iterator child_begin(); 1040 virtual child_iterator child_end(); 1041 1042 virtual void EmitImpl(llvm::Serializer& S) const; 1043 static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1044}; 1045 1046/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement 1047class ObjCAtFinallyStmt : public Stmt { 1048 Stmt *AtFinallyStmt; 1049 SourceLocation AtFinallyLoc; 1050public: 1051 ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 1052 : Stmt(ObjCAtFinallyStmtClass), 1053 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 1054 1055 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 1056 Stmt *getFinallyBody () { return AtFinallyStmt; } 1057 1058 virtual SourceRange getSourceRange() const { 1059 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 1060 } 1061 1062 static bool classof(const Stmt *T) { 1063 return T->getStmtClass() == ObjCAtFinallyStmtClass; 1064 } 1065 static bool classof(const ObjCAtFinallyStmt *) { return true; } 1066 1067 virtual child_iterator child_begin(); 1068 virtual child_iterator child_end(); 1069 1070 virtual void EmitImpl(llvm::Serializer& S) const; 1071 static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1072}; 1073 1074/// ObjCAtTryStmt - This represent objective-c's over-all 1075/// @try ... @catch ... @finally statement. 1076class ObjCAtTryStmt : public Stmt { 1077private: 1078 enum { TRY, CATCH, FINALLY, END_EXPR }; 1079 Stmt* SubStmts[END_EXPR]; 1080 1081 SourceLocation AtTryLoc; 1082public: 1083 ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 1084 Stmt *atCatchStmt, 1085 Stmt *atFinallyStmt) 1086 : Stmt(ObjCAtTryStmtClass) { 1087 SubStmts[TRY] = atTryStmt; 1088 SubStmts[CATCH] = atCatchStmt; 1089 SubStmts[FINALLY] = atFinallyStmt; 1090 AtTryLoc = atTryLoc; 1091 } 1092 1093 const Stmt *getTryBody() const { return SubStmts[TRY]; } 1094 Stmt *getTryBody() { return SubStmts[TRY]; } 1095 const ObjCAtCatchStmt *getCatchStmts() const { 1096 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 1097 } 1098 ObjCAtCatchStmt *getCatchStmts() { 1099 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 1100 } 1101 const ObjCAtFinallyStmt *getFinallyStmt() const { 1102 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 1103 } 1104 ObjCAtFinallyStmt *getFinallyStmt() { 1105 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 1106 } 1107 virtual SourceRange getSourceRange() const { 1108 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 1109 } 1110 1111 static bool classof(const Stmt *T) { 1112 return T->getStmtClass() == ObjCAtTryStmtClass; 1113 } 1114 static bool classof(const ObjCAtTryStmt *) { return true; } 1115 1116 virtual child_iterator child_begin(); 1117 virtual child_iterator child_end(); 1118 1119 virtual void EmitImpl(llvm::Serializer& S) const; 1120 static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1121}; 1122 1123/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement. 1124/// Example: @synchronized (sem) { 1125/// do-something; 1126/// } 1127/// 1128class ObjCAtSynchronizedStmt : public Stmt { 1129private: 1130 enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; 1131 Stmt* SubStmts[END_EXPR]; 1132 SourceLocation AtSynchronizedLoc; 1133 1134public: 1135 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, 1136 Stmt *synchBody) 1137 : Stmt(ObjCAtSynchronizedStmtClass) { 1138 SubStmts[SYNC_EXPR] = synchExpr; 1139 SubStmts[SYNC_BODY] = synchBody; 1140 AtSynchronizedLoc = atSynchronizedLoc; 1141 } 1142 1143 const CompoundStmt *getSynchBody() const { 1144 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1145 } 1146 CompoundStmt *getSynchBody() { 1147 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1148 } 1149 1150 const Expr *getSynchExpr() const { 1151 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1152 } 1153 Expr *getSynchExpr() { 1154 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1155 } 1156 1157 virtual SourceRange getSourceRange() const { 1158 return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd()); 1159 } 1160 1161 static bool classof(const Stmt *T) { 1162 return T->getStmtClass() == ObjCAtSynchronizedStmtClass; 1163 } 1164 static bool classof(const ObjCAtSynchronizedStmt *) { return true; } 1165 1166 virtual child_iterator child_begin(); 1167 virtual child_iterator child_end(); 1168 1169 virtual void EmitImpl(llvm::Serializer& S) const; 1170 static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D, 1171 ASTContext& C); 1172}; 1173 1174/// ObjCAtThrowStmt - This represents objective-c's @throw statement. 1175class ObjCAtThrowStmt : public Stmt { 1176 Stmt *Throw; 1177 SourceLocation AtThrowLoc; 1178public: 1179 ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 1180 : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { 1181 AtThrowLoc = atThrowLoc; 1182 } 1183 1184 const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 1185 Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } 1186 1187 virtual SourceRange getSourceRange() const { 1188 if (Throw) 1189 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 1190 else 1191 return SourceRange(AtThrowLoc); 1192 } 1193 1194 static bool classof(const Stmt *T) { 1195 return T->getStmtClass() == ObjCAtThrowStmtClass; 1196 } 1197 static bool classof(const ObjCAtThrowStmt *) { return true; } 1198 1199 virtual child_iterator child_begin(); 1200 virtual child_iterator child_end(); 1201 1202 virtual void EmitImpl(llvm::Serializer& S) const; 1203 static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1204}; 1205 1206/// CXXCatchStmt - This represents a C++ catch block. 1207class CXXCatchStmt : public Stmt { 1208 SourceLocation CatchLoc; 1209 /// The exception-declaration of the type. 1210 Decl *ExceptionDecl; 1211 /// The handler block. 1212 Stmt *HandlerBlock; 1213 1214public: 1215 CXXCatchStmt(SourceLocation catchLoc, Decl *exDecl, Stmt *handlerBlock) 1216 : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl), 1217 HandlerBlock(handlerBlock) {} 1218 1219 virtual void Destroy(ASTContext& Ctx); 1220 1221 virtual SourceRange getSourceRange() const { 1222 return SourceRange(CatchLoc, HandlerBlock->getLocEnd()); 1223 } 1224 1225 Decl *getExceptionDecl() { return ExceptionDecl; } 1226 QualType getCaughtType(); 1227 Stmt *getHandlerBlock() { return HandlerBlock; } 1228 1229 static bool classof(const Stmt *T) { 1230 return T->getStmtClass() == CXXCatchStmtClass; 1231 } 1232 static bool classof(const CXXCatchStmt *) { return true; } 1233 1234 virtual child_iterator child_begin(); 1235 virtual child_iterator child_end(); 1236 1237 virtual void EmitImpl(llvm::Serializer& S) const; 1238 static CXXCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1239}; 1240 1241} // end namespace clang 1242 1243#endif 1244