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