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