Stmt.h revision 6000dace22f110d8768476989313e9d981d690d0
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 <iosfwd> 20 21namespace clang { 22 class Expr; 23 class Decl; 24 class IdentifierInfo; 25 class StmtVisitor; 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 visitor support. 70 virtual void visit(StmtVisitor &Visitor); 71 72 // Implement isa<T> support. 73 static bool classof(const Stmt *) { return true; } 74}; 75 76/// DeclStmt - Adaptor class for mixing declarations with statements and 77/// expressions. For example, CompoundStmt mixes statements, expressions 78/// and declarations (variables, types). Another example is ForStmt, where 79/// the first statement can be an expression or a declaration. 80/// 81class DeclStmt : public Stmt { 82 Decl *TheDecl; 83public: 84 DeclStmt(Decl *D) : Stmt(DeclStmtClass), TheDecl(D) {} 85 86 const Decl *getDecl() const { return TheDecl; } 87 Decl *getDecl() { return TheDecl; } 88 89 virtual void visit(StmtVisitor &Visitor); 90 static bool classof(const Stmt *T) { 91 return T->getStmtClass() == DeclStmtClass; 92 } 93 static bool classof(const DeclStmt *) { return true; } 94}; 95 96/// NullStmt - This is the null statement ";": C99 6.8.3p3. 97/// 98class NullStmt : public Stmt { 99 SourceLocation SemiLoc; 100public: 101 NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} 102 103 SourceLocation getSemiLoc() const { return SemiLoc; } 104 105 virtual void visit(StmtVisitor &Visitor); 106 static bool classof(const Stmt *T) { 107 return T->getStmtClass() == NullStmtClass; 108 } 109 static bool classof(const NullStmt *) { return true; } 110}; 111 112/// CompoundStmt - This represents a group of statements like { stmt stmt }. 113/// 114class CompoundStmt : public Stmt { 115 llvm::SmallVector<Stmt*, 16> Body; 116public: 117 CompoundStmt(Stmt **StmtStart, unsigned NumStmts) 118 : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts) {} 119 120 bool body_empty() const { return Body.empty(); } 121 122 typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator; 123 body_iterator body_begin() { return Body.begin(); } 124 body_iterator body_end() { return Body.end(); } 125 Stmt *body_back() { return Body.back(); } 126 127 typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator; 128 const_body_iterator body_begin() const { return Body.begin(); } 129 const_body_iterator body_end() const { return Body.end(); } 130 const Stmt *body_back() const { return Body.back(); } 131 132 void push_back(Stmt *S) { Body.push_back(S); } 133 134 virtual void visit(StmtVisitor &Visitor); 135 static bool classof(const Stmt *T) { 136 return T->getStmtClass() == CompoundStmtClass; 137 } 138 static bool classof(const CompoundStmt *) { return true; } 139}; 140 141// SwitchCase is the base class for CaseStmt and DefaultStmt, 142class SwitchCase : public Stmt { 143 // A pointer to the following CaseStmt or DefaultStmt class, 144 // used by SwitchStmt. 145 SwitchCase *NextSwitchCase; 146protected: 147 SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {} 148 149public: 150 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 151 152 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 153 154 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 155 156 static bool classof(const Stmt *T) { 157 return T->getStmtClass() == CaseStmtClass || 158 T->getStmtClass() == DefaultStmtClass; 159 } 160 static bool classof(const SwitchCase *) { return true; } 161 162 virtual void visit(StmtVisitor &Visitor) = 0; 163}; 164 165class CaseStmt : public SwitchCase { 166 Expr *LHSVal; 167 Expr *RHSVal; // Non-null for GNU "case 1 ... 4" extension 168 Stmt *SubStmt; 169public: 170 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt) 171 : SwitchCase(CaseStmtClass), LHSVal(lhs), RHSVal(rhs), SubStmt(substmt) {} 172 173 Expr *getLHS() { return LHSVal; } 174 Expr *getRHS() { return RHSVal; } 175 Stmt *getSubStmt() { return SubStmt; } 176 177 virtual void visit(StmtVisitor &Visitor); 178 static bool classof(const Stmt *T) { 179 return T->getStmtClass() == CaseStmtClass; 180 } 181 static bool classof(const CaseStmt *) { return true; } 182}; 183 184class DefaultStmt : public SwitchCase { 185 SourceLocation DefaultLoc; 186 Stmt *SubStmt; 187public: 188 DefaultStmt(SourceLocation DL, Stmt *substmt) : SwitchCase(DefaultStmtClass), 189 DefaultLoc(DL), SubStmt(substmt) {} 190 191 SourceLocation getDefaultLoc() const { return DefaultLoc; } 192 Stmt *getSubStmt() { return SubStmt; } 193 194 virtual void visit(StmtVisitor &Visitor); 195 static bool classof(const Stmt *T) { 196 return T->getStmtClass() == DefaultStmtClass; 197 } 198 static bool classof(const DefaultStmt *) { return true; } 199}; 200 201class LabelStmt : public Stmt { 202 SourceLocation IdentLoc; 203 IdentifierInfo *Label; 204 Stmt *SubStmt; 205public: 206 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 207 : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {} 208 209 SourceLocation getIdentLoc() const { return IdentLoc; } 210 IdentifierInfo *getID() const { return Label; } 211 const char *getName() const; 212 Stmt *getSubStmt() { return SubStmt; } 213 const Stmt *getSubStmt() const { return SubStmt; } 214 215 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 216 void setSubStmt(Stmt *SS) { SubStmt = SS; } 217 218 virtual void visit(StmtVisitor &Visitor); 219 static bool classof(const Stmt *T) { 220 return T->getStmtClass() == LabelStmtClass; 221 } 222 static bool classof(const LabelStmt *) { return true; } 223}; 224 225 226/// IfStmt - This represents an if/then/else. 227/// 228class IfStmt : public Stmt { 229 Expr *Cond; 230 Stmt *Then, *Else; 231public: 232 IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0) 233 : Stmt(IfStmtClass), Cond(cond), Then(then), Else(elsev) {} 234 235 const Expr *getCond() const { return Cond; } 236 const Stmt *getThen() const { return Then; } 237 const Stmt *getElse() const { return Else; } 238 239 Expr *getCond() { return Cond; } 240 Stmt *getThen() { return Then; } 241 Stmt *getElse() { return Else; } 242 243 virtual void visit(StmtVisitor &Visitor); 244 static bool classof(const Stmt *T) { 245 return T->getStmtClass() == IfStmtClass; 246 } 247 static bool classof(const IfStmt *) { return true; } 248}; 249 250/// SwitchStmt - This represents a 'switch' stmt. 251/// 252class SwitchStmt : public Stmt { 253 Expr *Cond; 254 Stmt *Body; 255 256 // This points to a linked list of case and default statements. 257 SwitchCase *FirstCase; 258public: 259 SwitchStmt(Expr *cond) 260 : Stmt(SwitchStmtClass), Cond(cond), Body(0), FirstCase(0) {} 261 262 const Expr *getCond() const { return Cond; } 263 const Stmt *getBody() const { return Body; } 264 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 265 266 Expr *getCond() { return Cond; } 267 Stmt *getBody() { return Body; } 268 SwitchCase *getSwitchCaseList() { return FirstCase; } 269 270 void setBody(Stmt *S) { Body = S; } 271 272 void addSwitchCase(SwitchCase *SC) { 273 if (FirstCase) 274 SC->setNextSwitchCase(FirstCase); 275 276 FirstCase = SC; 277 } 278 279 virtual void visit(StmtVisitor &Visitor); 280 static bool classof(const Stmt *T) { 281 return T->getStmtClass() == SwitchStmtClass; 282 } 283 static bool classof(const SwitchStmt *) { return true; } 284}; 285 286 287/// WhileStmt - This represents a 'while' stmt. 288/// 289class WhileStmt : public Stmt { 290 Expr *Cond; 291 Stmt *Body; 292public: 293 WhileStmt(Expr *cond, Stmt *body) 294 : Stmt(WhileStmtClass), Cond(cond), Body(body) {} 295 296 Expr *getCond() { return Cond; } 297 const Expr *getCond() const { return Cond; } 298 Stmt *getBody() { return Body; } 299 const Stmt *getBody() const { return Body; } 300 301 virtual void visit(StmtVisitor &Visitor); 302 static bool classof(const Stmt *T) { 303 return T->getStmtClass() == WhileStmtClass; 304 } 305 static bool classof(const WhileStmt *) { return true; } 306}; 307 308/// DoStmt - This represents a 'do/while' stmt. 309/// 310class DoStmt : public Stmt { 311 Stmt *Body; 312 Expr *Cond; 313public: 314 DoStmt(Stmt *body, Expr *cond) 315 : Stmt(DoStmtClass), Body(body), Cond(cond) {} 316 317 Stmt *getBody() { return Body; } 318 const Stmt *getBody() const { return Body; } 319 Expr *getCond() { return Cond; } 320 const Expr *getCond() const { return Cond; } 321 322 virtual void visit(StmtVisitor &Visitor); 323 static bool classof(const Stmt *T) { 324 return T->getStmtClass() == DoStmtClass; 325 } 326 static bool classof(const DoStmt *) { return true; } 327}; 328 329 330/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 331/// the init/cond/inc parts of the ForStmt will be null if they were not 332/// specified in the source. 333/// 334class ForStmt : public Stmt { 335 Stmt *Init; // Expression or declstmt. 336 Expr *Cond, *Inc; 337 Stmt *Body; 338public: 339 ForStmt(Stmt *init, Expr *cond, Expr *inc, Stmt *body) 340 : Stmt(ForStmtClass), Init(init), Cond(cond), Inc(inc), Body(body) {} 341 342 Stmt *getInit() { return Init; } 343 Expr *getCond() { return Cond; } 344 Expr *getInc() { return Inc; } 345 Stmt *getBody() { return Body; } 346 347 const Stmt *getInit() const { return Init; } 348 const Expr *getCond() const { return Cond; } 349 const Expr *getInc() const { return Inc; } 350 const Stmt *getBody() const { return Body; } 351 352 virtual void visit(StmtVisitor &Visitor); 353 static bool classof(const Stmt *T) { 354 return T->getStmtClass() == ForStmtClass; 355 } 356 static bool classof(const ForStmt *) { return true; } 357}; 358 359/// GotoStmt - This represents a direct goto. 360/// 361class GotoStmt : public Stmt { 362 LabelStmt *Label; 363public: 364 GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {} 365 366 LabelStmt *getLabel() const { return Label; } 367 368 virtual void visit(StmtVisitor &Visitor); 369 static bool classof(const Stmt *T) { 370 return T->getStmtClass() == GotoStmtClass; 371 } 372 static bool classof(const GotoStmt *) { return true; } 373}; 374 375/// IndirectGotoStmt - This represents an indirect goto. 376/// 377class IndirectGotoStmt : public Stmt { 378 Expr *Target; 379public: 380 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 381 382 Expr *getTarget() { return Target; } 383 const Expr *getTarget() const { return Target; } 384 385 virtual void visit(StmtVisitor &Visitor); 386 static bool classof(const Stmt *T) { 387 return T->getStmtClass() == IndirectGotoStmtClass; 388 } 389 static bool classof(const IndirectGotoStmt *) { return true; } 390}; 391 392 393/// ContinueStmt - This represents a continue. 394/// 395class ContinueStmt : public Stmt { 396public: 397 ContinueStmt() : Stmt(ContinueStmtClass) {} 398 virtual void visit(StmtVisitor &Visitor); 399 static bool classof(const Stmt *T) { 400 return T->getStmtClass() == ContinueStmtClass; 401 } 402 static bool classof(const ContinueStmt *) { return true; } 403}; 404 405/// BreakStmt - This represents a break. 406/// 407class BreakStmt : public Stmt { 408public: 409 BreakStmt() : Stmt(BreakStmtClass) {} 410 virtual void visit(StmtVisitor &Visitor); 411 static bool classof(const Stmt *T) { 412 return T->getStmtClass() == BreakStmtClass; 413 } 414 static bool classof(const BreakStmt *) { return true; } 415}; 416 417 418/// ReturnStmt - This represents a return, optionally of an expression. 419/// 420class ReturnStmt : public Stmt { 421 Expr *RetExpr; 422public: 423 ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {} 424 425 const Expr *getRetValue() const { return RetExpr; } 426 Expr *getRetValue() { return RetExpr; } 427 428 virtual void visit(StmtVisitor &Visitor); 429 static bool classof(const Stmt *T) { 430 return T->getStmtClass() == ReturnStmtClass; 431 } 432 static bool classof(const ReturnStmt *) { return true; } 433}; 434 435} // end namespace clang 436 437#endif 438