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