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