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