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