Stmt.h revision 5f1b9e689fa5c101512aef99225f2afea1673449
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 "clang/AST/ASTContext.h" 25#include <string> 26using llvm::dyn_cast_or_null; 27 28namespace clang { 29 class ASTContext; 30 class Expr; 31 class Decl; 32 class ParmVarDecl; 33 class QualType; 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 106 // Make vanilla 'new' and 'delete' illegal for Stmts. 107protected: 108 void* operator new(size_t bytes) throw() { 109 assert(0 && "Stmts cannot be allocated with regular 'new'."); 110 return 0; 111 } 112 void operator delete(void* data) throw() { 113 assert(0 && "Stmts cannot be released with regular 'delete'."); 114 } 115 116public: 117 // Only allow allocation of Stmts using the allocator in ASTContext 118 // or by doing a placement new. 119 void* operator new(size_t bytes, ASTContext& C, 120 unsigned alignment = 16) throw() { 121 return ::operator new(bytes, C, alignment); 122 } 123 124 void* operator new(size_t bytes, ASTContext* C, 125 unsigned alignment = 16) throw() { 126 return ::operator new(bytes, *C, alignment); 127 } 128 129 void* operator new(size_t bytes, void* mem) throw() { 130 return mem; 131 } 132 133 void operator delete(void*, ASTContext&, unsigned) throw() { } 134 void operator delete(void*, ASTContext*, unsigned) throw() { } 135 void operator delete(void*, std::size_t) throw() { } 136 void operator delete(void*, void*) throw() { } 137 138public: 139 /// \brief A placeholder type used to construct an empty shell of a 140 /// type, that will be filled in later (e.g., by some 141 /// de-serialization). 142 struct EmptyShell { }; 143 144protected: 145 /// DestroyChildren - Invoked by destructors of subclasses of Stmt to 146 /// recursively release child AST nodes. 147 void DestroyChildren(ASTContext& Ctx); 148 149 /// \brief Construct an empty statement. 150 explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC) { 151 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 152 } 153 154public: 155 Stmt(StmtClass SC) : sClass(SC) { 156 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 157 } 158 virtual ~Stmt() {} 159 160 virtual void Destroy(ASTContext &Ctx); 161 162 StmtClass getStmtClass() const { return sClass; } 163 const char *getStmtClassName() const; 164 165 /// SourceLocation tokens are not useful in isolation - they are low level 166 /// value objects created/interpreted by SourceManager. We assume AST 167 /// clients will have a pointer to the respective SourceManager. 168 virtual SourceRange getSourceRange() const = 0; 169 SourceLocation getLocStart() const { return getSourceRange().getBegin(); } 170 SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } 171 172 // global temp stats (until we have a per-module visitor) 173 static void addStmtClass(const StmtClass s); 174 static bool CollectingStats(bool enable=false); 175 static void PrintStats(); 176 177 /// dump - This does a local dump of the specified AST fragment. It dumps the 178 /// specified node and a few nodes underneath it, but not the whole subtree. 179 /// This is useful in a debugger. 180 void dump() const; 181 void dump(SourceManager &SM) const; 182 183 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 184 void dumpAll() const; 185 void dumpAll(SourceManager &SM) const; 186 187 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 188 /// back to its original source language syntax. 189 void dumpPretty() const; 190 void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL, unsigned = 0, 191 bool NoIndent=false) const; 192 193 /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 194 /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 195 void viewAST() const; 196 197 // Implement isa<T> support. 198 static bool classof(const Stmt *) { return true; } 199 200 /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) 201 /// contain implicit control-flow in the order their subexpressions 202 /// are evaluated. This predicate returns true if this statement has 203 /// such implicit control-flow. Such statements are also specially handled 204 /// within CFGs. 205 bool hasImplicitControlFlow() const; 206 207 /// Child Iterators: All subclasses must implement child_begin and child_end 208 /// to permit easy iteration over the substatements/subexpessions of an 209 /// AST node. This permits easy iteration over all nodes in the AST. 210 typedef StmtIterator child_iterator; 211 typedef ConstStmtIterator const_child_iterator; 212 213 virtual child_iterator child_begin() = 0; 214 virtual child_iterator child_end() = 0; 215 216 const_child_iterator child_begin() const { 217 return const_child_iterator(const_cast<Stmt*>(this)->child_begin()); 218 } 219 220 const_child_iterator child_end() const { 221 return const_child_iterator(const_cast<Stmt*>(this)->child_end()); 222 } 223}; 224 225/// DeclStmt - Adaptor class for mixing declarations with statements and 226/// expressions. For example, CompoundStmt mixes statements, expressions 227/// and declarations (variables, types). Another example is ForStmt, where 228/// the first statement can be an expression or a declaration. 229/// 230class DeclStmt : public Stmt { 231 DeclGroupRef DG; 232 SourceLocation StartLoc, EndLoc; 233public: 234 DeclStmt(DeclGroupRef dg, SourceLocation startLoc, 235 SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg), 236 StartLoc(startLoc), EndLoc(endLoc) {} 237 238 /// \brief Build an empty declaration statement. 239 explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { } 240 241 virtual void Destroy(ASTContext& Ctx); 242 243 /// isSingleDecl - This method returns true if this DeclStmt refers 244 /// to a single Decl. 245 bool isSingleDecl() const { 246 return DG.isSingleDecl(); 247 } 248 249 const Decl *getSingleDecl() const { return DG.getSingleDecl(); } 250 Decl *getSingleDecl() { return DG.getSingleDecl(); } 251 252 const DeclGroupRef getDeclGroup() const { return DG; } 253 DeclGroupRef getDeclGroup() { return DG; } 254 void setDeclGroup(DeclGroupRef DGR) { DG = DGR; } 255 256 SourceLocation getStartLoc() const { return StartLoc; } 257 void setStartLoc(SourceLocation L) { StartLoc = L; } 258 SourceLocation getEndLoc() const { return EndLoc; } 259 void setEndLoc(SourceLocation L) { EndLoc = L; } 260 261 SourceRange getSourceRange() const { 262 return SourceRange(StartLoc, EndLoc); 263 } 264 265 static bool classof(const Stmt *T) { 266 return T->getStmtClass() == DeclStmtClass; 267 } 268 static bool classof(const DeclStmt *) { return true; } 269 270 // Iterators over subexpressions. 271 virtual child_iterator child_begin(); 272 virtual child_iterator child_end(); 273 274 typedef DeclGroupRef::iterator decl_iterator; 275 typedef DeclGroupRef::const_iterator const_decl_iterator; 276 277 decl_iterator decl_begin() { return DG.begin(); } 278 decl_iterator decl_end() { return DG.end(); } 279 const_decl_iterator decl_begin() const { return DG.begin(); } 280 const_decl_iterator decl_end() const { return DG.end(); } 281}; 282 283/// NullStmt - This is the null statement ";": C99 6.8.3p3. 284/// 285class NullStmt : public Stmt { 286 SourceLocation SemiLoc; 287public: 288 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 289 290 /// \brief Build an empty null statement. 291 explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { } 292 293 NullStmt* Clone(ASTContext &C) const; 294 295 SourceLocation getSemiLoc() const { return SemiLoc; } 296 void setSemiLoc(SourceLocation L) { SemiLoc = L; } 297 298 virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 299 300 static bool classof(const Stmt *T) { 301 return T->getStmtClass() == NullStmtClass; 302 } 303 static bool classof(const NullStmt *) { return true; } 304 305 // Iterators 306 virtual child_iterator child_begin(); 307 virtual child_iterator child_end(); 308}; 309 310/// CompoundStmt - This represents a group of statements like { stmt stmt }. 311/// 312class CompoundStmt : public Stmt { 313 Stmt** Body; 314 unsigned NumStmts; 315 SourceLocation LBracLoc, RBracLoc; 316public: 317 CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts, 318 SourceLocation LB, SourceLocation RB) 319 : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) { 320 if (NumStmts == 0) { 321 Body = 0; 322 return; 323 } 324 325 Body = new (C) Stmt*[NumStmts]; 326 memcpy(Body, StmtStart, numStmts * sizeof(*Body)); 327 } 328 329 // \brief Build an empty compound statement. 330 explicit CompoundStmt(EmptyShell Empty) 331 : Stmt(CompoundStmtClass, Empty), Body(0), NumStmts(0) { } 332 333 void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts); 334 335 bool body_empty() const { return NumStmts == 0; } 336 unsigned size() const { return NumStmts; } 337 338 typedef Stmt** body_iterator; 339 body_iterator body_begin() { return Body; } 340 body_iterator body_end() { return Body + NumStmts; } 341 Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; } 342 343 typedef Stmt* const * const_body_iterator; 344 const_body_iterator body_begin() const { return Body; } 345 const_body_iterator body_end() const { return Body + NumStmts; } 346 const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; } 347 348 typedef std::reverse_iterator<body_iterator> reverse_body_iterator; 349 reverse_body_iterator body_rbegin() { 350 return reverse_body_iterator(body_end()); 351 } 352 reverse_body_iterator body_rend() { 353 return reverse_body_iterator(body_begin()); 354 } 355 356 typedef std::reverse_iterator<const_body_iterator> 357 const_reverse_body_iterator; 358 359 const_reverse_body_iterator body_rbegin() const { 360 return const_reverse_body_iterator(body_end()); 361 } 362 363 const_reverse_body_iterator body_rend() const { 364 return const_reverse_body_iterator(body_begin()); 365 } 366 367 virtual SourceRange getSourceRange() const { 368 return SourceRange(LBracLoc, RBracLoc); 369 } 370 371 SourceLocation getLBracLoc() const { return LBracLoc; } 372 void setLBracLoc(SourceLocation L) { LBracLoc = L; } 373 SourceLocation getRBracLoc() const { return RBracLoc; } 374 void setRBracLoc(SourceLocation L) { RBracLoc = L; } 375 376 static bool classof(const Stmt *T) { 377 return T->getStmtClass() == CompoundStmtClass; 378 } 379 static bool classof(const CompoundStmt *) { return true; } 380 381 // Iterators 382 virtual child_iterator child_begin(); 383 virtual child_iterator child_end(); 384}; 385 386// SwitchCase is the base class for CaseStmt and DefaultStmt, 387class SwitchCase : public Stmt { 388protected: 389 // A pointer to the following CaseStmt or DefaultStmt class, 390 // used by SwitchStmt. 391 SwitchCase *NextSwitchCase; 392 393 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 394 395public: 396 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 397 398 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 399 400 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 401 402 Stmt *getSubStmt() { return v_getSubStmt(); } 403 404 virtual SourceRange getSourceRange() const { return SourceRange(); } 405 406 static bool classof(const Stmt *T) { 407 return T->getStmtClass() == CaseStmtClass || 408 T->getStmtClass() == DefaultStmtClass; 409 } 410 static bool classof(const SwitchCase *) { return true; } 411protected: 412 virtual Stmt* v_getSubStmt() = 0; 413}; 414 415class CaseStmt : public SwitchCase { 416 enum { SUBSTMT, LHS, RHS, END_EXPR }; 417 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 418 // GNU "case 1 ... 4" extension 419 SourceLocation CaseLoc; 420 SourceLocation EllipsisLoc; 421 SourceLocation ColonLoc; 422 423 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 424public: 425 CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc, 426 SourceLocation ellipsisLoc, SourceLocation colonLoc) 427 : SwitchCase(CaseStmtClass) { 428 SubExprs[SUBSTMT] = 0; 429 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 430 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 431 CaseLoc = caseLoc; 432 EllipsisLoc = ellipsisLoc; 433 ColonLoc = colonLoc; 434 } 435 436 /// \brief Build an empty switch case statement. 437 explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { } 438 439 SourceLocation getCaseLoc() const { return CaseLoc; } 440 void setCaseLoc(SourceLocation L) { CaseLoc = L; } 441 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 442 void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; } 443 SourceLocation getColonLoc() const { return ColonLoc; } 444 void setColonLoc(SourceLocation L) { ColonLoc = L; } 445 446 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 447 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 448 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 449 450 const Expr *getLHS() const { 451 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 452 } 453 const Expr *getRHS() const { 454 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 455 } 456 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 457 458 void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; } 459 void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } 460 void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } 461 462 463 virtual SourceRange getSourceRange() const { 464 // Handle deeply nested case statements with iteration instead of recursion. 465 const CaseStmt *CS = this; 466 while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt())) 467 CS = CS2; 468 469 return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd()); 470 } 471 static bool classof(const Stmt *T) { 472 return T->getStmtClass() == CaseStmtClass; 473 } 474 static bool classof(const CaseStmt *) { return true; } 475 476 // Iterators 477 virtual child_iterator child_begin(); 478 virtual child_iterator child_end(); 479}; 480 481class DefaultStmt : public SwitchCase { 482 Stmt* SubStmt; 483 SourceLocation DefaultLoc; 484 SourceLocation ColonLoc; 485 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 486public: 487 DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) : 488 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL), 489 ColonLoc(CL) {} 490 491 /// \brief Build an empty default statement. 492 explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { } 493 494 Stmt *getSubStmt() { return SubStmt; } 495 const Stmt *getSubStmt() const { return SubStmt; } 496 void setSubStmt(Stmt *S) { SubStmt = S; } 497 498 SourceLocation getDefaultLoc() const { return DefaultLoc; } 499 void setDefaultLoc(SourceLocation L) { DefaultLoc = L; } 500 SourceLocation getColonLoc() const { return ColonLoc; } 501 void setColonLoc(SourceLocation L) { ColonLoc = L; } 502 503 virtual SourceRange getSourceRange() const { 504 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 505 } 506 static bool classof(const Stmt *T) { 507 return T->getStmtClass() == DefaultStmtClass; 508 } 509 static bool classof(const DefaultStmt *) { return true; } 510 511 // Iterators 512 virtual child_iterator child_begin(); 513 virtual child_iterator child_end(); 514}; 515 516class LabelStmt : public Stmt { 517 IdentifierInfo *Label; 518 Stmt *SubStmt; 519 SourceLocation IdentLoc; 520public: 521 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 522 : Stmt(LabelStmtClass), Label(label), 523 SubStmt(substmt), IdentLoc(IL) {} 524 525 // \brief Build an empty label statement. 526 explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { } 527 528 SourceLocation getIdentLoc() const { return IdentLoc; } 529 IdentifierInfo *getID() const { return Label; } 530 void setID(IdentifierInfo *II) { Label = II; } 531 const char *getName() const; 532 Stmt *getSubStmt() { return SubStmt; } 533 const Stmt *getSubStmt() const { return SubStmt; } 534 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 535 void setSubStmt(Stmt *SS) { SubStmt = SS; } 536 537 virtual SourceRange getSourceRange() const { 538 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 539 } 540 static bool classof(const Stmt *T) { 541 return T->getStmtClass() == LabelStmtClass; 542 } 543 static bool classof(const LabelStmt *) { return true; } 544 545 // Iterators 546 virtual child_iterator child_begin(); 547 virtual child_iterator child_end(); 548}; 549 550 551/// IfStmt - This represents an if/then/else. 552/// 553class IfStmt : public Stmt { 554 enum { COND, THEN, ELSE, END_EXPR }; 555 Stmt* SubExprs[END_EXPR]; 556 SourceLocation IfLoc; 557 SourceLocation ElseLoc; 558public: 559 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, 560 SourceLocation EL = SourceLocation(), Stmt *elsev = 0) 561 : Stmt(IfStmtClass) { 562 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 563 SubExprs[THEN] = then; 564 SubExprs[ELSE] = elsev; 565 IfLoc = IL; 566 ElseLoc = EL; 567 } 568 569 /// \brief Build an empty if/then/else statement 570 explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { } 571 572 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 573 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } 574 const Stmt *getThen() const { return SubExprs[THEN]; } 575 void setThen(Stmt *S) { SubExprs[THEN] = S; } 576 const Stmt *getElse() const { return SubExprs[ELSE]; } 577 void setElse(Stmt *S) { SubExprs[ELSE] = S; } 578 579 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 580 Stmt *getThen() { return SubExprs[THEN]; } 581 Stmt *getElse() { return SubExprs[ELSE]; } 582 583 SourceLocation getIfLoc() const { return IfLoc; } 584 void setIfLoc(SourceLocation L) { IfLoc = L; } 585 SourceLocation getElseLoc() const { return ElseLoc; } 586 void setElseLoc(SourceLocation L) { ElseLoc = L; } 587 588 virtual SourceRange getSourceRange() const { 589 if (SubExprs[ELSE]) 590 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 591 else 592 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 593 } 594 595 static bool classof(const Stmt *T) { 596 return T->getStmtClass() == IfStmtClass; 597 } 598 static bool classof(const IfStmt *) { return true; } 599 600 // Iterators 601 virtual child_iterator child_begin(); 602 virtual child_iterator child_end(); 603}; 604 605/// SwitchStmt - This represents a 'switch' stmt. 606/// 607class SwitchStmt : public Stmt { 608 enum { COND, BODY, END_EXPR }; 609 Stmt* SubExprs[END_EXPR]; 610 // This points to a linked list of case and default statements. 611 SwitchCase *FirstCase; 612 SourceLocation SwitchLoc; 613public: 614 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 615 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 616 SubExprs[BODY] = NULL; 617 } 618 619 /// \brief Build a empty switch statement. 620 explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } 621 622 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 623 const Stmt *getBody() const { return SubExprs[BODY]; } 624 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 625 626 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 627 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } 628 Stmt *getBody() { return SubExprs[BODY]; } 629 void setBody(Stmt *S) { SubExprs[BODY] = S; } 630 SwitchCase *getSwitchCaseList() { return FirstCase; } 631 void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } 632 633 SourceLocation getSwitchLoc() const { return SwitchLoc; } 634 void setSwitchLoc(SourceLocation L) { SwitchLoc = L; } 635 636 void setBody(Stmt *S, SourceLocation SL) { 637 SubExprs[BODY] = S; 638 SwitchLoc = SL; 639 } 640 void addSwitchCase(SwitchCase *SC) { 641 assert(!SC->getNextSwitchCase() && "case/default already added to a switch"); 642 SC->setNextSwitchCase(FirstCase); 643 FirstCase = SC; 644 } 645 virtual SourceRange getSourceRange() const { 646 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 647 } 648 static bool classof(const Stmt *T) { 649 return T->getStmtClass() == SwitchStmtClass; 650 } 651 static bool classof(const SwitchStmt *) { return true; } 652 653 // Iterators 654 virtual child_iterator child_begin(); 655 virtual child_iterator child_end(); 656}; 657 658 659/// WhileStmt - This represents a 'while' stmt. 660/// 661class WhileStmt : public Stmt { 662 enum { COND, BODY, END_EXPR }; 663 Stmt* SubExprs[END_EXPR]; 664 SourceLocation WhileLoc; 665public: 666 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 667 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 668 SubExprs[BODY] = body; 669 WhileLoc = WL; 670 } 671 672 /// \brief Build an empty while statement. 673 explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { } 674 675 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 676 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 677 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 678 Stmt *getBody() { return SubExprs[BODY]; } 679 const Stmt *getBody() const { return SubExprs[BODY]; } 680 void setBody(Stmt *S) { SubExprs[BODY] = S; } 681 682 SourceLocation getWhileLoc() const { return WhileLoc; } 683 void setWhileLoc(SourceLocation L) { WhileLoc = L; } 684 685 virtual SourceRange getSourceRange() const { 686 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 687 } 688 static bool classof(const Stmt *T) { 689 return T->getStmtClass() == WhileStmtClass; 690 } 691 static bool classof(const WhileStmt *) { return true; } 692 693 // Iterators 694 virtual child_iterator child_begin(); 695 virtual child_iterator child_end(); 696}; 697 698/// DoStmt - This represents a 'do/while' stmt. 699/// 700class DoStmt : public Stmt { 701 enum { COND, BODY, END_EXPR }; 702 Stmt* SubExprs[END_EXPR]; 703 SourceLocation DoLoc; 704 SourceLocation WhileLoc; 705 706public: 707 DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL) 708 : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL) { 709 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 710 SubExprs[BODY] = body; 711 DoLoc = DL; 712 WhileLoc = WL; 713 } 714 715 /// \brief Build an empty do-while statement. 716 explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { } 717 718 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 719 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 720 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 721 Stmt *getBody() { return SubExprs[BODY]; } 722 const Stmt *getBody() const { return SubExprs[BODY]; } 723 void setBody(Stmt *S) { SubExprs[BODY] = S; } 724 725 SourceLocation getDoLoc() const { return DoLoc; } 726 void setDoLoc(SourceLocation L) { DoLoc = L; } 727 SourceLocation getWhileLoc() const { return WhileLoc; } 728 void setWhileLoc(SourceLocation L) { WhileLoc = L; } 729 730 virtual SourceRange getSourceRange() const { 731 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 732 } 733 static bool classof(const Stmt *T) { 734 return T->getStmtClass() == DoStmtClass; 735 } 736 static bool classof(const DoStmt *) { return true; } 737 738 // Iterators 739 virtual child_iterator child_begin(); 740 virtual child_iterator child_end(); 741}; 742 743 744/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 745/// the init/cond/inc parts of the ForStmt will be null if they were not 746/// specified in the source. 747/// 748class ForStmt : public Stmt { 749 enum { INIT, COND, INC, BODY, END_EXPR }; 750 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 751 SourceLocation ForLoc; 752 SourceLocation LParenLoc, RParenLoc; 753 754public: 755 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL, 756 SourceLocation LP, SourceLocation RP) 757 : Stmt(ForStmtClass) { 758 SubExprs[INIT] = Init; 759 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 760 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 761 SubExprs[BODY] = Body; 762 ForLoc = FL; 763 LParenLoc = LP; 764 RParenLoc = RP; 765 } 766 767 /// \brief Build an empty for statement. 768 explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { } 769 770 Stmt *getInit() { return SubExprs[INIT]; } 771 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 772 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 773 Stmt *getBody() { return SubExprs[BODY]; } 774 775 const Stmt *getInit() const { return SubExprs[INIT]; } 776 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 777 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 778 const Stmt *getBody() const { return SubExprs[BODY]; } 779 780 void setInit(Stmt *S) { SubExprs[INIT] = S; } 781 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } 782 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } 783 void setBody(Stmt *S) { SubExprs[BODY] = S; } 784 785 SourceLocation getForLoc() const { return ForLoc; } 786 void setForLoc(SourceLocation L) { ForLoc = L; } 787 SourceLocation getLParenLoc() const { return LParenLoc; } 788 void setLParenLoc(SourceLocation L) { LParenLoc = L; } 789 SourceLocation getRParenLoc() const { return RParenLoc; } 790 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 791 792 virtual SourceRange getSourceRange() const { 793 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 794 } 795 static bool classof(const Stmt *T) { 796 return T->getStmtClass() == ForStmtClass; 797 } 798 static bool classof(const ForStmt *) { return true; } 799 800 // Iterators 801 virtual child_iterator child_begin(); 802 virtual child_iterator child_end(); 803}; 804 805/// GotoStmt - This represents a direct goto. 806/// 807class GotoStmt : public Stmt { 808 LabelStmt *Label; 809 SourceLocation GotoLoc; 810 SourceLocation LabelLoc; 811public: 812 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 813 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 814 815 /// \brief Build an empty goto statement. 816 explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { } 817 818 LabelStmt *getLabel() const { return Label; } 819 void setLabel(LabelStmt *S) { Label = S; } 820 821 SourceLocation getGotoLoc() const { return GotoLoc; } 822 void setGotoLoc(SourceLocation L) { GotoLoc = L; } 823 SourceLocation getLabelLoc() const { return LabelLoc; } 824 void setLabelLoc(SourceLocation L) { LabelLoc = L; } 825 826 virtual SourceRange getSourceRange() const { 827 return SourceRange(GotoLoc, LabelLoc); 828 } 829 static bool classof(const Stmt *T) { 830 return T->getStmtClass() == GotoStmtClass; 831 } 832 static bool classof(const GotoStmt *) { return true; } 833 834 // Iterators 835 virtual child_iterator child_begin(); 836 virtual child_iterator child_end(); 837}; 838 839/// IndirectGotoStmt - This represents an indirect goto. 840/// 841class IndirectGotoStmt : public Stmt { 842 SourceLocation GotoLoc; 843 SourceLocation StarLoc; 844 Stmt *Target; 845public: 846 IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, 847 Expr *target) 848 : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc), 849 Target((Stmt*)target) {} 850 851 /// \brief Build an empty indirect goto statement. 852 explicit IndirectGotoStmt(EmptyShell Empty) 853 : Stmt(IndirectGotoStmtClass, Empty) { } 854 855 void setGotoLoc(SourceLocation L) { GotoLoc = L; } 856 SourceLocation getGotoLoc() const { return GotoLoc; } 857 void setStarLoc(SourceLocation L) { StarLoc = L; } 858 SourceLocation getStarLoc() const { return StarLoc; } 859 860 Expr *getTarget(); 861 const Expr *getTarget() const; 862 void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); } 863 864 virtual SourceRange getSourceRange() const { 865 return SourceRange(GotoLoc, Target->getLocEnd()); 866 } 867 868 static bool classof(const Stmt *T) { 869 return T->getStmtClass() == IndirectGotoStmtClass; 870 } 871 static bool classof(const IndirectGotoStmt *) { return true; } 872 873 // Iterators 874 virtual child_iterator child_begin(); 875 virtual child_iterator child_end(); 876}; 877 878 879/// ContinueStmt - This represents a continue. 880/// 881class ContinueStmt : public Stmt { 882 SourceLocation ContinueLoc; 883public: 884 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 885 886 /// \brief Build an empty continue statement. 887 explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { } 888 889 SourceLocation getContinueLoc() const { return ContinueLoc; } 890 void setContinueLoc(SourceLocation L) { ContinueLoc = L; } 891 892 virtual SourceRange getSourceRange() const { 893 return SourceRange(ContinueLoc); 894 } 895 896 ContinueStmt* Clone(ASTContext &C) const; 897 898 static bool classof(const Stmt *T) { 899 return T->getStmtClass() == ContinueStmtClass; 900 } 901 static bool classof(const ContinueStmt *) { return true; } 902 903 // Iterators 904 virtual child_iterator child_begin(); 905 virtual child_iterator child_end(); 906}; 907 908/// BreakStmt - This represents a break. 909/// 910class BreakStmt : public Stmt { 911 SourceLocation BreakLoc; 912public: 913 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 914 915 /// \brief Build an empty break statement. 916 explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { } 917 918 SourceLocation getBreakLoc() const { return BreakLoc; } 919 void setBreakLoc(SourceLocation L) { BreakLoc = L; } 920 921 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 922 923 BreakStmt* Clone(ASTContext &C) const; 924 925 static bool classof(const Stmt *T) { 926 return T->getStmtClass() == BreakStmtClass; 927 } 928 static bool classof(const BreakStmt *) { return true; } 929 930 // Iterators 931 virtual child_iterator child_begin(); 932 virtual child_iterator child_end(); 933}; 934 935 936/// ReturnStmt - This represents a return, optionally of an expression: 937/// return; 938/// return 4; 939/// 940/// Note that GCC allows return with no argument in a function declared to 941/// return a value, and it allows returning a value in functions declared to 942/// return void. We explicitly model this in the AST, which means you can't 943/// depend on the return type of the function and the presence of an argument. 944/// 945class ReturnStmt : public Stmt { 946 Stmt *RetExpr; 947 SourceLocation RetLoc; 948public: 949 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 950 RetExpr((Stmt*) E), RetLoc(RL) {} 951 952 /// \brief Build an empty return expression. 953 explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { } 954 955 const Expr *getRetValue() const; 956 Expr *getRetValue(); 957 void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); } 958 959 SourceLocation getReturnLoc() const { return RetLoc; } 960 void setReturnLoc(SourceLocation L) { RetLoc = L; } 961 962 virtual SourceRange getSourceRange() const; 963 964 static bool classof(const Stmt *T) { 965 return T->getStmtClass() == ReturnStmtClass; 966 } 967 static bool classof(const ReturnStmt *) { return true; } 968 969 // Iterators 970 virtual child_iterator child_begin(); 971 virtual child_iterator child_end(); 972}; 973 974/// AsmStmt - This represents a GNU inline-assembly statement extension. 975/// 976class AsmStmt : public Stmt { 977 SourceLocation AsmLoc, RParenLoc; 978 StringLiteral *AsmStr; 979 980 bool IsSimple; 981 bool IsVolatile; 982 983 unsigned NumOutputs; 984 unsigned NumInputs; 985 986 llvm::SmallVector<std::string, 4> Names; 987 llvm::SmallVector<StringLiteral*, 4> Constraints; 988 llvm::SmallVector<Stmt*, 4> Exprs; 989 990 llvm::SmallVector<StringLiteral*, 4> Clobbers; 991public: 992 AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 993 unsigned numoutputs, unsigned numinputs, 994 std::string *names, StringLiteral **constraints, 995 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 996 StringLiteral **clobbers, SourceLocation rparenloc); 997 998 /// \brief Build an empty inline-assembly statement. 999 explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty) { } 1000 1001 SourceLocation getAsmLoc() const { return AsmLoc; } 1002 void setAsmLoc(SourceLocation L) { AsmLoc = L; } 1003 SourceLocation getRParenLoc() const { return RParenLoc; } 1004 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 1005 1006 bool isVolatile() const { return IsVolatile; } 1007 void setVolatile(bool V) { IsVolatile = V; } 1008 bool isSimple() const { return IsSimple; } 1009 void setSimple(bool V) { IsSimple = false; } 1010 1011 //===--- Asm String Analysis ---===// 1012 1013 const StringLiteral *getAsmString() const { return AsmStr; } 1014 StringLiteral *getAsmString() { return AsmStr; } 1015 void setAsmString(StringLiteral *E) { AsmStr = E; } 1016 1017 /// AsmStringPiece - this is part of a decomposed asm string specification 1018 /// (for use with the AnalyzeAsmString function below). An asm string is 1019 /// considered to be a concatenation of these parts. 1020 class AsmStringPiece { 1021 public: 1022 enum Kind { 1023 String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%". 1024 Operand // Operand reference, with optional modifier %c4. 1025 }; 1026 private: 1027 Kind MyKind; 1028 std::string Str; 1029 unsigned OperandNo; 1030 public: 1031 AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {} 1032 AsmStringPiece(unsigned OpNo, char Modifier) 1033 : MyKind(Operand), Str(), OperandNo(OpNo) { 1034 Str += Modifier; 1035 } 1036 1037 bool isString() const { return MyKind == String; } 1038 bool isOperand() const { return MyKind == Operand; } 1039 1040 const std::string &getString() const { 1041 assert(isString()); 1042 return Str; 1043 } 1044 1045 unsigned getOperandNo() const { 1046 assert(isOperand()); 1047 return OperandNo; 1048 } 1049 1050 /// getModifier - Get the modifier for this operand, if present. This 1051 /// returns '\0' if there was no modifier. 1052 char getModifier() const { 1053 assert(isOperand()); 1054 return Str[0]; 1055 } 1056 }; 1057 1058 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing 1059 /// it into pieces. If the asm string is erroneous, emit errors and return 1060 /// true, otherwise return false. This handles canonicalization and 1061 /// translation of strings from GCC syntax to LLVM IR syntax, and handles 1062 //// flattening of named references like %[foo] to Operand AsmStringPiece's. 1063 unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces, 1064 ASTContext &C, unsigned &DiagOffs) const; 1065 1066 1067 //===--- Output operands ---===// 1068 1069 unsigned getNumOutputs() const { return NumOutputs; } 1070 1071 const std::string &getOutputName(unsigned i) const { 1072 return Names[i]; 1073 } 1074 1075 /// getOutputConstraint - Return the constraint string for the specified 1076 /// output operand. All output constraints are known to be non-empty (either 1077 /// '=' or '+'). 1078 std::string getOutputConstraint(unsigned i) const; 1079 1080 const StringLiteral *getOutputConstraintLiteral(unsigned i) const { 1081 return Constraints[i]; 1082 } 1083 StringLiteral *getOutputConstraintLiteral(unsigned i) { 1084 return Constraints[i]; 1085 } 1086 1087 1088 Expr *getOutputExpr(unsigned i); 1089 1090 const Expr *getOutputExpr(unsigned i) const { 1091 return const_cast<AsmStmt*>(this)->getOutputExpr(i); 1092 } 1093 1094 /// isOutputPlusConstraint - Return true if the specified output constraint 1095 /// is a "+" constraint (which is both an input and an output) or false if it 1096 /// is an "=" constraint (just an output). 1097 bool isOutputPlusConstraint(unsigned i) const { 1098 return getOutputConstraint(i)[0] == '+'; 1099 } 1100 1101 /// getNumPlusOperands - Return the number of output operands that have a "+" 1102 /// constraint. 1103 unsigned getNumPlusOperands() const; 1104 1105 //===--- Input operands ---===// 1106 1107 unsigned getNumInputs() const { return NumInputs; } 1108 1109 const std::string &getInputName(unsigned i) const { 1110 return Names[i + NumOutputs]; 1111 } 1112 1113 /// getInputConstraint - Return the specified input constraint. Unlike output 1114 /// constraints, these can be empty. 1115 std::string getInputConstraint(unsigned i) const; 1116 1117 const StringLiteral *getInputConstraintLiteral(unsigned i) const { 1118 return Constraints[i + NumOutputs]; 1119 } 1120 StringLiteral *getInputConstraintLiteral(unsigned i) { 1121 return Constraints[i + NumOutputs]; 1122 } 1123 1124 1125 Expr *getInputExpr(unsigned i); 1126 1127 const Expr *getInputExpr(unsigned i) const { 1128 return const_cast<AsmStmt*>(this)->getInputExpr(i); 1129 } 1130 1131 void setOutputsAndInputs(unsigned NumOutputs, 1132 unsigned NumInputs, 1133 const std::string *Names, 1134 StringLiteral **Constraints, 1135 Stmt **Exprs); 1136 1137 //===--- Other ---===// 1138 1139 /// getNamedOperand - Given a symbolic operand reference like %[foo], 1140 /// translate this into a numeric value needed to reference the same operand. 1141 /// This returns -1 if the operand name is invalid. 1142 int getNamedOperand(const std::string &SymbolicName) const; 1143 1144 1145 1146 unsigned getNumClobbers() const { return Clobbers.size(); } 1147 StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } 1148 const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } 1149 void setClobbers(StringLiteral **Clobbers, unsigned NumClobbers); 1150 1151 virtual SourceRange getSourceRange() const { 1152 return SourceRange(AsmLoc, RParenLoc); 1153 } 1154 1155 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 1156 static bool classof(const AsmStmt *) { return true; } 1157 1158 // Input expr iterators. 1159 1160 typedef ExprIterator inputs_iterator; 1161 typedef ConstExprIterator const_inputs_iterator; 1162 1163 inputs_iterator begin_inputs() { 1164 return &Exprs[0] + NumOutputs; 1165 } 1166 1167 inputs_iterator end_inputs() { 1168 return &Exprs[0] + NumOutputs + NumInputs; 1169 } 1170 1171 const_inputs_iterator begin_inputs() const { 1172 return &Exprs[0] + NumOutputs; 1173 } 1174 1175 const_inputs_iterator end_inputs() const { 1176 return &Exprs[0] + NumOutputs + NumInputs;} 1177 1178 // Output expr iterators. 1179 1180 typedef ExprIterator outputs_iterator; 1181 typedef ConstExprIterator const_outputs_iterator; 1182 1183 outputs_iterator begin_outputs() { return &Exprs[0]; } 1184 outputs_iterator end_outputs() { return &Exprs[0] + NumOutputs; } 1185 1186 const_outputs_iterator begin_outputs() const { return &Exprs[0]; } 1187 const_outputs_iterator end_outputs() const { return &Exprs[0] + NumOutputs; } 1188 1189 // Input name iterator. 1190 1191 const std::string *begin_output_names() const { 1192 return &Names[0]; 1193 } 1194 1195 const std::string *end_output_names() const { 1196 return &Names[0] + NumOutputs; 1197 } 1198 1199 // Child iterators 1200 1201 virtual child_iterator child_begin(); 1202 virtual child_iterator child_end(); 1203}; 1204 1205} // end namespace clang 1206 1207#endif 1208