Stmt.h revision 5e97d4b5ec7ce97e311d7aa4e8bd2b4fd9dbfa2e
1//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source 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 "clang/Basic/SourceLocation.h" 18#include "llvm/ADT/SmallVector.h" 19#include "llvm/ADT/iterator" 20#include "llvm/ADT/GraphTraits.h" 21#include <iosfwd> 22 23namespace clang { 24 class Expr; 25 class Decl; 26 class ScopedDecl; 27 class IdentifierInfo; 28 class SourceManager; 29 class SwitchStmt; 30 class PrinterHelper; 31 32/// Stmt - This represents one statement. 33/// 34class Stmt { 35public: 36 enum StmtClass { 37#define STMT(N, CLASS, PARENT) CLASS##Class = N, 38#define FIRST_STMT(N) firstStmtConstant = N, 39#define LAST_STMT(N) lastStmtConstant = N, 40#define FIRST_EXPR(N) firstExprConstant = N, 41#define LAST_EXPR(N) lastExprConstant = N 42#include "clang/AST/StmtNodes.def" 43}; 44private: 45 const StmtClass sClass; 46public: 47 Stmt(StmtClass SC) : sClass(SC) { 48 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 49 } 50 virtual ~Stmt() {} 51 52 StmtClass getStmtClass() const { return sClass; } 53 const char *getStmtClassName() const; 54 55 /// SourceLocation tokens are not useful in isolation - they are low level 56 /// value objects created/interpreted by SourceManager. We assume AST 57 /// clients will have a pointer to the respective SourceManager. 58 virtual SourceRange getSourceRange() const = 0; 59 SourceLocation getLocStart() const { return getSourceRange().Begin(); } 60 SourceLocation getLocEnd() const { return getSourceRange().End(); } 61 62 // global temp stats (until we have a per-module visitor) 63 static void addStmtClass(const StmtClass s); 64 static bool CollectingStats(bool enable=false); 65 static void PrintStats(); 66 67 /// dump - This does a local dump of the specified AST fragment. It dumps the 68 /// specified node and a few nodes underneath it, but not the whole subtree. 69 /// This is useful in a debugger. 70 void dump() const; 71 void dump(SourceManager &SM) const; 72 73 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 74 void dumpAll() const; 75 void dumpAll(SourceManager &SM) const; 76 77 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 78 /// back to its original source language syntax. 79 void dumpPretty() const; 80 void printPretty(std::ostream &OS, PrinterHelper* = NULL) const; 81 82 // Implement isa<T> support. 83 static bool classof(const Stmt *) { return true; } 84 85 /// Child Iterators: All subclasses must implement child_begin and child_end 86 /// to permit easy iteration over the substatements/subexpessions of an 87 /// AST node. This permits easy iteration over all nodes in the AST. 88 typedef Stmt** child_iterator; 89 typedef Stmt* const * const_child_iterator; 90 91 typedef std::reverse_iterator<child_iterator> 92 reverse_child_iterator; 93 typedef std::reverse_iterator<const_child_iterator> 94 const_reverse_child_iterator; 95 96 virtual child_iterator child_begin() = 0; 97 virtual child_iterator child_end() = 0; 98 99 const_child_iterator child_begin() const { 100 return (child_iterator) const_cast<Stmt*>(this)->child_begin(); 101 } 102 103 const_child_iterator child_end() const { 104 return (child_iterator) const_cast<Stmt*>(this)->child_end(); 105 } 106 107 reverse_child_iterator child_rbegin() { 108 return reverse_child_iterator(child_end()); 109 } 110 111 reverse_child_iterator child_rend() { 112 return reverse_child_iterator(child_begin()); 113 } 114 115 const_reverse_child_iterator child_rbegin() const { 116 return const_reverse_child_iterator(child_end()); 117 } 118 119 const_reverse_child_iterator child_rend() const { 120 return const_reverse_child_iterator(child_begin()); 121 } 122}; 123 124/// DeclStmt - Adaptor class for mixing declarations with statements and 125/// expressions. For example, CompoundStmt mixes statements, expressions 126/// and declarations (variables, types). Another example is ForStmt, where 127/// the first statement can be an expression or a declaration. 128/// 129class DeclStmt : public Stmt { 130 ScopedDecl *TheDecl; 131public: 132 DeclStmt(ScopedDecl *D) : Stmt(DeclStmtClass), TheDecl(D) {} 133 134 const ScopedDecl *getDecl() const { return TheDecl; } 135 ScopedDecl *getDecl() { return TheDecl; } 136 137 virtual SourceRange getSourceRange() const { return SourceRange(); } 138 139 static bool classof(const Stmt *T) { 140 return T->getStmtClass() == DeclStmtClass; 141 } 142 static bool classof(const DeclStmt *) { return true; } 143 144 // Iterators 145 virtual child_iterator child_begin(); 146 virtual child_iterator child_end(); 147}; 148 149/// NullStmt - This is the null statement ";": C99 6.8.3p3. 150/// 151class NullStmt : public Stmt { 152 SourceLocation SemiLoc; 153public: 154 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 155 156 SourceLocation getSemiLoc() const { return SemiLoc; } 157 158 virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 159 160 static bool classof(const Stmt *T) { 161 return T->getStmtClass() == NullStmtClass; 162 } 163 static bool classof(const NullStmt *) { return true; } 164 165 // Iterators 166 virtual child_iterator child_begin(); 167 virtual child_iterator child_end(); 168}; 169 170/// CompoundStmt - This represents a group of statements like { stmt stmt }. 171/// 172class CompoundStmt : public Stmt { 173 llvm::SmallVector<Stmt*, 16> Body; 174 SourceLocation LBracLoc, RBracLoc; 175public: 176 CompoundStmt(Stmt **StmtStart, unsigned NumStmts, 177 SourceLocation LB, SourceLocation RB) 178 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts), 179 LBracLoc(LB), RBracLoc(RB) {} 180 181 bool body_empty() const { return Body.empty(); } 182 183 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 184 body_iterator body_begin() { return Body.begin(); } 185 body_iterator body_end() { return Body.end(); } 186 Stmt *body_back() { return Body.back(); } 187 188 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 189 const_body_iterator body_begin() const { return Body.begin(); } 190 const_body_iterator body_end() const { return Body.end(); } 191 const Stmt *body_back() const { return Body.back(); } 192 193 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 194 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 195 reverse_body_iterator body_rend() { return Body.rend(); } 196 197 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 198 const_reverse_body_iterator; 199 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 200 const_reverse_body_iterator body_rend() const { return Body.rend(); } 201 202 void push_back(Stmt *S) { Body.push_back(S); } 203 204 virtual SourceRange getSourceRange() const { 205 return SourceRange(LBracLoc, RBracLoc); 206 } 207 static bool classof(const Stmt *T) { 208 return T->getStmtClass() == CompoundStmtClass; 209 } 210 static bool classof(const CompoundStmt *) { return true; } 211 212 // Iterators 213 virtual child_iterator child_begin(); 214 virtual child_iterator child_end(); 215}; 216 217// SwitchCase is the base class for CaseStmt and DefaultStmt, 218class SwitchCase : public Stmt { 219 // A pointer to the following CaseStmt or DefaultStmt class, 220 // used by SwitchStmt. 221 SwitchCase *NextSwitchCase; 222protected: 223 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 224 225public: 226 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 227 228 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 229 230 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 231 232 virtual Stmt* v_getSubStmt() = 0; 233 Stmt *getSubStmt() { return v_getSubStmt(); } 234 235 virtual SourceRange getSourceRange() const { return SourceRange(); } 236 237 static bool classof(const Stmt *T) { 238 return T->getStmtClass() == CaseStmtClass || 239 T->getStmtClass() == DefaultStmtClass; 240 } 241 static bool classof(const SwitchCase *) { return true; } 242}; 243 244class CaseStmt : public SwitchCase { 245 enum { SUBSTMT, LHS, RHS, END_EXPR }; 246 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 247 // GNU "case 1 ... 4" extension 248 SourceLocation CaseLoc; 249public: 250 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 251 : SwitchCase(CaseStmtClass) { 252 SubExprs[SUBSTMT] = substmt; 253 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 254 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 255 CaseLoc = caseLoc; 256 } 257 258 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 259 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 260 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 261 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 262 263 virtual SourceRange getSourceRange() const { 264 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 265 } 266 static bool classof(const Stmt *T) { 267 return T->getStmtClass() == CaseStmtClass; 268 } 269 static bool classof(const CaseStmt *) { return true; } 270 271 // Iterators 272 virtual child_iterator child_begin(); 273 virtual child_iterator child_end(); 274}; 275 276class DefaultStmt : public SwitchCase { 277 Stmt* SubStmt; 278 SourceLocation DefaultLoc; 279public: 280 DefaultStmt(SourceLocation DL, Stmt *substmt) : 281 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 282 283 Stmt *getSubStmt() { return SubStmt; } 284 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 285 286 SourceLocation getDefaultLoc() const { return DefaultLoc; } 287 288 virtual SourceRange getSourceRange() const { 289 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 290 } 291 static bool classof(const Stmt *T) { 292 return T->getStmtClass() == DefaultStmtClass; 293 } 294 static bool classof(const DefaultStmt *) { return true; } 295 296 // Iterators 297 virtual child_iterator child_begin(); 298 virtual child_iterator child_end(); 299}; 300 301class LabelStmt : public Stmt { 302 IdentifierInfo *Label; 303 Stmt *SubStmt; 304 SourceLocation IdentLoc; 305public: 306 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 307 : Stmt(LabelStmtClass), Label(label), 308 SubStmt(substmt), IdentLoc(IL) {} 309 310 SourceLocation getIdentLoc() const { return IdentLoc; } 311 IdentifierInfo *getID() const { return Label; } 312 const char *getName() const; 313 Stmt *getSubStmt() { return SubStmt; } 314 const Stmt *getSubStmt() const { return SubStmt; } 315 316 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 317 void setSubStmt(Stmt *SS) { SubStmt = SS; } 318 319 virtual SourceRange getSourceRange() const { 320 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 321 } 322 static bool classof(const Stmt *T) { 323 return T->getStmtClass() == LabelStmtClass; 324 } 325 static bool classof(const LabelStmt *) { return true; } 326 327 // Iterators 328 virtual child_iterator child_begin(); 329 virtual child_iterator child_end(); 330}; 331 332 333/// IfStmt - This represents an if/then/else. 334/// 335class IfStmt : public Stmt { 336 enum { COND, THEN, ELSE, END_EXPR }; 337 Stmt* SubExprs[END_EXPR]; 338 SourceLocation IfLoc; 339public: 340 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 341 : Stmt(IfStmtClass) { 342 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 343 SubExprs[THEN] = then; 344 SubExprs[ELSE] = elsev; 345 IfLoc = IL; 346 } 347 348 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 349 const Stmt *getThen() const { return SubExprs[THEN]; } 350 const Stmt *getElse() const { return SubExprs[ELSE]; } 351 352 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 353 Stmt *getThen() { return SubExprs[THEN]; } 354 Stmt *getElse() { return SubExprs[ELSE]; } 355 356 virtual SourceRange getSourceRange() const { 357 if (SubExprs[ELSE]) 358 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 359 else 360 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 361 } 362 363 static bool classof(const Stmt *T) { 364 return T->getStmtClass() == IfStmtClass; 365 } 366 static bool classof(const IfStmt *) { return true; } 367 368 // Iterators 369 virtual child_iterator child_begin(); 370 virtual child_iterator child_end(); 371}; 372 373/// SwitchStmt - This represents a 'switch' stmt. 374/// 375class SwitchStmt : public Stmt { 376 enum { COND, BODY, END_EXPR }; 377 Stmt* SubExprs[END_EXPR]; 378 // This points to a linked list of case and default statements. 379 SwitchCase *FirstCase; 380 SourceLocation SwitchLoc; 381public: 382 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 383 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 384 SubExprs[BODY] = NULL; 385 } 386 387 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 388 const Stmt *getBody() const { return SubExprs[BODY]; } 389 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 390 391 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 392 Stmt *getBody() { return SubExprs[BODY]; } 393 SwitchCase *getSwitchCaseList() { return FirstCase; } 394 395 void setBody(Stmt *S, SourceLocation SL) { 396 SubExprs[BODY] = S; 397 SwitchLoc = SL; 398 } 399 void addSwitchCase(SwitchCase *SC) { 400 if (FirstCase) 401 SC->setNextSwitchCase(FirstCase); 402 403 FirstCase = SC; 404 } 405 virtual SourceRange getSourceRange() const { 406 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 407 } 408 static bool classof(const Stmt *T) { 409 return T->getStmtClass() == SwitchStmtClass; 410 } 411 static bool classof(const SwitchStmt *) { return true; } 412 413 // Iterators 414 virtual child_iterator child_begin(); 415 virtual child_iterator child_end(); 416}; 417 418 419/// WhileStmt - This represents a 'while' stmt. 420/// 421class WhileStmt : public Stmt { 422 enum { COND, BODY, END_EXPR }; 423 Stmt* SubExprs[END_EXPR]; 424 SourceLocation WhileLoc; 425public: 426 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 427 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 428 SubExprs[BODY] = body; 429 WhileLoc = WL; 430 } 431 432 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 433 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 434 Stmt *getBody() { return SubExprs[BODY]; } 435 const Stmt *getBody() const { return SubExprs[BODY]; } 436 437 virtual SourceRange getSourceRange() const { 438 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 439 } 440 static bool classof(const Stmt *T) { 441 return T->getStmtClass() == WhileStmtClass; 442 } 443 static bool classof(const WhileStmt *) { return true; } 444 445 // Iterators 446 virtual child_iterator child_begin(); 447 virtual child_iterator child_end(); 448}; 449 450/// DoStmt - This represents a 'do/while' stmt. 451/// 452class DoStmt : public Stmt { 453 enum { COND, BODY, END_EXPR }; 454 Stmt* SubExprs[END_EXPR]; 455 SourceLocation DoLoc; 456public: 457 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 458 : Stmt(DoStmtClass), DoLoc(DL) { 459 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 460 SubExprs[BODY] = body; 461 DoLoc = DL; 462 } 463 464 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 465 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 466 Stmt *getBody() { return SubExprs[BODY]; } 467 const Stmt *getBody() const { return SubExprs[BODY]; } 468 469 virtual SourceRange getSourceRange() const { 470 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 471 } 472 static bool classof(const Stmt *T) { 473 return T->getStmtClass() == DoStmtClass; 474 } 475 static bool classof(const DoStmt *) { return true; } 476 477 // Iterators 478 virtual child_iterator child_begin(); 479 virtual child_iterator child_end(); 480}; 481 482 483/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 484/// the init/cond/inc parts of the ForStmt will be null if they were not 485/// specified in the source. 486/// 487class ForStmt : public Stmt { 488 enum { INIT, COND, INC, BODY, END_EXPR }; 489 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 490 SourceLocation ForLoc; 491public: 492 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 493 : Stmt(ForStmtClass) { 494 SubExprs[INIT] = Init; 495 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 496 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 497 SubExprs[BODY] = Body; 498 ForLoc = FL; 499 } 500 501 Stmt *getInit() { return SubExprs[INIT]; } 502 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 503 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 504 Stmt *getBody() { return SubExprs[BODY]; } 505 506 const Stmt *getInit() const { return SubExprs[INIT]; } 507 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 508 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 509 const Stmt *getBody() const { return SubExprs[BODY]; } 510 511 virtual SourceRange getSourceRange() const { 512 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 513 } 514 static bool classof(const Stmt *T) { 515 return T->getStmtClass() == ForStmtClass; 516 } 517 static bool classof(const ForStmt *) { return true; } 518 519 // Iterators 520 virtual child_iterator child_begin(); 521 virtual child_iterator child_end(); 522}; 523 524/// GotoStmt - This represents a direct goto. 525/// 526class GotoStmt : public Stmt { 527 LabelStmt *Label; 528 SourceLocation GotoLoc; 529 SourceLocation LabelLoc; 530public: 531 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 532 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 533 534 LabelStmt *getLabel() const { return Label; } 535 536 virtual SourceRange getSourceRange() const { 537 return SourceRange(GotoLoc, LabelLoc); 538 } 539 static bool classof(const Stmt *T) { 540 return T->getStmtClass() == GotoStmtClass; 541 } 542 static bool classof(const GotoStmt *) { return true; } 543 544 // Iterators 545 virtual child_iterator child_begin(); 546 virtual child_iterator child_end(); 547}; 548 549/// IndirectGotoStmt - This represents an indirect goto. 550/// 551class IndirectGotoStmt : public Stmt { 552 Expr *Target; 553public: 554 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 555 556 Expr *getTarget() { return Target; } 557 const Expr *getTarget() const { return Target; } 558 559 virtual SourceRange getSourceRange() const { return SourceRange(); } 560 561 static bool classof(const Stmt *T) { 562 return T->getStmtClass() == IndirectGotoStmtClass; 563 } 564 static bool classof(const IndirectGotoStmt *) { return true; } 565 566 // Iterators 567 virtual child_iterator child_begin(); 568 virtual child_iterator child_end(); 569}; 570 571 572/// ContinueStmt - This represents a continue. 573/// 574class ContinueStmt : public Stmt { 575 SourceLocation ContinueLoc; 576public: 577 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 578 579 virtual SourceRange getSourceRange() const { 580 return SourceRange(ContinueLoc); 581 } 582 static bool classof(const Stmt *T) { 583 return T->getStmtClass() == ContinueStmtClass; 584 } 585 static bool classof(const ContinueStmt *) { return true; } 586 587 // Iterators 588 virtual child_iterator child_begin(); 589 virtual child_iterator child_end(); 590}; 591 592/// BreakStmt - This represents a break. 593/// 594class BreakStmt : public Stmt { 595 SourceLocation BreakLoc; 596public: 597 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 598 599 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 600 601 static bool classof(const Stmt *T) { 602 return T->getStmtClass() == BreakStmtClass; 603 } 604 static bool classof(const BreakStmt *) { return true; } 605 606 // Iterators 607 virtual child_iterator child_begin(); 608 virtual child_iterator child_end(); 609}; 610 611 612/// ReturnStmt - This represents a return, optionally of an expression. 613/// 614class ReturnStmt : public Stmt { 615 Expr *RetExpr; 616 SourceLocation RetLoc; 617public: 618 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 619 RetExpr(E), RetLoc(RL) {} 620 621 const Expr *getRetValue() const { return RetExpr; } 622 Expr *getRetValue() { return RetExpr; } 623 624 virtual SourceRange getSourceRange() const; 625 626 static bool classof(const Stmt *T) { 627 return T->getStmtClass() == ReturnStmtClass; 628 } 629 static bool classof(const ReturnStmt *) { return true; } 630 631 // Iterators 632 virtual child_iterator child_begin(); 633 virtual child_iterator child_end(); 634}; 635 636} // end namespace clang 637 638//===----------------------------------------------------------------------===// 639// GraphTraits specialization to treat ASTs (Stmt*) as graphs 640//===----------------------------------------------------------------------===// 641 642namespace llvm { 643 644template <> struct GraphTraits<clang::Stmt*> { 645 typedef clang::Stmt NodeType; 646 typedef clang::Stmt::child_iterator ChildIteratorType; 647 648 static NodeType* getEntryNode(clang::Stmt* S) { return S; } 649 650 static inline ChildIteratorType child_begin(NodeType* N) { 651 return N->child_begin(); 652 } 653 654 static inline ChildIteratorType child_end(NodeType* N) { 655 return N->child_end(); 656 } 657}; 658 659template <> struct GraphTraits<const clang::Stmt*> { 660 typedef const clang::Stmt NodeType; 661 typedef clang::Stmt::const_child_iterator ChildIteratorType; 662 663 static NodeType* getEntryNode(const clang::Stmt* S) { return S; } 664 665 static inline ChildIteratorType child_begin(NodeType* N) { 666 return N->child_begin(); 667 } 668 669 static inline ChildIteratorType child_end(NodeType* N) { 670 return N->child_end(); 671 } 672}; 673 674} // end namespace llvm 675#endif 676