Stmt.h revision 0c727a35718556866a978f64ac549d9798735f08
1//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source 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 "clang/Basic/SourceLocation.h" 18#include "llvm/ADT/SmallVector.h" 19#include "llvm/ADT/iterator" 20#include <iosfwd> 21 22namespace clang { 23 class Expr; 24 class Decl; 25 class IdentifierInfo; 26 class SourceManager; 27 class SwitchStmt; 28 29/// Stmt - This represents one statement. 30/// 31class Stmt { 32public: 33 enum StmtClass { 34#define STMT(N, CLASS, PARENT) CLASS##Class = N, 35#define FIRST_STMT(N) firstStmtConstant = N, 36#define LAST_STMT(N) lastStmtConstant = N, 37#define FIRST_EXPR(N) firstExprConstant = N, 38#define LAST_EXPR(N) lastExprConstant = N 39#include "clang/AST/StmtNodes.def" 40}; 41private: 42 const StmtClass sClass; 43public: 44 Stmt(StmtClass SC) : sClass(SC) { 45 if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); 46 } 47 virtual ~Stmt() {} 48 49 StmtClass getStmtClass() const { return sClass; } 50 const char *getStmtClassName() const; 51 52 // global temp stats (until we have a per-module visitor) 53 static void addStmtClass(const StmtClass s); 54 static bool CollectingStats(bool enable=false); 55 static void PrintStats(); 56 57 /// dump - This does a local dump of the specified AST fragment. It dumps the 58 /// specified node and a few nodes underneath it, but not the whole subtree. 59 /// This is useful in a debugger. 60 void dump() const; 61 void dump(const SourceManager &SM) const; 62 63 /// dumpAll - This does a dump of the specified AST fragment and all subtrees. 64 void dumpAll() const; 65 void dumpAll(const SourceManager &SM) const; 66 67 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST 68 /// back to its original source language syntax. 69 void dumpPretty() const; 70 void printPretty(std::ostream &OS) const; 71 72 // Implement isa<T> support. 73 static bool classof(const Stmt *) { return true; } 74 75 /// Child Iterators: All subclasses must implement child_begin and child_end 76 /// to permit easy iteration over the substatements/subexpessions of an 77 /// AST node. This permits easy iteration over all nodes in the AST. 78 typedef Stmt** child_iterator; 79 typedef Stmt* const * const_child_iterator; 80 81 typedef std::reverse_iterator<child_iterator> 82 reverse_child_iterator; 83 typedef std::reverse_iterator<const_child_iterator> 84 const_reverse_child_iterator; 85 86 virtual child_iterator child_begin() = 0; 87 virtual child_iterator child_end() = 0; 88 89 const_child_iterator child_begin() const { 90 return (child_iterator) const_cast<Stmt*>(this)->child_begin(); 91 } 92 93 const_child_iterator child_end() const { 94 return (child_iterator) const_cast<Stmt*>(this)->child_end(); 95 } 96 97 reverse_child_iterator child_rbegin() { 98 return reverse_child_iterator(child_end()); 99 } 100 101 reverse_child_iterator child_rend() { 102 return reverse_child_iterator(child_begin()); 103 } 104 105 const_reverse_child_iterator child_rbegin() const { 106 return const_reverse_child_iterator(child_end()); 107 } 108 109 const_reverse_child_iterator child_rend() const { 110 return const_reverse_child_iterator(child_begin()); 111 } 112}; 113 114/// DeclStmt - Adaptor class for mixing declarations with statements and 115/// expressions. For example, CompoundStmt mixes statements, expressions 116/// and declarations (variables, types). Another example is ForStmt, where 117/// the first statement can be an expression or a declaration. 118/// 119class DeclStmt : public Stmt { 120 Decl *TheDecl; 121public: 122 DeclStmt(Decl *D) : Stmt(DeclStmtClass), TheDecl(D) {} 123 124 const Decl *getDecl() const { return TheDecl; } 125 Decl *getDecl() { return TheDecl; } 126 127 static bool classof(const Stmt *T) { 128 return T->getStmtClass() == DeclStmtClass; 129 } 130 static bool classof(const DeclStmt *) { return true; } 131 132 // Iterators 133 virtual child_iterator child_begin(); 134 virtual child_iterator child_end(); 135}; 136 137/// NullStmt - This is the null statement ";": C99 6.8.3p3. 138/// 139class NullStmt : public Stmt { 140 SourceLocation SemiLoc; 141public: 142 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 143 144 SourceLocation getSemiLoc() const { return SemiLoc; } 145 146 static bool classof(const Stmt *T) { 147 return T->getStmtClass() == NullStmtClass; 148 } 149 static bool classof(const NullStmt *) { return true; } 150 151 // Iterators 152 virtual child_iterator child_begin(); 153 virtual child_iterator child_end(); 154}; 155 156/// CompoundStmt - This represents a group of statements like { stmt stmt }. 157/// 158class CompoundStmt : public Stmt { 159 llvm::SmallVector<Stmt*, 16> Body; 160public: 161 CompoundStmt(Stmt **StmtStart, unsigned NumStmts) 162 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts) {} 163 164 bool body_empty() const { return Body.empty(); } 165 166 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 167 body_iterator body_begin() { return Body.begin(); } 168 body_iterator body_end() { return Body.end(); } 169 Stmt *body_back() { return Body.back(); } 170 171 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 172 const_body_iterator body_begin() const { return Body.begin(); } 173 const_body_iterator body_end() const { return Body.end(); } 174 const Stmt *body_back() const { return Body.back(); } 175 176 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 177 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 178 reverse_body_iterator body_rend() { return Body.rend(); } 179 180 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 181 const_reverse_body_iterator; 182 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 183 const_reverse_body_iterator body_rend() const { return Body.rend(); } 184 185 void push_back(Stmt *S) { Body.push_back(S); } 186 187 static bool classof(const Stmt *T) { 188 return T->getStmtClass() == CompoundStmtClass; 189 } 190 static bool classof(const CompoundStmt *) { return true; } 191 192 // Iterators 193 virtual child_iterator child_begin(); 194 virtual child_iterator child_end(); 195}; 196 197// SwitchCase is the base class for CaseStmt and DefaultStmt, 198class SwitchCase : public Stmt { 199 // A pointer to the following CaseStmt or DefaultStmt class, 200 // used by SwitchStmt. 201 SwitchCase *NextSwitchCase; 202 Stmt *SubStmt; 203protected: 204 SwitchCase(StmtClass SC, Stmt* substmt) : Stmt(SC), NextSwitchCase(0), 205 SubStmt(substmt) {} 206 207public: 208 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 209 210 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 211 212 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 213 214 Stmt *getSubStmt() { return SubStmt; } 215 216 static bool classof(const Stmt *T) { 217 return T->getStmtClass() == CaseStmtClass || 218 T->getStmtClass() == DefaultStmtClass; 219 } 220 static bool classof(const SwitchCase *) { return true; } 221 222 // Iterators 223 virtual child_iterator child_begin(); 224 virtual child_iterator child_end(); 225}; 226 227class CaseStmt : public SwitchCase { 228 Expr *LHSVal; 229 Expr *RHSVal; // Non-null for GNU "case 1 ... 4" extension 230public: 231 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt) 232 : SwitchCase(CaseStmtClass,substmt), LHSVal(lhs), RHSVal(rhs) {} 233 234 Expr *getLHS() { return LHSVal; } 235 Expr *getRHS() { return RHSVal; } 236 237 static bool classof(const Stmt *T) { 238 return T->getStmtClass() == CaseStmtClass; 239 } 240 static bool classof(const CaseStmt *) { return true; } 241}; 242 243class DefaultStmt : public SwitchCase { 244 SourceLocation DefaultLoc; 245public: 246 DefaultStmt(SourceLocation DL, Stmt *substmt) : 247 SwitchCase(DefaultStmtClass,substmt), DefaultLoc(DL) {} 248 249 SourceLocation getDefaultLoc() const { return DefaultLoc; } 250 251 static bool classof(const Stmt *T) { 252 return T->getStmtClass() == DefaultStmtClass; 253 } 254 static bool classof(const DefaultStmt *) { return true; } 255}; 256 257class LabelStmt : public Stmt { 258 SourceLocation IdentLoc; 259 IdentifierInfo *Label; 260 Stmt *SubStmt; 261public: 262 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 263 : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {} 264 265 SourceLocation getIdentLoc() const { return IdentLoc; } 266 IdentifierInfo *getID() const { return Label; } 267 const char *getName() const; 268 Stmt *getSubStmt() { return SubStmt; } 269 const Stmt *getSubStmt() const { return SubStmt; } 270 271 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 272 void setSubStmt(Stmt *SS) { SubStmt = SS; } 273 274 static bool classof(const Stmt *T) { 275 return T->getStmtClass() == LabelStmtClass; 276 } 277 static bool classof(const LabelStmt *) { return true; } 278 279 // Iterators 280 virtual child_iterator child_begin(); 281 virtual child_iterator child_end(); 282}; 283 284 285/// IfStmt - This represents an if/then/else. 286/// 287class IfStmt : public Stmt { 288 enum { COND, THEN, ELSE, END_EXPR }; 289 Stmt* SubExprs[END_EXPR]; 290public: 291 IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0) : Stmt(IfStmtClass) { 292 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 293 SubExprs[THEN] = then; 294 SubExprs[ELSE] = elsev; 295 } 296 297 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 298 const Stmt *getThen() const { return SubExprs[THEN]; } 299 const Stmt *getElse() const { return SubExprs[ELSE]; } 300 301 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 302 Stmt *getThen() { return SubExprs[THEN]; } 303 Stmt *getElse() { return SubExprs[ELSE]; } 304 305 static bool classof(const Stmt *T) { 306 return T->getStmtClass() == IfStmtClass; 307 } 308 static bool classof(const IfStmt *) { return true; } 309 310 // Iterators 311 virtual child_iterator child_begin(); 312 virtual child_iterator child_end(); 313}; 314 315/// SwitchStmt - This represents a 'switch' stmt. 316/// 317class SwitchStmt : public Stmt { 318 enum { COND, BODY, END_EXPR }; 319 Stmt* SubExprs[END_EXPR]; 320 // This points to a linked list of case and default statements. 321 SwitchCase *FirstCase; 322public: 323 SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) { 324 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 325 SubExprs[BODY] = NULL; 326 } 327 328 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 329 const Stmt *getBody() const { return SubExprs[BODY]; } 330 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 331 332 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} 333 Stmt *getBody() { return SubExprs[BODY]; } 334 SwitchCase *getSwitchCaseList() { return FirstCase; } 335 336 void setBody(Stmt *S) { SubExprs[BODY] = S; } 337 338 void addSwitchCase(SwitchCase *SC) { 339 if (FirstCase) 340 SC->setNextSwitchCase(FirstCase); 341 342 FirstCase = SC; 343 } 344 345 static bool classof(const Stmt *T) { 346 return T->getStmtClass() == SwitchStmtClass; 347 } 348 static bool classof(const SwitchStmt *) { return true; } 349 350 // Iterators 351 virtual child_iterator child_begin(); 352 virtual child_iterator child_end(); 353}; 354 355 356/// WhileStmt - This represents a 'while' stmt. 357/// 358class WhileStmt : public Stmt { 359 enum { COND, BODY, END_EXPR }; 360 Stmt* SubExprs[END_EXPR]; 361public: 362 WhileStmt(Expr *cond, Stmt *body) : Stmt(WhileStmtClass) { 363 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 364 SubExprs[BODY] = body; 365 } 366 367 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 368 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 369 Stmt *getBody() { return SubExprs[BODY]; } 370 const Stmt *getBody() const { return SubExprs[BODY]; } 371 372 static bool classof(const Stmt *T) { 373 return T->getStmtClass() == WhileStmtClass; 374 } 375 static bool classof(const WhileStmt *) { return true; } 376 377 // Iterators 378 virtual child_iterator child_begin(); 379 virtual child_iterator child_end(); 380}; 381 382/// DoStmt - This represents a 'do/while' stmt. 383/// 384class DoStmt : public Stmt { 385 enum { COND, BODY, END_EXPR }; 386 Stmt* SubExprs[END_EXPR]; 387public: 388 DoStmt(Stmt *body, Expr *cond) : Stmt(DoStmtClass) { 389 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 390 SubExprs[BODY] = body; 391 } 392 393 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 394 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 395 Stmt *getBody() { return SubExprs[BODY]; } 396 const Stmt *getBody() const { return SubExprs[BODY]; } 397 398 static bool classof(const Stmt *T) { 399 return T->getStmtClass() == DoStmtClass; 400 } 401 static bool classof(const DoStmt *) { return true; } 402 403 // Iterators 404 virtual child_iterator child_begin(); 405 virtual child_iterator child_end(); 406}; 407 408 409/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 410/// the init/cond/inc parts of the ForStmt will be null if they were not 411/// specified in the source. 412/// 413class ForStmt : public Stmt { 414 enum { INIT, COND, INC, BODY, END_EXPR }; 415 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. 416public: 417 ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body) : Stmt(ForStmtClass) { 418 SubExprs[INIT] = Init; 419 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 420 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 421 SubExprs[BODY] = Body; 422 } 423 424 Stmt *getInit() { return SubExprs[INIT]; } 425 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } 426 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); } 427 Stmt *getBody() { return SubExprs[BODY]; } 428 429 const Stmt *getInit() const { return SubExprs[INIT]; } 430 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} 431 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); } 432 const Stmt *getBody() const { return SubExprs[BODY]; } 433 434 static bool classof(const Stmt *T) { 435 return T->getStmtClass() == ForStmtClass; 436 } 437 static bool classof(const ForStmt *) { return true; } 438 439 // Iterators 440 virtual child_iterator child_begin(); 441 virtual child_iterator child_end(); 442}; 443 444/// GotoStmt - This represents a direct goto. 445/// 446class GotoStmt : public Stmt { 447 LabelStmt *Label; 448public: 449 GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {} 450 451 LabelStmt *getLabel() const { return Label; } 452 453 static bool classof(const Stmt *T) { 454 return T->getStmtClass() == GotoStmtClass; 455 } 456 static bool classof(const GotoStmt *) { return true; } 457 458 // Iterators 459 virtual child_iterator child_begin(); 460 virtual child_iterator child_end(); 461}; 462 463/// IndirectGotoStmt - This represents an indirect goto. 464/// 465class IndirectGotoStmt : public Stmt { 466 Expr *Target; 467public: 468 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 469 470 Expr *getTarget() { return Target; } 471 const Expr *getTarget() const { return Target; } 472 473 static bool classof(const Stmt *T) { 474 return T->getStmtClass() == IndirectGotoStmtClass; 475 } 476 static bool classof(const IndirectGotoStmt *) { return true; } 477 478 // Iterators 479 virtual child_iterator child_begin(); 480 virtual child_iterator child_end(); 481}; 482 483 484/// ContinueStmt - This represents a continue. 485/// 486class ContinueStmt : public Stmt { 487public: 488 ContinueStmt() : Stmt(ContinueStmtClass) {} 489 static bool classof(const Stmt *T) { 490 return T->getStmtClass() == ContinueStmtClass; 491 } 492 static bool classof(const ContinueStmt *) { return true; } 493 494 // Iterators 495 virtual child_iterator child_begin(); 496 virtual child_iterator child_end(); 497}; 498 499/// BreakStmt - This represents a break. 500/// 501class BreakStmt : public Stmt { 502public: 503 BreakStmt() : Stmt(BreakStmtClass) {} 504 static bool classof(const Stmt *T) { 505 return T->getStmtClass() == BreakStmtClass; 506 } 507 static bool classof(const BreakStmt *) { return true; } 508 509 // Iterators 510 virtual child_iterator child_begin(); 511 virtual child_iterator child_end(); 512}; 513 514 515/// ReturnStmt - This represents a return, optionally of an expression. 516/// 517class ReturnStmt : public Stmt { 518 Expr *RetExpr; 519public: 520 ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {} 521 522 const Expr *getRetValue() const { return RetExpr; } 523 Expr *getRetValue() { return RetExpr; } 524 525 static bool classof(const Stmt *T) { 526 return T->getStmtClass() == ReturnStmtClass; 527 } 528 static bool classof(const ReturnStmt *) { return true; } 529 530 // Iterators 531 virtual child_iterator child_begin(); 532 virtual child_iterator child_end(); 533}; 534 535} // end namespace clang 536 537#endif 538