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