Stmt.h revision 14f8b4ff660bcaa763974b8d0fae81857c594495
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 "clang/Basic/SourceLocation.h" 19#include "clang/AST/StmtIterator.h" 20#include "llvm/ADT/SmallVector.h" 21#include "llvm/ADT/iterator.h" 22#include "llvm/Bitcode/SerializationFwd.h" 23#include <iosfwd> 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(std::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 { 143 ScopedDecl *TheDecl; 144 SourceLocation StartLoc, EndLoc; 145public: 146 DeclStmt(ScopedDecl *D, SourceLocation startLoc, SourceLocation endLoc) 147 : Stmt(DeclStmtClass), TheDecl(D), StartLoc(startLoc), EndLoc(endLoc) {} 148 149 virtual void Destroy(ASTContext& Ctx); 150 151 const ScopedDecl *getDecl() const { return TheDecl; } 152 ScopedDecl *getDecl() { return TheDecl; } 153 154 SourceLocation getStartLoc() const { return StartLoc; } 155 SourceLocation getEndLoc() const { return EndLoc; } 156 virtual SourceRange getSourceRange() const { 157 return SourceRange(StartLoc, EndLoc); 158 } 159 160 static bool classof(const Stmt *T) { 161 return T->getStmtClass() == DeclStmtClass; 162 } 163 static bool classof(const DeclStmt *) { return true; } 164 165 // Iterators over subexpressions. 166 virtual child_iterator child_begin(); 167 virtual child_iterator child_end(); 168 169 // Iterators over the decls. 170 class decl_iterator { 171 ScopedDecl* D; 172 public: 173 decl_iterator(ScopedDecl *d) : D(d) {} 174 bool operator==(const decl_iterator& I) const { return D == I.D; } 175 bool operator!=(const decl_iterator& I) const { return D != I.D; } 176 ScopedDecl* operator*() const { return D; } 177 decl_iterator& operator++(); 178 }; 179 180 virtual decl_iterator decl_begin() { return TheDecl; } 181 virtual decl_iterator decl_end() { return 0; } 182 183 // Serialization. 184 virtual void EmitImpl(llvm::Serializer& S) const; 185 static DeclStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 186}; 187 188/// NullStmt - This is the null statement ";": C99 6.8.3p3. 189/// 190class NullStmt : public Stmt { 191 SourceLocation SemiLoc; 192public: 193 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 194 195 SourceLocation getSemiLoc() const { return SemiLoc; } 196 197 virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } 198 199 static bool classof(const Stmt *T) { 200 return T->getStmtClass() == NullStmtClass; 201 } 202 static bool classof(const NullStmt *) { return true; } 203 204 // Iterators 205 virtual child_iterator child_begin(); 206 virtual child_iterator child_end(); 207 208 virtual void EmitImpl(llvm::Serializer& S) const; 209 static NullStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 210}; 211 212/// CompoundStmt - This represents a group of statements like { stmt stmt }. 213/// 214class CompoundStmt : public Stmt { 215 llvm::SmallVector<Stmt*, 16> Body; 216 SourceLocation LBracLoc, RBracLoc; 217public: 218 CompoundStmt(Stmt **StmtStart, unsigned NumStmts, 219 SourceLocation LB, SourceLocation RB) 220 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts), 221 LBracLoc(LB), RBracLoc(RB) {} 222 223 bool body_empty() const { return Body.empty(); } 224 225 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 226 body_iterator body_begin() { return Body.begin(); } 227 body_iterator body_end() { return Body.end(); } 228 Stmt *body_back() { return Body.back(); } 229 230 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 231 const_body_iterator body_begin() const { return Body.begin(); } 232 const_body_iterator body_end() const { return Body.end(); } 233 const Stmt *body_back() const { return Body.back(); } 234 235 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 236 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 237 reverse_body_iterator body_rend() { return Body.rend(); } 238 239 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 240 const_reverse_body_iterator; 241 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 242 const_reverse_body_iterator body_rend() const { return Body.rend(); } 243 244 void push_back(Stmt *S) { Body.push_back(S); } 245 246 virtual SourceRange getSourceRange() const { 247 return SourceRange(LBracLoc, RBracLoc); 248 } 249 250 SourceLocation getLBracLoc() const { return LBracLoc; } 251 SourceLocation getRBracLoc() const { return RBracLoc; } 252 253 static bool classof(const Stmt *T) { 254 return T->getStmtClass() == CompoundStmtClass; 255 } 256 static bool classof(const CompoundStmt *) { return true; } 257 258 // Iterators 259 virtual child_iterator child_begin(); 260 virtual child_iterator child_end(); 261 262 virtual void EmitImpl(llvm::Serializer& S) const; 263 static CompoundStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 264}; 265 266// SwitchCase is the base class for CaseStmt and DefaultStmt, 267class SwitchCase : public Stmt { 268protected: 269 // A pointer to the following CaseStmt or DefaultStmt class, 270 // used by SwitchStmt. 271 SwitchCase *NextSwitchCase; 272 273 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 274 275public: 276 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 277 278 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 279 280 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 281 282 virtual Stmt* v_getSubStmt() = 0; 283 Stmt *getSubStmt() { return v_getSubStmt(); } 284 285 virtual SourceRange getSourceRange() const { return SourceRange(); } 286 287 static bool classof(const Stmt *T) { 288 return T->getStmtClass() == CaseStmtClass || 289 T->getStmtClass() == DefaultStmtClass; 290 } 291 static bool classof(const SwitchCase *) { return true; } 292}; 293 294class CaseStmt : public SwitchCase { 295 enum { SUBSTMT, LHS, RHS, END_EXPR }; 296 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for 297 // GNU "case 1 ... 4" extension 298 SourceLocation CaseLoc; 299public: 300 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc) 301 : SwitchCase(CaseStmtClass) { 302 SubExprs[SUBSTMT] = substmt; 303 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs); 304 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); 305 CaseLoc = caseLoc; 306 } 307 308 SourceLocation getCaseLoc() const { return CaseLoc; } 309 310 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } 311 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } 312 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } 313 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 314 const Expr *getLHS() const { 315 return reinterpret_cast<const Expr*>(SubExprs[LHS]); 316 } 317 const Expr *getRHS() const { 318 return reinterpret_cast<const Expr*>(SubExprs[RHS]); 319 } 320 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; } 321 322 void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; } 323 void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); } 324 void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); } 325 326 327 virtual SourceRange getSourceRange() const { 328 return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd()); 329 } 330 static bool classof(const Stmt *T) { 331 return T->getStmtClass() == CaseStmtClass; 332 } 333 static bool classof(const CaseStmt *) { return true; } 334 335 // Iterators 336 virtual child_iterator child_begin(); 337 virtual child_iterator child_end(); 338 339 virtual void EmitImpl(llvm::Serializer& S) const; 340 static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 341}; 342 343class DefaultStmt : public SwitchCase { 344 Stmt* SubStmt; 345 SourceLocation DefaultLoc; 346public: 347 DefaultStmt(SourceLocation DL, Stmt *substmt) : 348 SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} 349 350 Stmt *getSubStmt() { return SubStmt; } 351 virtual Stmt* v_getSubStmt() { return getSubStmt(); } 352 const Stmt *getSubStmt() const { return SubStmt; } 353 354 SourceLocation getDefaultLoc() const { return DefaultLoc; } 355 356 virtual SourceRange getSourceRange() const { 357 return SourceRange(DefaultLoc, SubStmt->getLocEnd()); 358 } 359 static bool classof(const Stmt *T) { 360 return T->getStmtClass() == DefaultStmtClass; 361 } 362 static bool classof(const DefaultStmt *) { return true; } 363 364 // Iterators 365 virtual child_iterator child_begin(); 366 virtual child_iterator child_end(); 367 368 virtual void EmitImpl(llvm::Serializer& S) const; 369 static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 370}; 371 372class LabelStmt : public Stmt { 373 IdentifierInfo *Label; 374 Stmt *SubStmt; 375 SourceLocation IdentLoc; 376public: 377 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 378 : Stmt(LabelStmtClass), Label(label), 379 SubStmt(substmt), IdentLoc(IL) {} 380 381 SourceLocation getIdentLoc() const { return IdentLoc; } 382 IdentifierInfo *getID() const { return Label; } 383 const char *getName() const; 384 Stmt *getSubStmt() { return SubStmt; } 385 const Stmt *getSubStmt() const { return SubStmt; } 386 387 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 388 void setSubStmt(Stmt *SS) { SubStmt = SS; } 389 390 virtual SourceRange getSourceRange() const { 391 return SourceRange(IdentLoc, SubStmt->getLocEnd()); 392 } 393 static bool classof(const Stmt *T) { 394 return T->getStmtClass() == LabelStmtClass; 395 } 396 static bool classof(const LabelStmt *) { return true; } 397 398 // Iterators 399 virtual child_iterator child_begin(); 400 virtual child_iterator child_end(); 401 402 virtual void EmitImpl(llvm::Serializer& S) const; 403 static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 404}; 405 406 407/// IfStmt - This represents an if/then/else. 408/// 409class IfStmt : public Stmt { 410 enum { COND, THEN, ELSE, END_EXPR }; 411 Stmt* SubExprs[END_EXPR]; 412 SourceLocation IfLoc; 413public: 414 IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0) 415 : Stmt(IfStmtClass) { 416 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 417 SubExprs[THEN] = then; 418 SubExprs[ELSE] = elsev; 419 IfLoc = IL; 420 } 421 422 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 423 const Stmt *getThen() const { return SubExprs[THEN]; } 424 const Stmt *getElse() const { return SubExprs[ELSE]; } 425 426 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 427 Stmt *getThen() { return SubExprs[THEN]; } 428 Stmt *getElse() { return SubExprs[ELSE]; } 429 430 virtual SourceRange getSourceRange() const { 431 if (SubExprs[ELSE]) 432 return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); 433 else 434 return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd()); 435 } 436 437 static bool classof(const Stmt *T) { 438 return T->getStmtClass() == IfStmtClass; 439 } 440 static bool classof(const IfStmt *) { return true; } 441 442 // Iterators 443 virtual child_iterator child_begin(); 444 virtual child_iterator child_end(); 445 446 virtual void EmitImpl(llvm::Serializer& S) const; 447 static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 448}; 449 450/// SwitchStmt - This represents a 'switch' stmt. 451/// 452class SwitchStmt : public Stmt { 453 enum { COND, BODY, END_EXPR }; 454 Stmt* SubExprs[END_EXPR]; 455 // This points to a linked list of case and default statements. 456 SwitchCase *FirstCase; 457 SourceLocation SwitchLoc; 458public: 459 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 460 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 461 SubExprs[BODY] = NULL; 462 } 463 464 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 465 const Stmt *getBody() const { return SubExprs[BODY]; } 466 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 467 468 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 469 Stmt *getBody() { return SubExprs[BODY]; } 470 SwitchCase *getSwitchCaseList() { return FirstCase; } 471 472 void setBody(Stmt *S, SourceLocation SL) { 473 SubExprs[BODY] = S; 474 SwitchLoc = SL; 475 } 476 void addSwitchCase(SwitchCase *SC) { 477 if (FirstCase) 478 SC->setNextSwitchCase(FirstCase); 479 480 FirstCase = SC; 481 } 482 virtual SourceRange getSourceRange() const { 483 return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd()); 484 } 485 static bool classof(const Stmt *T) { 486 return T->getStmtClass() == SwitchStmtClass; 487 } 488 static bool classof(const SwitchStmt *) { return true; } 489 490 // Iterators 491 virtual child_iterator child_begin(); 492 virtual child_iterator child_end(); 493 494 virtual void EmitImpl(llvm::Serializer& S) const; 495 static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 496}; 497 498 499/// WhileStmt - This represents a 'while' stmt. 500/// 501class WhileStmt : public Stmt { 502 enum { COND, BODY, END_EXPR }; 503 Stmt* SubExprs[END_EXPR]; 504 SourceLocation WhileLoc; 505public: 506 WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) { 507 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 508 SubExprs[BODY] = body; 509 WhileLoc = WL; 510 } 511 512 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 513 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 514 Stmt *getBody() { return SubExprs[BODY]; } 515 const Stmt *getBody() const { return SubExprs[BODY]; } 516 517 virtual SourceRange getSourceRange() const { 518 return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd()); 519 } 520 static bool classof(const Stmt *T) { 521 return T->getStmtClass() == WhileStmtClass; 522 } 523 static bool classof(const WhileStmt *) { return true; } 524 525 // Iterators 526 virtual child_iterator child_begin(); 527 virtual child_iterator child_end(); 528 529 virtual void EmitImpl(llvm::Serializer& S) const; 530 static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 531}; 532 533/// DoStmt - This represents a 'do/while' stmt. 534/// 535class DoStmt : public Stmt { 536 enum { COND, BODY, END_EXPR }; 537 Stmt* SubExprs[END_EXPR]; 538 SourceLocation DoLoc; 539public: 540 DoStmt(Stmt *body, Expr *cond, SourceLocation DL) 541 : Stmt(DoStmtClass), DoLoc(DL) { 542 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 543 SubExprs[BODY] = body; 544 DoLoc = DL; 545 } 546 547 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 548 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 549 Stmt *getBody() { return SubExprs[BODY]; } 550 const Stmt *getBody() const { return SubExprs[BODY]; } 551 552 virtual SourceRange getSourceRange() const { 553 return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd()); 554 } 555 static bool classof(const Stmt *T) { 556 return T->getStmtClass() == DoStmtClass; 557 } 558 static bool classof(const DoStmt *) { return true; } 559 560 // Iterators 561 virtual child_iterator child_begin(); 562 virtual child_iterator child_end(); 563 564 virtual void EmitImpl(llvm::Serializer& S) const; 565 static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 566}; 567 568 569/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 570/// the init/cond/inc parts of the ForStmt will be null if they were not 571/// specified in the source. 572/// 573class ForStmt : public Stmt { 574 enum { INIT, COND, INC, BODY, END_EXPR }; 575 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 576 SourceLocation ForLoc; 577public: 578 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL) 579 : Stmt(ForStmtClass) { 580 SubExprs[INIT] = Init; 581 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 582 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 583 SubExprs[BODY] = Body; 584 ForLoc = FL; 585 } 586 587 Stmt *getInit() { return SubExprs[INIT]; } 588 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 589 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 590 Stmt *getBody() { return SubExprs[BODY]; } 591 592 const Stmt *getInit() const { return SubExprs[INIT]; } 593 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 594 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 595 const Stmt *getBody() const { return SubExprs[BODY]; } 596 597 virtual SourceRange getSourceRange() const { 598 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 599 } 600 static bool classof(const Stmt *T) { 601 return T->getStmtClass() == ForStmtClass; 602 } 603 static bool classof(const ForStmt *) { return true; } 604 605 // Iterators 606 virtual child_iterator child_begin(); 607 virtual child_iterator child_end(); 608 609 virtual void EmitImpl(llvm::Serializer& S) const; 610 static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 611}; 612 613/// GotoStmt - This represents a direct goto. 614/// 615class GotoStmt : public Stmt { 616 LabelStmt *Label; 617 SourceLocation GotoLoc; 618 SourceLocation LabelLoc; 619public: 620 GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL) 621 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {} 622 623 LabelStmt *getLabel() const { return Label; } 624 625 virtual SourceRange getSourceRange() const { 626 return SourceRange(GotoLoc, LabelLoc); 627 } 628 static bool classof(const Stmt *T) { 629 return T->getStmtClass() == GotoStmtClass; 630 } 631 static bool classof(const GotoStmt *) { return true; } 632 633 // Iterators 634 virtual child_iterator child_begin(); 635 virtual child_iterator child_end(); 636 637 virtual void EmitImpl(llvm::Serializer& S) const; 638 static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 639}; 640 641/// IndirectGotoStmt - This represents an indirect goto. 642/// 643class IndirectGotoStmt : public Stmt { 644 Stmt *Target; 645 // FIXME: Add location information (e.g. SourceLocation objects). 646 // When doing so, update the serialization routines. 647public: 648 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), 649 Target((Stmt*)target){} 650 651 Expr *getTarget(); 652 const Expr *getTarget() const; 653 654 virtual SourceRange getSourceRange() const { return SourceRange(); } 655 656 static bool classof(const Stmt *T) { 657 return T->getStmtClass() == IndirectGotoStmtClass; 658 } 659 static bool classof(const IndirectGotoStmt *) { return true; } 660 661 // Iterators 662 virtual child_iterator child_begin(); 663 virtual child_iterator child_end(); 664 665 virtual void EmitImpl(llvm::Serializer& S) const; 666 static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 667}; 668 669 670/// ContinueStmt - This represents a continue. 671/// 672class ContinueStmt : public Stmt { 673 SourceLocation ContinueLoc; 674public: 675 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 676 677 virtual SourceRange getSourceRange() const { 678 return SourceRange(ContinueLoc); 679 } 680 static bool classof(const Stmt *T) { 681 return T->getStmtClass() == ContinueStmtClass; 682 } 683 static bool classof(const ContinueStmt *) { return true; } 684 685 // Iterators 686 virtual child_iterator child_begin(); 687 virtual child_iterator child_end(); 688 689 virtual void EmitImpl(llvm::Serializer& S) const; 690 static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 691}; 692 693/// BreakStmt - This represents a break. 694/// 695class BreakStmt : public Stmt { 696 SourceLocation BreakLoc; 697public: 698 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 699 700 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 701 702 static bool classof(const Stmt *T) { 703 return T->getStmtClass() == BreakStmtClass; 704 } 705 static bool classof(const BreakStmt *) { return true; } 706 707 // Iterators 708 virtual child_iterator child_begin(); 709 virtual child_iterator child_end(); 710 711 virtual void EmitImpl(llvm::Serializer& S) const; 712 static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 713}; 714 715 716/// ReturnStmt - This represents a return, optionally of an expression: 717/// return; 718/// return 4; 719/// 720/// Note that GCC allows return with no argument in a function declared to 721/// return a value, and it allows returning a value in functions declared to 722/// return void. We explicitly model this in the AST, which means you can't 723/// depend on the return type of the function and the presence of an argument. 724/// 725class ReturnStmt : public Stmt { 726 Stmt *RetExpr; 727 SourceLocation RetLoc; 728public: 729 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 730 RetExpr((Stmt*) E), RetLoc(RL) {} 731 732 const Expr *getRetValue() const; 733 Expr *getRetValue(); 734 735 virtual SourceRange getSourceRange() const; 736 737 static bool classof(const Stmt *T) { 738 return T->getStmtClass() == ReturnStmtClass; 739 } 740 static bool classof(const ReturnStmt *) { return true; } 741 742 // Iterators 743 virtual child_iterator child_begin(); 744 virtual child_iterator child_end(); 745 746 virtual void EmitImpl(llvm::Serializer& S) const; 747 static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 748}; 749 750/// AsmStmt - This represents a GNU inline-assembly statement extension. 751/// 752class AsmStmt : public Stmt { 753 SourceLocation AsmLoc, RParenLoc; 754 StringLiteral *AsmStr; 755 756 bool IsSimple; 757 bool IsVolatile; 758 759 unsigned NumOutputs; 760 unsigned NumInputs; 761 762 llvm::SmallVector<std::string, 4> Names; 763 llvm::SmallVector<StringLiteral*, 4> Constraints; 764 llvm::SmallVector<Expr*, 4> Exprs; 765 766 llvm::SmallVector<StringLiteral*, 4> Clobbers; 767public: 768 AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 769 unsigned numoutputs, unsigned numinputs, 770 std::string *names, StringLiteral **constraints, 771 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 772 StringLiteral **clobbers, SourceLocation rparenloc); 773 774 bool isVolatile() const { return IsVolatile; } 775 bool isSimple() const { return IsSimple; } 776 777 unsigned getNumOutputs() const { return NumOutputs; } 778 const std::string &getOutputName(unsigned i) const 779 { return Names[i]; } 780 const StringLiteral *getOutputConstraint(unsigned i) const 781 { return Constraints[i]; } 782 StringLiteral *getOutputConstraint(unsigned i) 783 { return Constraints[i]; } 784 const Expr *getOutputExpr(unsigned i) const { return Exprs[i]; } 785 Expr *getOutputExpr(unsigned i) { return Exprs[i]; } 786 787 unsigned getNumInputs() const { return NumInputs; } 788 const std::string &getInputName(unsigned i) const 789 { return Names[i + NumOutputs]; } 790 StringLiteral *getInputConstraint(unsigned i) 791 { return Constraints[i + NumOutputs]; } 792 const StringLiteral *getInputConstraint(unsigned i) const 793 { return Constraints[i + NumOutputs]; } 794 Expr *getInputExpr(unsigned i) { return Exprs[i + NumOutputs]; } 795 const Expr *getInputExpr(unsigned i) const { return Exprs[i + NumOutputs]; } 796 797 const StringLiteral *getAsmString() const { return AsmStr; } 798 StringLiteral *getAsmString() { return AsmStr; } 799 800 unsigned getNumClobbers() const { return Clobbers.size(); } 801 StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } 802 const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } 803 804 virtual SourceRange getSourceRange() const { 805 return SourceRange(AsmLoc, RParenLoc); 806 } 807 808 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 809 static bool classof(const AsmStmt *) { return true; } 810 811 // Input expr iterators. 812 813 typedef Expr* const * inputs_iterator; 814 typedef const Expr* const* const_inputs_iterator; 815 816 inputs_iterator begin_inputs() { return &Exprs[0] + NumOutputs; } 817 inputs_iterator end_inputs() { return begin_inputs() + NumInputs; } 818 819 const_inputs_iterator begin_inputs() const { return &Exprs[0] + NumOutputs; } 820 const_inputs_iterator end_inputs() const { return begin_inputs() + NumInputs;} 821 822 // Output expr iterators. 823 824 typedef Expr* const * outputs_iterator; 825 typedef const Expr* const* const_outputs_iterator; 826 827 outputs_iterator begin_outputs() { return &Exprs[0]; } 828 outputs_iterator end_outputs() { return begin_outputs() + NumOutputs; } 829 830 const_outputs_iterator begin_outputs() const { return &Exprs[0]; } 831 const_outputs_iterator end_outputs() const { 832 return begin_outputs() + NumOutputs; 833 } 834 835 // Child iterators 836 837 virtual child_iterator child_begin(); 838 virtual child_iterator child_end(); 839 840 virtual void EmitImpl(llvm::Serializer& S) const; 841 static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 842}; 843 844/// ObjCForCollectionStmt - This represents Objective-c's collection statement; 845/// represented as 'for (element 'in' collection-expression)' stmt. 846/// 847class ObjCForCollectionStmt : public Stmt { 848 enum { ELEM, COLLECTION, BODY, END_EXPR }; 849 Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt. 850 SourceLocation ForLoc; 851 SourceLocation RParenLoc; 852public: 853 ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, 854 SourceLocation FCL, SourceLocation RPL); 855 856 Stmt *getElement() { return SubExprs[ELEM]; } 857 Expr *getCollection() { 858 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 859 } 860 Stmt *getBody() { return SubExprs[BODY]; } 861 862 const Stmt *getElement() const { return SubExprs[ELEM]; } 863 const Expr *getCollection() const { 864 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 865 } 866 const Stmt *getBody() const { return SubExprs[BODY]; } 867 868 SourceLocation getRParenLoc() const { return RParenLoc; } 869 870 virtual SourceRange getSourceRange() const { 871 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 872 } 873 static bool classof(const Stmt *T) { 874 return T->getStmtClass() == ObjCForCollectionStmtClass; 875 } 876 static bool classof(const ObjCForCollectionStmt *) { return true; } 877 878 // Iterators 879 virtual child_iterator child_begin(); 880 virtual child_iterator child_end(); 881 882 virtual void EmitImpl(llvm::Serializer& S) const; 883 static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 884}; 885 886/// ObjCAtCatchStmt - This represents objective-c's @catch statement. 887class ObjCAtCatchStmt : public Stmt { 888private: 889 enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR }; 890 Stmt *SubExprs[END_EXPR]; 891 SourceLocation AtCatchLoc, RParenLoc; 892 893 // Used by deserialization. 894 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc) 895 : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {} 896 897public: 898 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 899 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList); 900 901 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 902 Stmt *getCatchBody() { return SubExprs[BODY]; } 903 904 const ObjCAtCatchStmt *getNextCatchStmt() const { 905 return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 906 } 907 ObjCAtCatchStmt *getNextCatchStmt() { 908 return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 909 } 910 911 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 912 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 913 914 SourceLocation getRParenLoc() const { return RParenLoc; } 915 916 virtual SourceRange getSourceRange() const { 917 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 918 } 919 920 bool hasEllipsis() const { return getCatchParamStmt() == 0; } 921 922 static bool classof(const Stmt *T) { 923 return T->getStmtClass() == ObjCAtCatchStmtClass; 924 } 925 static bool classof(const ObjCAtCatchStmt *) { return true; } 926 927 virtual child_iterator child_begin(); 928 virtual child_iterator child_end(); 929 930 virtual void EmitImpl(llvm::Serializer& S) const; 931 static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 932}; 933 934/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement 935class ObjCAtFinallyStmt : public Stmt { 936 Stmt *AtFinallyStmt; 937 SourceLocation AtFinallyLoc; 938public: 939 ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 940 : Stmt(ObjCAtFinallyStmtClass), 941 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 942 943 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 944 Stmt *getFinallyBody () { return AtFinallyStmt; } 945 946 virtual SourceRange getSourceRange() const { 947 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 948 } 949 950 static bool classof(const Stmt *T) { 951 return T->getStmtClass() == ObjCAtFinallyStmtClass; 952 } 953 static bool classof(const ObjCAtFinallyStmt *) { return true; } 954 955 virtual child_iterator child_begin(); 956 virtual child_iterator child_end(); 957 958 virtual void EmitImpl(llvm::Serializer& S) const; 959 static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 960}; 961 962/// ObjCAtTryStmt - This represent objective-c's over-all 963/// @try ... @catch ... @finally statement. 964class ObjCAtTryStmt : public Stmt { 965private: 966 enum { TRY, CATCH, FINALLY, END_EXPR }; 967 Stmt* SubStmts[END_EXPR]; 968 969 SourceLocation AtTryLoc; 970public: 971 ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 972 Stmt *atCatchStmt, 973 Stmt *atFinallyStmt) 974 : Stmt(ObjCAtTryStmtClass) { 975 SubStmts[TRY] = atTryStmt; 976 SubStmts[CATCH] = atCatchStmt; 977 SubStmts[FINALLY] = atFinallyStmt; 978 AtTryLoc = atTryLoc; 979 } 980 981 const Stmt *getTryBody() const { return SubStmts[TRY]; } 982 Stmt *getTryBody() { return SubStmts[TRY]; } 983 const ObjCAtCatchStmt *getCatchStmts() const { 984 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 985 } 986 ObjCAtCatchStmt *getCatchStmts() { 987 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 988 } 989 const ObjCAtFinallyStmt *getFinallyStmt() const { 990 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 991 } 992 ObjCAtFinallyStmt *getFinallyStmt() { 993 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 994 } 995 virtual SourceRange getSourceRange() const { 996 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 997 } 998 999 static bool classof(const Stmt *T) { 1000 return T->getStmtClass() == ObjCAtTryStmtClass; 1001 } 1002 static bool classof(const ObjCAtTryStmt *) { return true; } 1003 1004 virtual child_iterator child_begin(); 1005 virtual child_iterator child_end(); 1006 1007 virtual void EmitImpl(llvm::Serializer& S) const; 1008 static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1009}; 1010 1011/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement. 1012/// Example: @synchronized (sem) { 1013/// do-something; 1014/// } 1015/// 1016class ObjCAtSynchronizedStmt : public Stmt { 1017private: 1018 enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; 1019 Stmt* SubStmts[END_EXPR]; 1020 SourceLocation AtSynchronizedLoc; 1021 1022public: 1023 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, 1024 Stmt *synchBody) 1025 : Stmt(ObjCAtSynchronizedStmtClass) { 1026 SubStmts[SYNC_EXPR] = synchExpr; 1027 SubStmts[SYNC_BODY] = synchBody; 1028 AtSynchronizedLoc = atSynchronizedLoc; 1029 } 1030 1031 const CompoundStmt *getSynchBody() const { 1032 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1033 } 1034 CompoundStmt *getSynchBody() { 1035 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1036 } 1037 1038 const Expr *getSynchExpr() const { 1039 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1040 } 1041 Expr *getSynchExpr() { 1042 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1043 } 1044 1045 virtual SourceRange getSourceRange() const { 1046 return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd()); 1047 } 1048 1049 static bool classof(const Stmt *T) { 1050 return T->getStmtClass() == ObjCAtSynchronizedStmtClass; 1051 } 1052 static bool classof(const ObjCAtSynchronizedStmt *) { return true; } 1053 1054 virtual child_iterator child_begin(); 1055 virtual child_iterator child_end(); 1056 1057 virtual void EmitImpl(llvm::Serializer& S) const; 1058 static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D, 1059 ASTContext& C); 1060}; 1061 1062/// ObjCAtThrowStmt - This represents objective-c's @throw statement. 1063class ObjCAtThrowStmt : public Stmt { 1064 Stmt *Throw; 1065 SourceLocation AtThrowLoc; 1066public: 1067 ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 1068 : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { 1069 AtThrowLoc = atThrowLoc; 1070 } 1071 1072 const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 1073 Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } 1074 1075 virtual SourceRange getSourceRange() const { 1076 if (Throw) 1077 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 1078 else 1079 return SourceRange(AtThrowLoc); 1080 } 1081 1082 static bool classof(const Stmt *T) { 1083 return T->getStmtClass() == ObjCAtThrowStmtClass; 1084 } 1085 static bool classof(const ObjCAtThrowStmt *) { return true; } 1086 1087 virtual child_iterator child_begin(); 1088 virtual child_iterator child_end(); 1089 1090 virtual void EmitImpl(llvm::Serializer& S) const; 1091 static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1092}; 1093 1094} // end namespace clang 1095 1096#endif 1097