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