Stmt.h revision 655137a6c19110620d82d5f03cdcaec3a48c059f
1//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the Stmt interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_STMT_H 15#define LLVM_CLANG_AST_STMT_H 16 17#include "llvm/Support/Casting.h" 18#include "llvm/Support/raw_ostream.h" 19#include "clang/Basic/SourceLocation.h" 20#include "clang/AST/StmtIterator.h" 21#include "llvm/ADT/SmallVector.h" 22#include "llvm/ADT/iterator.h" 23#include "llvm/Bitcode/SerializationFwd.h" 24#include <string> 25 26using llvm::dyn_cast_or_null; 27 28namespace clang { 29 class ASTContext; 30 class Expr; 31 class Decl; 32 class ScopedDecl; 33 class IdentifierInfo; 34 class SourceManager; 35 class StringLiteral; 36 class SwitchStmt; 37 class PrinterHelper; 38 39/// Stmt - This represents one statement. 40/// 41class Stmt { 42public: 43 enum StmtClass { 44#define STMT(N, CLASS, PARENT) CLASS##Class = N, 45#define FIRST_STMT(N) firstStmtConstant = N, 46#define LAST_STMT(N) lastStmtConstant = N, 47#define FIRST_EXPR(N) firstExprConstant = N, 48#define LAST_EXPR(N) lastExprConstant = N 49#include "clang/AST/StmtNodes.def" 50}; 51private: 52 const StmtClass sClass; 53 54protected: 55 /// DestroyChildren - Invoked by destructors of subclasses of Stmt to 56 /// recursively release child AST nodes. 57 void DestroyChildren(ASTContext& Ctx); 58 59public: 60 Stmt(StmtClass SC) : sClass(SC) { 61 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 62 } 63 virtual ~Stmt() {} 64 65 virtual void Destroy(ASTContext& Ctx); 66 67 StmtClass getStmtClass() const { return sClass; } 68 const char *getStmtClassName() const; 69 70 /// SourceLocation tokens are not useful in isolation - they are low level 71 /// value objects created/interpreted by SourceManager. We assume AST 72 /// clients will have a pointer to the respective SourceManager. 73 virtual SourceRange getSourceRange() const = 0; 74 SourceLocation getLocStart() const { return getSourceRange().getBegin(); } 75 SourceLocation getLocEnd() const { return getSourceRange().getEnd(); } 76 77 // global temp stats (until we have a per-module visitor) 78 static void addStmtClass(const StmtClass s); 79 static bool CollectingStats(bool enable=false); 80 static void PrintStats(); 81 82 /// dump - This does a local dump of the specified AST fragment. It dumps the 83 /// specified node and a few nodes underneath it, but not the whole subtree. 84 /// This is useful in a debugger. 85 void dump() const; 86 void dump(SourceManager &SM) const; 87 88 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 89 void dumpAll() const; 90 void dumpAll(SourceManager &SM) const; 91 92 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 93 /// back to its original source language syntax. 94 void dumpPretty() const; 95 void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL) const; 96 97 /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only 98 /// works on systems with GraphViz (Mac OS X) or dot+gv installed. 99 void viewAST() const; 100 101 // Implement isa<T> support. 102 static bool classof(const Stmt *) { return true; } 103 104 /// hasImplicitControlFlow - Some statements (e.g. short circuited operations) 105 /// contain implicit control-flow in the order their subexpressions 106 /// are evaluated. This predicate returns true if this statement has 107 /// such implicit control-flow. Such statements are also specially handled 108 /// within CFGs. 109 bool hasImplicitControlFlow() const; 110 111 /// Child Iterators: All subclasses must implement child_begin and child_end 112 /// to permit easy iteration over the substatements/subexpessions of an 113 /// AST node. This permits easy iteration over all nodes in the AST. 114 typedef StmtIterator child_iterator; 115 typedef ConstStmtIterator const_child_iterator; 116 117 virtual child_iterator child_begin() = 0; 118 virtual child_iterator child_end() = 0; 119 120 const_child_iterator child_begin() const { 121 return const_child_iterator(const_cast<Stmt*>(this)->child_begin()); 122 } 123 124 const_child_iterator child_end() const { 125 return const_child_iterator(const_cast<Stmt*>(this)->child_end()); 126 } 127 128 void Emit(llvm::Serializer& S) const; 129 static Stmt* Create(llvm::Deserializer& D, ASTContext& C); 130 131 virtual void EmitImpl(llvm::Serializer& S) const { 132 // This method will eventually be a pure-virtual function. 133 assert (false && "Not implemented."); 134 } 135}; 136 137/// DeclStmt - Adaptor class for mixing declarations with statements and 138/// expressions. For example, CompoundStmt mixes statements, expressions 139/// and declarations (variables, types). Another example is ForStmt, where 140/// the first statement can be an expression or a declaration. 141/// 142class DeclStmt : public Stmt { 143protected: 144 ScopedDecl *TheDecl; 145 SourceLocation StartLoc, EndLoc; 146public: 147 DeclStmt(ScopedDecl *D, SourceLocation startLoc, SourceLocation endLoc) 148 : Stmt(DeclStmtClass), TheDecl(D), StartLoc(startLoc), EndLoc(endLoc) {} 149 150 virtual void Destroy(ASTContext& Ctx); 151 152 // hasSolitaryDecl - This method returns true if this DeclStmt refers 153 // to a single Decl. 154 bool hasSolitaryDecl() const; 155 156 const ScopedDecl* getSolitaryDecl() const { 157 assert (hasSolitaryDecl() && 158 "Caller assumes this DeclStmt points to one Decl*"); 159 return TheDecl; 160 } 161 162 ScopedDecl* getSolitaryDecl() { 163 assert (hasSolitaryDecl() && 164 "Caller assumes this DeclStmt points to one Decl*"); 165 return TheDecl; 166 } 167 168 SourceLocation getStartLoc() const { return StartLoc; } 169 SourceLocation getEndLoc() const { return EndLoc; } 170 virtual SourceRange getSourceRange() const { 171 return SourceRange(StartLoc, EndLoc); 172 } 173 174 static bool classof(const Stmt *T) { 175 return T->getStmtClass() == DeclStmtClass; 176 } 177 static bool classof(const DeclStmt *) { return true; } 178 179 // Iterators over subexpressions. 180 virtual child_iterator child_begin(); 181 virtual child_iterator child_end(); 182 183 // Iterators over the decls. 184 class decl_iterator { 185 ScopedDecl* D; 186 public: 187 decl_iterator(ScopedDecl *d) : D(d) {} 188 bool operator==(const decl_iterator& I) const { return D == I.D; } 189 bool operator!=(const decl_iterator& I) const { return D != I.D; } 190 ScopedDecl* operator*() const { return D; } 191 decl_iterator& operator++(); 192 }; 193 194 virtual decl_iterator decl_begin() { return TheDecl; } 195 virtual decl_iterator decl_end() { return 0; } 196 197 class const_decl_iterator { 198 decl_iterator Impl; 199 public: 200 const_decl_iterator(const ScopedDecl *d) 201 : Impl(const_cast<ScopedDecl*>(d)) {} 202 203 bool operator==(const const_decl_iterator& I) const { 204 return Impl == I.Impl; 205 } 206 bool operator!=(const const_decl_iterator& I) const { 207 return Impl != I.Impl; 208 } 209 const ScopedDecl* operator*() const { 210 return *Impl; 211 } 212 const_decl_iterator& operator++() { 213 ++Impl; return *this; 214 } 215 }; 216 217 const_decl_iterator decl_begin() const { return TheDecl; } 218 const_decl_iterator decl_end() const { return 0; } 219 220 // Serialization. 221 virtual void EmitImpl(llvm::Serializer& S) const; 222 static DeclStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 223}; 224 225/// NullStmt - This is the null statement ";": C99 6.8.3p3. 226/// 227class NullStmt : public Stmt { 228 SourceLocation SemiLoc; 229public: 230 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 231 232 SourceLocation getSemiLoc() const { return SemiLoc; } 233 234 virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 235 236 static bool classof(const Stmt *T) { 237 return T->getStmtClass() == NullStmtClass; 238 } 239 static bool classof(const NullStmt *) { return true; } 240 241 // Iterators 242 virtual child_iterator child_begin(); 243 virtual child_iterator child_end(); 244 245 virtual void EmitImpl(llvm::Serializer& S) const; 246 static NullStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 247}; 248 249/// CompoundStmt - This represents a group of statements like { stmt stmt }. 250/// 251class CompoundStmt : public Stmt { 252 llvm::SmallVector<Stmt*, 16> Body; 253 SourceLocation LBracLoc, RBracLoc; 254public: 255 CompoundStmt(Stmt **StmtStart, unsigned NumStmts, 256 SourceLocation LB, SourceLocation RB) 257 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts), 258 LBracLoc(LB), RBracLoc(RB) {} 259 260 bool body_empty() const { return Body.empty(); } 261 262 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 263 body_iterator body_begin() { return Body.begin(); } 264 body_iterator body_end() { return Body.end(); } 265 Stmt *body_back() { return Body.back(); } 266 267 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 268 const_body_iterator body_begin() const { return Body.begin(); } 269 const_body_iterator body_end() const { return Body.end(); } 270 const Stmt *body_back() const { return Body.back(); } 271 272 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 273 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 274 reverse_body_iterator body_rend() { return Body.rend(); } 275 276 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 277 const_reverse_body_iterator; 278 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 279 const_reverse_body_iterator body_rend() const { return Body.rend(); } 280 281 void push_back(Stmt *S) { Body.push_back(S); } 282 283 virtual SourceRange getSourceRange() const { 284 return SourceRange(LBracLoc, RBracLoc); 285 } 286 287 SourceLocation getLBracLoc() const { return LBracLoc; } 288 SourceLocation getRBracLoc() const { return RBracLoc; } 289 290 static bool classof(const Stmt *T) { 291 return T->getStmtClass() == CompoundStmtClass; 292 } 293 static bool classof(const CompoundStmt *) { return true; } 294 295 // Iterators 296 virtual child_iterator child_begin(); 297 virtual child_iterator child_end(); 298 299 virtual void EmitImpl(llvm::Serializer& S) const; 300 static CompoundStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 301}; 302 303// SwitchCase is the base class for CaseStmt and DefaultStmt, 304class SwitchCase : public Stmt { 305protected: 306 // A pointer to the following CaseStmt or DefaultStmt class, 307 // used by SwitchStmt. 308 SwitchCase *NextSwitchCase; 309 310 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 311 312public: 313 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 314 315 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 316 317 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 318 319 virtual Stmt* v_getSubStmt() = 0; 320 Stmt *getSubStmt() { return v_getSubStmt(); } 321 322 virtual SourceRange getSourceRange() const { return SourceRange(); } 323 324 static bool classof(const Stmt *T) { 325 return T->getStmtClass() == CaseStmtClass || 326 T->getStmtClass() == DefaultStmtClass; 327 } 328 static bool classof(const SwitchCase *) { return true; } 329}; 330 331class CaseStmt : public SwitchCase { 332 enum { SUBSTMT, LHS, RHS, END_EXPR }; 333 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 334 // GNU "case 1 ... 4" extension 335 SourceLocation CaseLoc; 336public: 337 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 338 : SwitchCase(CaseStmtClass) { 339 SubExprs[SUBSTMT] = substmt; 340 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 341 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 342 CaseLoc = caseLoc; 343 } 344 345 SourceLocation getCaseLoc() const { return CaseLoc; } 346 347 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 348 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 349 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 350 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 351 const Expr *getLHS() const { 352 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 353 } 354 const Expr *getRHS() const { 355 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 356 } 357 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 358 359 void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; } 360 void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } 361 void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } 362 363 364 virtual SourceRange getSourceRange() const { 365 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 366 } 367 static bool classof(const Stmt *T) { 368 return T->getStmtClass() == CaseStmtClass; 369 } 370 static bool classof(const CaseStmt *) { return true; } 371 372 // Iterators 373 virtual child_iterator child_begin(); 374 virtual child_iterator child_end(); 375 376 virtual void EmitImpl(llvm::Serializer& S) const; 377 static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 378}; 379 380class DefaultStmt : public SwitchCase { 381 Stmt* SubStmt; 382 SourceLocation DefaultLoc; 383public: 384 DefaultStmt(SourceLocation DL, Stmt *substmt) : 385 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 386 387 Stmt *getSubStmt() { return SubStmt; } 388 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 389 const Stmt *getSubStmt() const { return SubStmt; } 390 391 SourceLocation getDefaultLoc() const { return DefaultLoc; } 392 393 virtual SourceRange getSourceRange() const { 394 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 395 } 396 static bool classof(const Stmt *T) { 397 return T->getStmtClass() == DefaultStmtClass; 398 } 399 static bool classof(const DefaultStmt *) { return true; } 400 401 // Iterators 402 virtual child_iterator child_begin(); 403 virtual child_iterator child_end(); 404 405 virtual void EmitImpl(llvm::Serializer& S) const; 406 static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 407}; 408 409class LabelStmt : public Stmt { 410 IdentifierInfo *Label; 411 Stmt *SubStmt; 412 SourceLocation IdentLoc; 413public: 414 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 415 : Stmt(LabelStmtClass), Label(label), 416 SubStmt(substmt), IdentLoc(IL) {} 417 418 SourceLocation getIdentLoc() const { return IdentLoc; } 419 IdentifierInfo *getID() const { return Label; } 420 const char *getName() const; 421 Stmt *getSubStmt() { return SubStmt; } 422 const Stmt *getSubStmt() const { return SubStmt; } 423 424 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 425 void setSubStmt(Stmt *SS) { SubStmt = SS; } 426 427 virtual SourceRange getSourceRange() const { 428 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 429 } 430 static bool classof(const Stmt *T) { 431 return T->getStmtClass() == LabelStmtClass; 432 } 433 static bool classof(const LabelStmt *) { return true; } 434 435 // Iterators 436 virtual child_iterator child_begin(); 437 virtual child_iterator child_end(); 438 439 virtual void EmitImpl(llvm::Serializer& S) const; 440 static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 441}; 442 443 444/// IfStmt - This represents an if/then/else. 445/// 446class IfStmt : public Stmt { 447 enum { COND, THEN, ELSE, END_EXPR }; 448 Stmt* SubExprs[END_EXPR]; 449 SourceLocation IfLoc; 450public: 451 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 452 : Stmt(IfStmtClass) { 453 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 454 SubExprs[THEN] = then; 455 SubExprs[ELSE] = elsev; 456 IfLoc = IL; 457 } 458 459 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 460 const Stmt *getThen() const { return SubExprs[THEN]; } 461 const Stmt *getElse() const { return SubExprs[ELSE]; } 462 463 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 464 Stmt *getThen() { return SubExprs[THEN]; } 465 Stmt *getElse() { return SubExprs[ELSE]; } 466 467 virtual SourceRange getSourceRange() const { 468 if (SubExprs[ELSE]) 469 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 470 else 471 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 472 } 473 474 static bool classof(const Stmt *T) { 475 return T->getStmtClass() == IfStmtClass; 476 } 477 static bool classof(const IfStmt *) { return true; } 478 479 // Iterators 480 virtual child_iterator child_begin(); 481 virtual child_iterator child_end(); 482 483 virtual void EmitImpl(llvm::Serializer& S) const; 484 static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 485}; 486 487/// SwitchStmt - This represents a 'switch' stmt. 488/// 489class SwitchStmt : public Stmt { 490 enum { COND, BODY, END_EXPR }; 491 Stmt* SubExprs[END_EXPR]; 492 // This points to a linked list of case and default statements. 493 SwitchCase *FirstCase; 494 SourceLocation SwitchLoc; 495public: 496 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 497 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 498 SubExprs[BODY] = NULL; 499 } 500 501 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 502 const Stmt *getBody() const { return SubExprs[BODY]; } 503 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 504 505 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 506 Stmt *getBody() { return SubExprs[BODY]; } 507 SwitchCase *getSwitchCaseList() { return FirstCase; } 508 509 void setBody(Stmt *S, SourceLocation SL) { 510 SubExprs[BODY] = S; 511 SwitchLoc = SL; 512 } 513 void addSwitchCase(SwitchCase *SC) { 514 if (FirstCase) 515 SC->setNextSwitchCase(FirstCase); 516 517 FirstCase = SC; 518 } 519 virtual SourceRange getSourceRange() const { 520 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 521 } 522 static bool classof(const Stmt *T) { 523 return T->getStmtClass() == SwitchStmtClass; 524 } 525 static bool classof(const SwitchStmt *) { return true; } 526 527 // Iterators 528 virtual child_iterator child_begin(); 529 virtual child_iterator child_end(); 530 531 virtual void EmitImpl(llvm::Serializer& S) const; 532 static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 533}; 534 535 536/// WhileStmt - This represents a 'while' stmt. 537/// 538class WhileStmt : public Stmt { 539 enum { COND, BODY, END_EXPR }; 540 Stmt* SubExprs[END_EXPR]; 541 SourceLocation WhileLoc; 542public: 543 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 544 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 545 SubExprs[BODY] = body; 546 WhileLoc = WL; 547 } 548 549 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 550 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 551 Stmt *getBody() { return SubExprs[BODY]; } 552 const Stmt *getBody() const { return SubExprs[BODY]; } 553 554 virtual SourceRange getSourceRange() const { 555 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 556 } 557 static bool classof(const Stmt *T) { 558 return T->getStmtClass() == WhileStmtClass; 559 } 560 static bool classof(const WhileStmt *) { return true; } 561 562 // Iterators 563 virtual child_iterator child_begin(); 564 virtual child_iterator child_end(); 565 566 virtual void EmitImpl(llvm::Serializer& S) const; 567 static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 568}; 569 570/// DoStmt - This represents a 'do/while' stmt. 571/// 572class DoStmt : public Stmt { 573 enum { COND, BODY, END_EXPR }; 574 Stmt* SubExprs[END_EXPR]; 575 SourceLocation DoLoc; 576public: 577 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 578 : Stmt(DoStmtClass), DoLoc(DL) { 579 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 580 SubExprs[BODY] = body; 581 DoLoc = DL; 582 } 583 584 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 585 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 586 Stmt *getBody() { return SubExprs[BODY]; } 587 const Stmt *getBody() const { return SubExprs[BODY]; } 588 589 virtual SourceRange getSourceRange() const { 590 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 591 } 592 static bool classof(const Stmt *T) { 593 return T->getStmtClass() == DoStmtClass; 594 } 595 static bool classof(const DoStmt *) { return true; } 596 597 // Iterators 598 virtual child_iterator child_begin(); 599 virtual child_iterator child_end(); 600 601 virtual void EmitImpl(llvm::Serializer& S) const; 602 static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 603}; 604 605 606/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 607/// the init/cond/inc parts of the ForStmt will be null if they were not 608/// specified in the source. 609/// 610class ForStmt : public Stmt { 611 enum { INIT, COND, INC, BODY, END_EXPR }; 612 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 613 SourceLocation ForLoc; 614public: 615 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 616 : Stmt(ForStmtClass) { 617 SubExprs[INIT] = Init; 618 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 619 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 620 SubExprs[BODY] = Body; 621 ForLoc = FL; 622 } 623 624 Stmt *getInit() { return SubExprs[INIT]; } 625 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 626 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 627 Stmt *getBody() { return SubExprs[BODY]; } 628 629 const Stmt *getInit() const { return SubExprs[INIT]; } 630 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 631 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 632 const Stmt *getBody() const { return SubExprs[BODY]; } 633 634 virtual SourceRange getSourceRange() const { 635 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 636 } 637 static bool classof(const Stmt *T) { 638 return T->getStmtClass() == ForStmtClass; 639 } 640 static bool classof(const ForStmt *) { return true; } 641 642 // Iterators 643 virtual child_iterator child_begin(); 644 virtual child_iterator child_end(); 645 646 virtual void EmitImpl(llvm::Serializer& S) const; 647 static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 648}; 649 650/// GotoStmt - This represents a direct goto. 651/// 652class GotoStmt : public Stmt { 653 LabelStmt *Label; 654 SourceLocation GotoLoc; 655 SourceLocation LabelLoc; 656public: 657 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 658 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 659 660 LabelStmt *getLabel() const { return Label; } 661 662 virtual SourceRange getSourceRange() const { 663 return SourceRange(GotoLoc, LabelLoc); 664 } 665 static bool classof(const Stmt *T) { 666 return T->getStmtClass() == GotoStmtClass; 667 } 668 static bool classof(const GotoStmt *) { return true; } 669 670 // Iterators 671 virtual child_iterator child_begin(); 672 virtual child_iterator child_end(); 673 674 virtual void EmitImpl(llvm::Serializer& S) const; 675 static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 676}; 677 678/// IndirectGotoStmt - This represents an indirect goto. 679/// 680class IndirectGotoStmt : public Stmt { 681 Stmt *Target; 682 // FIXME: Add location information (e.g. SourceLocation objects). 683 // When doing so, update the serialization routines. 684public: 685 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), 686 Target((Stmt*)target){} 687 688 Expr *getTarget(); 689 const Expr *getTarget() const; 690 691 virtual SourceRange getSourceRange() const { return SourceRange(); } 692 693 static bool classof(const Stmt *T) { 694 return T->getStmtClass() == IndirectGotoStmtClass; 695 } 696 static bool classof(const IndirectGotoStmt *) { return true; } 697 698 // Iterators 699 virtual child_iterator child_begin(); 700 virtual child_iterator child_end(); 701 702 virtual void EmitImpl(llvm::Serializer& S) const; 703 static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 704}; 705 706 707/// ContinueStmt - This represents a continue. 708/// 709class ContinueStmt : public Stmt { 710 SourceLocation ContinueLoc; 711public: 712 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 713 714 virtual SourceRange getSourceRange() const { 715 return SourceRange(ContinueLoc); 716 } 717 static bool classof(const Stmt *T) { 718 return T->getStmtClass() == ContinueStmtClass; 719 } 720 static bool classof(const ContinueStmt *) { return true; } 721 722 // Iterators 723 virtual child_iterator child_begin(); 724 virtual child_iterator child_end(); 725 726 virtual void EmitImpl(llvm::Serializer& S) const; 727 static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 728}; 729 730/// BreakStmt - This represents a break. 731/// 732class BreakStmt : public Stmt { 733 SourceLocation BreakLoc; 734public: 735 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 736 737 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 738 739 static bool classof(const Stmt *T) { 740 return T->getStmtClass() == BreakStmtClass; 741 } 742 static bool classof(const BreakStmt *) { return true; } 743 744 // Iterators 745 virtual child_iterator child_begin(); 746 virtual child_iterator child_end(); 747 748 virtual void EmitImpl(llvm::Serializer& S) const; 749 static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 750}; 751 752 753/// ReturnStmt - This represents a return, optionally of an expression: 754/// return; 755/// return 4; 756/// 757/// Note that GCC allows return with no argument in a function declared to 758/// return a value, and it allows returning a value in functions declared to 759/// return void. We explicitly model this in the AST, which means you can't 760/// depend on the return type of the function and the presence of an argument. 761/// 762class ReturnStmt : public Stmt { 763 Stmt *RetExpr; 764 SourceLocation RetLoc; 765public: 766 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 767 RetExpr((Stmt*) E), RetLoc(RL) {} 768 769 const Expr *getRetValue() const; 770 Expr *getRetValue(); 771 772 virtual SourceRange getSourceRange() const; 773 774 static bool classof(const Stmt *T) { 775 return T->getStmtClass() == ReturnStmtClass; 776 } 777 static bool classof(const ReturnStmt *) { return true; } 778 779 // Iterators 780 virtual child_iterator child_begin(); 781 virtual child_iterator child_end(); 782 783 virtual void EmitImpl(llvm::Serializer& S) const; 784 static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 785}; 786 787/// AsmStmt - This represents a GNU inline-assembly statement extension. 788/// 789class AsmStmt : public Stmt { 790 SourceLocation AsmLoc, RParenLoc; 791 StringLiteral *AsmStr; 792 793 bool IsSimple; 794 bool IsVolatile; 795 796 unsigned NumOutputs; 797 unsigned NumInputs; 798 799 llvm::SmallVector<std::string, 4> Names; 800 llvm::SmallVector<StringLiteral*, 4> Constraints; 801 llvm::SmallVector<Expr*, 4> Exprs; 802 803 llvm::SmallVector<StringLiteral*, 4> Clobbers; 804public: 805 AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 806 unsigned numoutputs, unsigned numinputs, 807 std::string *names, StringLiteral **constraints, 808 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 809 StringLiteral **clobbers, SourceLocation rparenloc); 810 811 bool isVolatile() const { return IsVolatile; } 812 bool isSimple() const { return IsSimple; } 813 814 unsigned getNumOutputs() const { return NumOutputs; } 815 const std::string &getOutputName(unsigned i) const 816 { return Names[i]; } 817 const StringLiteral *getOutputConstraint(unsigned i) const 818 { return Constraints[i]; } 819 StringLiteral *getOutputConstraint(unsigned i) 820 { return Constraints[i]; } 821 const Expr *getOutputExpr(unsigned i) const { return Exprs[i]; } 822 Expr *getOutputExpr(unsigned i) { return Exprs[i]; } 823 824 unsigned getNumInputs() const { return NumInputs; } 825 const std::string &getInputName(unsigned i) const 826 { return Names[i + NumOutputs]; } 827 StringLiteral *getInputConstraint(unsigned i) 828 { return Constraints[i + NumOutputs]; } 829 const StringLiteral *getInputConstraint(unsigned i) const 830 { return Constraints[i + NumOutputs]; } 831 Expr *getInputExpr(unsigned i) { return Exprs[i + NumOutputs]; } 832 const Expr *getInputExpr(unsigned i) const { return Exprs[i + NumOutputs]; } 833 834 const StringLiteral *getAsmString() const { return AsmStr; } 835 StringLiteral *getAsmString() { return AsmStr; } 836 837 unsigned getNumClobbers() const { return Clobbers.size(); } 838 StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } 839 const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } 840 841 virtual SourceRange getSourceRange() const { 842 return SourceRange(AsmLoc, RParenLoc); 843 } 844 845 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 846 static bool classof(const AsmStmt *) { return true; } 847 848 // Input expr iterators. 849 850 typedef Expr* const * inputs_iterator; 851 typedef const Expr* const* const_inputs_iterator; 852 853 inputs_iterator begin_inputs() { return &Exprs[0] + NumOutputs; } 854 inputs_iterator end_inputs() { return begin_inputs() + NumInputs; } 855 856 const_inputs_iterator begin_inputs() const { return &Exprs[0] + NumOutputs; } 857 const_inputs_iterator end_inputs() const { return begin_inputs() + NumInputs;} 858 859 // Output expr iterators. 860 861 typedef Expr* const * outputs_iterator; 862 typedef const Expr* const* const_outputs_iterator; 863 864 outputs_iterator begin_outputs() { return &Exprs[0]; } 865 outputs_iterator end_outputs() { return begin_outputs() + NumOutputs; } 866 867 const_outputs_iterator begin_outputs() const { return &Exprs[0]; } 868 const_outputs_iterator end_outputs() const { 869 return begin_outputs() + NumOutputs; 870 } 871 872 // Child iterators 873 874 virtual child_iterator child_begin(); 875 virtual child_iterator child_end(); 876 877 virtual void EmitImpl(llvm::Serializer& S) const; 878 static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 879}; 880 881/// ObjCForCollectionStmt - This represents Objective-c's collection statement; 882/// represented as 'for (element 'in' collection-expression)' stmt. 883/// 884class ObjCForCollectionStmt : public Stmt { 885 enum { ELEM, COLLECTION, BODY, END_EXPR }; 886 Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt. 887 SourceLocation ForLoc; 888 SourceLocation RParenLoc; 889public: 890 ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, 891 SourceLocation FCL, SourceLocation RPL); 892 893 Stmt *getElement() { return SubExprs[ELEM]; } 894 Expr *getCollection() { 895 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 896 } 897 Stmt *getBody() { return SubExprs[BODY]; } 898 899 const Stmt *getElement() const { return SubExprs[ELEM]; } 900 const Expr *getCollection() const { 901 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 902 } 903 const Stmt *getBody() const { return SubExprs[BODY]; } 904 905 SourceLocation getRParenLoc() const { return RParenLoc; } 906 907 virtual SourceRange getSourceRange() const { 908 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 909 } 910 static bool classof(const Stmt *T) { 911 return T->getStmtClass() == ObjCForCollectionStmtClass; 912 } 913 static bool classof(const ObjCForCollectionStmt *) { return true; } 914 915 // Iterators 916 virtual child_iterator child_begin(); 917 virtual child_iterator child_end(); 918 919 virtual void EmitImpl(llvm::Serializer& S) const; 920 static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 921}; 922 923/// ObjCAtCatchStmt - This represents objective-c's @catch statement. 924class ObjCAtCatchStmt : public Stmt { 925private: 926 enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR }; 927 Stmt *SubExprs[END_EXPR]; 928 SourceLocation AtCatchLoc, RParenLoc; 929 930 // Used by deserialization. 931 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc) 932 : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {} 933 934public: 935 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 936 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList); 937 938 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 939 Stmt *getCatchBody() { return SubExprs[BODY]; } 940 941 const ObjCAtCatchStmt *getNextCatchStmt() const { 942 return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 943 } 944 ObjCAtCatchStmt *getNextCatchStmt() { 945 return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 946 } 947 948 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 949 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 950 951 SourceLocation getRParenLoc() const { return RParenLoc; } 952 953 virtual SourceRange getSourceRange() const { 954 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 955 } 956 957 bool hasEllipsis() const { return getCatchParamStmt() == 0; } 958 959 static bool classof(const Stmt *T) { 960 return T->getStmtClass() == ObjCAtCatchStmtClass; 961 } 962 static bool classof(const ObjCAtCatchStmt *) { return true; } 963 964 virtual child_iterator child_begin(); 965 virtual child_iterator child_end(); 966 967 virtual void EmitImpl(llvm::Serializer& S) const; 968 static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 969}; 970 971/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement 972class ObjCAtFinallyStmt : public Stmt { 973 Stmt *AtFinallyStmt; 974 SourceLocation AtFinallyLoc; 975public: 976 ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 977 : Stmt(ObjCAtFinallyStmtClass), 978 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 979 980 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 981 Stmt *getFinallyBody () { return AtFinallyStmt; } 982 983 virtual SourceRange getSourceRange() const { 984 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 985 } 986 987 static bool classof(const Stmt *T) { 988 return T->getStmtClass() == ObjCAtFinallyStmtClass; 989 } 990 static bool classof(const ObjCAtFinallyStmt *) { return true; } 991 992 virtual child_iterator child_begin(); 993 virtual child_iterator child_end(); 994 995 virtual void EmitImpl(llvm::Serializer& S) const; 996 static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 997}; 998 999/// ObjCAtTryStmt - This represent objective-c's over-all 1000/// @try ... @catch ... @finally statement. 1001class ObjCAtTryStmt : public Stmt { 1002private: 1003 enum { TRY, CATCH, FINALLY, END_EXPR }; 1004 Stmt* SubStmts[END_EXPR]; 1005 1006 SourceLocation AtTryLoc; 1007public: 1008 ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 1009 Stmt *atCatchStmt, 1010 Stmt *atFinallyStmt) 1011 : Stmt(ObjCAtTryStmtClass) { 1012 SubStmts[TRY] = atTryStmt; 1013 SubStmts[CATCH] = atCatchStmt; 1014 SubStmts[FINALLY] = atFinallyStmt; 1015 AtTryLoc = atTryLoc; 1016 } 1017 1018 const Stmt *getTryBody() const { return SubStmts[TRY]; } 1019 Stmt *getTryBody() { return SubStmts[TRY]; } 1020 const ObjCAtCatchStmt *getCatchStmts() const { 1021 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 1022 } 1023 ObjCAtCatchStmt *getCatchStmts() { 1024 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 1025 } 1026 const ObjCAtFinallyStmt *getFinallyStmt() const { 1027 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 1028 } 1029 ObjCAtFinallyStmt *getFinallyStmt() { 1030 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 1031 } 1032 virtual SourceRange getSourceRange() const { 1033 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 1034 } 1035 1036 static bool classof(const Stmt *T) { 1037 return T->getStmtClass() == ObjCAtTryStmtClass; 1038 } 1039 static bool classof(const ObjCAtTryStmt *) { return true; } 1040 1041 virtual child_iterator child_begin(); 1042 virtual child_iterator child_end(); 1043 1044 virtual void EmitImpl(llvm::Serializer& S) const; 1045 static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1046}; 1047 1048/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement. 1049/// Example: @synchronized (sem) { 1050/// do-something; 1051/// } 1052/// 1053class ObjCAtSynchronizedStmt : public Stmt { 1054private: 1055 enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; 1056 Stmt* SubStmts[END_EXPR]; 1057 SourceLocation AtSynchronizedLoc; 1058 1059public: 1060 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, 1061 Stmt *synchBody) 1062 : Stmt(ObjCAtSynchronizedStmtClass) { 1063 SubStmts[SYNC_EXPR] = synchExpr; 1064 SubStmts[SYNC_BODY] = synchBody; 1065 AtSynchronizedLoc = atSynchronizedLoc; 1066 } 1067 1068 const CompoundStmt *getSynchBody() const { 1069 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1070 } 1071 CompoundStmt *getSynchBody() { 1072 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1073 } 1074 1075 const Expr *getSynchExpr() const { 1076 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1077 } 1078 Expr *getSynchExpr() { 1079 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1080 } 1081 1082 virtual SourceRange getSourceRange() const { 1083 return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd()); 1084 } 1085 1086 static bool classof(const Stmt *T) { 1087 return T->getStmtClass() == ObjCAtSynchronizedStmtClass; 1088 } 1089 static bool classof(const ObjCAtSynchronizedStmt *) { return true; } 1090 1091 virtual child_iterator child_begin(); 1092 virtual child_iterator child_end(); 1093 1094 virtual void EmitImpl(llvm::Serializer& S) const; 1095 static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D, 1096 ASTContext& C); 1097}; 1098 1099/// ObjCAtThrowStmt - This represents objective-c's @throw statement. 1100class ObjCAtThrowStmt : public Stmt { 1101 Stmt *Throw; 1102 SourceLocation AtThrowLoc; 1103public: 1104 ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 1105 : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { 1106 AtThrowLoc = atThrowLoc; 1107 } 1108 1109 const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 1110 Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } 1111 1112 virtual SourceRange getSourceRange() const { 1113 if (Throw) 1114 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 1115 else 1116 return SourceRange(AtThrowLoc); 1117 } 1118 1119 static bool classof(const Stmt *T) { 1120 return T->getStmtClass() == ObjCAtThrowStmtClass; 1121 } 1122 static bool classof(const ObjCAtThrowStmt *) { return true; } 1123 1124 virtual child_iterator child_begin(); 1125 virtual child_iterator child_end(); 1126 1127 virtual void EmitImpl(llvm::Serializer& S) const; 1128 static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1129}; 1130 1131} // end namespace clang 1132 1133#endif 1134