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