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