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