Stmt.h revision 1060aff23f72135f8b50034a1e80f16725ebc56c
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 Stmt *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), 634 Target((Stmt*)target){} 635 636 Expr *getTarget(); 637 const Expr *getTarget() const; 638 639 virtual SourceRange getSourceRange() const { return SourceRange(); } 640 641 static bool classof(const Stmt *T) { 642 return T->getStmtClass() == IndirectGotoStmtClass; 643 } 644 static bool classof(const IndirectGotoStmt *) { return true; } 645 646 // Iterators 647 virtual child_iterator child_begin(); 648 virtual child_iterator child_end(); 649 650 virtual void EmitImpl(llvm::Serializer& S) const; 651 static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 652}; 653 654 655/// ContinueStmt - This represents a continue. 656/// 657class ContinueStmt : public Stmt { 658 SourceLocation ContinueLoc; 659public: 660 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {} 661 662 virtual SourceRange getSourceRange() const { 663 return SourceRange(ContinueLoc); 664 } 665 static bool classof(const Stmt *T) { 666 return T->getStmtClass() == ContinueStmtClass; 667 } 668 static bool classof(const ContinueStmt *) { return true; } 669 670 // Iterators 671 virtual child_iterator child_begin(); 672 virtual child_iterator child_end(); 673 674 virtual void EmitImpl(llvm::Serializer& S) const; 675 static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 676}; 677 678/// BreakStmt - This represents a break. 679/// 680class BreakStmt : public Stmt { 681 SourceLocation BreakLoc; 682public: 683 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} 684 685 virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } 686 687 static bool classof(const Stmt *T) { 688 return T->getStmtClass() == BreakStmtClass; 689 } 690 static bool classof(const BreakStmt *) { return true; } 691 692 // Iterators 693 virtual child_iterator child_begin(); 694 virtual child_iterator child_end(); 695 696 virtual void EmitImpl(llvm::Serializer& S) const; 697 static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 698}; 699 700 701/// ReturnStmt - This represents a return, optionally of an expression: 702/// return; 703/// return 4; 704/// 705/// Note that GCC allows return with no argument in a function declared to 706/// return a value, and it allows returning a value in functions declared to 707/// return void. We explicitly model this in the AST, which means you can't 708/// depend on the return type of the function and the presence of an argument. 709/// 710class ReturnStmt : public Stmt { 711 Stmt *RetExpr; 712 SourceLocation RetLoc; 713public: 714 ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), 715 RetExpr((Stmt*) E), RetLoc(RL) {} 716 717 const Expr *getRetValue() const; 718 Expr *getRetValue(); 719 720 virtual SourceRange getSourceRange() const; 721 722 static bool classof(const Stmt *T) { 723 return T->getStmtClass() == ReturnStmtClass; 724 } 725 static bool classof(const ReturnStmt *) { 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 ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 733}; 734 735/// AsmStmt - This represents a GNU inline-assembly statement extension. 736/// 737class AsmStmt : public Stmt { 738 SourceLocation AsmLoc, RParenLoc; 739 StringLiteral *AsmStr; 740 741 bool IsSimple; 742 bool IsVolatile; 743 744 unsigned NumOutputs; 745 unsigned NumInputs; 746 747 llvm::SmallVector<std::string, 4> Names; 748 llvm::SmallVector<StringLiteral*, 4> Constraints; 749 llvm::SmallVector<Expr*, 4> Exprs; 750 751 llvm::SmallVector<StringLiteral*, 4> Clobbers; 752public: 753 AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 754 unsigned numoutputs, unsigned numinputs, 755 std::string *names, StringLiteral **constraints, 756 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 757 StringLiteral **clobbers, SourceLocation rparenloc); 758 759 bool isVolatile() const { return IsVolatile; } 760 bool isSimple() const { return IsSimple; } 761 762 unsigned getNumOutputs() const { return NumOutputs; } 763 const std::string &getOutputName(unsigned i) const 764 { return Names[i]; } 765 const StringLiteral *getOutputConstraint(unsigned i) const 766 { return Constraints[i]; } 767 StringLiteral *getOutputConstraint(unsigned i) 768 { return Constraints[i]; } 769 const Expr *getOutputExpr(unsigned i) const { return Exprs[i]; } 770 Expr *getOutputExpr(unsigned i) { return Exprs[i]; } 771 772 unsigned getNumInputs() const { return NumInputs; } 773 const std::string &getInputName(unsigned i) const 774 { return Names[i + NumOutputs]; } 775 StringLiteral *getInputConstraint(unsigned i) 776 { return Constraints[i + NumOutputs]; } 777 const StringLiteral *getInputConstraint(unsigned i) const 778 { return Constraints[i + NumOutputs]; } 779 Expr *getInputExpr(unsigned i) { return Exprs[i + NumOutputs]; } 780 const Expr *getInputExpr(unsigned i) const { return Exprs[i + NumOutputs]; } 781 782 const StringLiteral *getAsmString() const { return AsmStr; } 783 StringLiteral *getAsmString() { return AsmStr; } 784 785 unsigned getNumClobbers() const { return Clobbers.size(); } 786 StringLiteral *getClobber(unsigned i) { return Clobbers[i]; } 787 const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; } 788 789 virtual SourceRange getSourceRange() const { 790 return SourceRange(AsmLoc, RParenLoc); 791 } 792 793 static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;} 794 static bool classof(const AsmStmt *) { return true; } 795 796 // Input expr iterators. 797 798 typedef Expr* const * inputs_iterator; 799 typedef const Expr* const* const_inputs_iterator; 800 801 inputs_iterator begin_inputs() { return &Exprs[0] + NumOutputs; } 802 inputs_iterator end_inputs() { return begin_inputs() + NumInputs; } 803 804 const_inputs_iterator begin_inputs() const { return &Exprs[0] + NumOutputs; } 805 const_inputs_iterator end_inputs() const { return begin_inputs() + NumInputs;} 806 807 // Output expr iterators. 808 809 typedef Expr* const * outputs_iterator; 810 typedef const Expr* const* const_outputs_iterator; 811 812 outputs_iterator begin_outputs() { return &Exprs[0]; } 813 outputs_iterator end_outputs() { return begin_outputs() + NumOutputs; } 814 815 const_outputs_iterator begin_outputs() const { return &Exprs[0]; } 816 const_outputs_iterator end_outputs() const { 817 return begin_outputs() + NumOutputs; 818 } 819 820 // Child iterators 821 822 virtual child_iterator child_begin(); 823 virtual child_iterator child_end(); 824 825 virtual void EmitImpl(llvm::Serializer& S) const; 826 static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 827}; 828 829/// ObjCForCollectionStmt - This represents Objective-c's collection statement; 830/// represented as 'for (element 'in' collection-expression)' stmt. 831/// 832class ObjCForCollectionStmt : public Stmt { 833 enum { ELEM, COLLECTION, BODY, END_EXPR }; 834 Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt. 835 SourceLocation ForLoc; 836 SourceLocation RParenLoc; 837public: 838 ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body, 839 SourceLocation FCL, SourceLocation RPL); 840 841 Stmt *getElement() { return SubExprs[ELEM]; } 842 Expr *getCollection() { 843 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 844 } 845 Stmt *getBody() { return SubExprs[BODY]; } 846 847 const Stmt *getElement() const { return SubExprs[ELEM]; } 848 const Expr *getCollection() const { 849 return reinterpret_cast<Expr*>(SubExprs[COLLECTION]); 850 } 851 const Stmt *getBody() const { return SubExprs[BODY]; } 852 853 SourceLocation getRParenLoc() const { return RParenLoc; } 854 855 virtual SourceRange getSourceRange() const { 856 return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd()); 857 } 858 static bool classof(const Stmt *T) { 859 return T->getStmtClass() == ObjCForCollectionStmtClass; 860 } 861 static bool classof(const ObjCForCollectionStmt *) { return true; } 862 863 // Iterators 864 virtual child_iterator child_begin(); 865 virtual child_iterator child_end(); 866 867 virtual void EmitImpl(llvm::Serializer& S) const; 868 static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 869}; 870 871/// ObjCAtCatchStmt - This represents objective-c's @catch statement. 872class ObjCAtCatchStmt : public Stmt { 873private: 874 enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR }; 875 Stmt *SubExprs[END_EXPR]; 876 SourceLocation AtCatchLoc, RParenLoc; 877 878 // Used by deserialization. 879 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc) 880 : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {} 881 882public: 883 ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc, 884 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList); 885 886 const Stmt *getCatchBody() const { return SubExprs[BODY]; } 887 Stmt *getCatchBody() { return SubExprs[BODY]; } 888 889 const ObjCAtCatchStmt *getNextCatchStmt() const { 890 return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 891 } 892 ObjCAtCatchStmt *getNextCatchStmt() { 893 return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]); 894 } 895 896 const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; } 897 Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; } 898 899 SourceLocation getRParenLoc() const { return RParenLoc; } 900 901 virtual SourceRange getSourceRange() const { 902 return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd()); 903 } 904 905 bool hasEllipsis() const { return getCatchParamStmt() == 0; } 906 907 static bool classof(const Stmt *T) { 908 return T->getStmtClass() == ObjCAtCatchStmtClass; 909 } 910 static bool classof(const ObjCAtCatchStmt *) { return true; } 911 912 virtual child_iterator child_begin(); 913 virtual child_iterator child_end(); 914 915 virtual void EmitImpl(llvm::Serializer& S) const; 916 static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 917}; 918 919/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement 920class ObjCAtFinallyStmt : public Stmt { 921 Stmt *AtFinallyStmt; 922 SourceLocation AtFinallyLoc; 923public: 924 ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) 925 : Stmt(ObjCAtFinallyStmtClass), 926 AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} 927 928 const Stmt *getFinallyBody () const { return AtFinallyStmt; } 929 Stmt *getFinallyBody () { return AtFinallyStmt; } 930 931 virtual SourceRange getSourceRange() const { 932 return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd()); 933 } 934 935 static bool classof(const Stmt *T) { 936 return T->getStmtClass() == ObjCAtFinallyStmtClass; 937 } 938 static bool classof(const ObjCAtFinallyStmt *) { return true; } 939 940 virtual child_iterator child_begin(); 941 virtual child_iterator child_end(); 942 943 virtual void EmitImpl(llvm::Serializer& S) const; 944 static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 945}; 946 947/// ObjCAtTryStmt - This represent objective-c's over-all 948/// @try ... @catch ... @finally statement. 949class ObjCAtTryStmt : public Stmt { 950private: 951 enum { TRY, CATCH, FINALLY, END_EXPR }; 952 Stmt* SubStmts[END_EXPR]; 953 954 SourceLocation AtTryLoc; 955public: 956 ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 957 Stmt *atCatchStmt, 958 Stmt *atFinallyStmt) 959 : Stmt(ObjCAtTryStmtClass) { 960 SubStmts[TRY] = atTryStmt; 961 SubStmts[CATCH] = atCatchStmt; 962 SubStmts[FINALLY] = atFinallyStmt; 963 AtTryLoc = atTryLoc; 964 } 965 966 const Stmt *getTryBody() const { return SubStmts[TRY]; } 967 Stmt *getTryBody() { return SubStmts[TRY]; } 968 const ObjCAtCatchStmt *getCatchStmts() const { 969 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 970 } 971 ObjCAtCatchStmt *getCatchStmts() { 972 return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]); 973 } 974 const ObjCAtFinallyStmt *getFinallyStmt() const { 975 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 976 } 977 ObjCAtFinallyStmt *getFinallyStmt() { 978 return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]); 979 } 980 virtual SourceRange getSourceRange() const { 981 return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd()); 982 } 983 984 static bool classof(const Stmt *T) { 985 return T->getStmtClass() == ObjCAtTryStmtClass; 986 } 987 static bool classof(const ObjCAtTryStmt *) { return true; } 988 989 virtual child_iterator child_begin(); 990 virtual child_iterator child_end(); 991 992 virtual void EmitImpl(llvm::Serializer& S) const; 993 static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 994}; 995 996/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement. 997/// Example: @synchronized (sem) { 998/// do-something; 999/// } 1000/// 1001class ObjCAtSynchronizedStmt : public Stmt { 1002private: 1003 enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; 1004 Stmt* SubStmts[END_EXPR]; 1005 SourceLocation AtSynchronizedLoc; 1006 1007public: 1008 ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, 1009 Stmt *synchBody) 1010 : Stmt(ObjCAtSynchronizedStmtClass) { 1011 SubStmts[SYNC_EXPR] = synchExpr; 1012 SubStmts[SYNC_BODY] = synchBody; 1013 AtSynchronizedLoc = atSynchronizedLoc; 1014 } 1015 1016 const CompoundStmt *getSynchBody() const { 1017 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1018 } 1019 CompoundStmt *getSynchBody() { 1020 return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]); 1021 } 1022 1023 const Expr *getSynchExpr() const { 1024 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1025 } 1026 Expr *getSynchExpr() { 1027 return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]); 1028 } 1029 1030 virtual SourceRange getSourceRange() const { 1031 return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd()); 1032 } 1033 1034 static bool classof(const Stmt *T) { 1035 return T->getStmtClass() == ObjCAtSynchronizedStmtClass; 1036 } 1037 static bool classof(const ObjCAtSynchronizedStmt *) { return true; } 1038 1039 virtual child_iterator child_begin(); 1040 virtual child_iterator child_end(); 1041 1042 virtual void EmitImpl(llvm::Serializer& S) const; 1043 static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D, 1044 ASTContext& C); 1045}; 1046 1047/// ObjCAtThrowStmt - This represents objective-c's @throw statement. 1048class ObjCAtThrowStmt : public Stmt { 1049 Stmt *Throw; 1050 SourceLocation AtThrowLoc; 1051public: 1052 ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) 1053 : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { 1054 AtThrowLoc = atThrowLoc; 1055 } 1056 1057 const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); } 1058 Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } 1059 1060 virtual SourceRange getSourceRange() const { 1061 if (Throw) 1062 return SourceRange(AtThrowLoc, Throw->getLocEnd()); 1063 else 1064 return SourceRange(AtThrowLoc); 1065 } 1066 1067 static bool classof(const Stmt *T) { 1068 return T->getStmtClass() == ObjCAtThrowStmtClass; 1069 } 1070 static bool classof(const ObjCAtThrowStmt *) { return true; } 1071 1072 virtual child_iterator child_begin(); 1073 virtual child_iterator child_end(); 1074 1075 virtual void EmitImpl(llvm::Serializer& S) const; 1076 static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C); 1077}; 1078 1079} // end namespace clang 1080 1081#endif 1082