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