Stmt.h revision edcc752060be38bfa7e7b32691c0cc4d843622a8
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 typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator; 127 reverse_body_iterator body_rbegin() { return Body.rbegin(); } 128 reverse_body_iterator body_rend() { return Body.rend(); } 129 130 typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator 131 const_reverse_body_iterator; 132 const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); } 133 const_reverse_body_iterator body_rend() const { return Body.rend(); } 134 135 void push_back(Stmt *S) { Body.push_back(S); } 136 137 static bool classof(const Stmt *T) { 138 return T->getStmtClass() == CompoundStmtClass; 139 } 140 static bool classof(const CompoundStmt *) { return true; } 141}; 142 143// SwitchCase is the base class for CaseStmt and DefaultStmt, 144class SwitchCase : public Stmt { 145 // A pointer to the following CaseStmt or DefaultStmt class, 146 // used by SwitchStmt. 147 SwitchCase *NextSwitchCase; 148 Stmt *SubStmt; 149protected: 150 SwitchCase(StmtClass SC, Stmt* substmt) : Stmt(SC), NextSwitchCase(0), 151 SubStmt(substmt) {} 152 153public: 154 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; } 155 156 SwitchCase *getNextSwitchCase() { return NextSwitchCase; } 157 158 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; } 159 160 Stmt *getSubStmt() { return SubStmt; } 161 162 static bool classof(const Stmt *T) { 163 return T->getStmtClass() == CaseStmtClass || 164 T->getStmtClass() == DefaultStmtClass; 165 } 166 static bool classof(const SwitchCase *) { return true; } 167}; 168 169class CaseStmt : public SwitchCase { 170 Expr *LHSVal; 171 Expr *RHSVal; // Non-null for GNU "case 1 ... 4" extension 172public: 173 CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt) 174 : SwitchCase(CaseStmtClass,substmt), LHSVal(lhs), RHSVal(rhs) {} 175 176 Expr *getLHS() { return LHSVal; } 177 Expr *getRHS() { return RHSVal; } 178 179 static bool classof(const Stmt *T) { 180 return T->getStmtClass() == CaseStmtClass; 181 } 182 static bool classof(const CaseStmt *) { return true; } 183}; 184 185class DefaultStmt : public SwitchCase { 186 SourceLocation DefaultLoc; 187public: 188 DefaultStmt(SourceLocation DL, Stmt *substmt) : 189 SwitchCase(DefaultStmtClass,substmt), DefaultLoc(DL) {} 190 191 SourceLocation getDefaultLoc() const { return DefaultLoc; } 192 193 static bool classof(const Stmt *T) { 194 return T->getStmtClass() == DefaultStmtClass; 195 } 196 static bool classof(const DefaultStmt *) { return true; } 197}; 198 199class LabelStmt : public Stmt { 200 SourceLocation IdentLoc; 201 IdentifierInfo *Label; 202 Stmt *SubStmt; 203public: 204 LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt) 205 : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {} 206 207 SourceLocation getIdentLoc() const { return IdentLoc; } 208 IdentifierInfo *getID() const { return Label; } 209 const char *getName() const; 210 Stmt *getSubStmt() { return SubStmt; } 211 const Stmt *getSubStmt() const { return SubStmt; } 212 213 void setIdentLoc(SourceLocation L) { IdentLoc = L; } 214 void setSubStmt(Stmt *SS) { SubStmt = SS; } 215 216 static bool classof(const Stmt *T) { 217 return T->getStmtClass() == LabelStmtClass; 218 } 219 static bool classof(const LabelStmt *) { return true; } 220}; 221 222 223/// IfStmt - This represents an if/then/else. 224/// 225class IfStmt : public Stmt { 226 Expr *Cond; 227 Stmt *Then, *Else; 228public: 229 IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0) 230 : Stmt(IfStmtClass), Cond(cond), Then(then), Else(elsev) {} 231 232 const Expr *getCond() const { return Cond; } 233 const Stmt *getThen() const { return Then; } 234 const Stmt *getElse() const { return Else; } 235 236 Expr *getCond() { return Cond; } 237 Stmt *getThen() { return Then; } 238 Stmt *getElse() { return Else; } 239 240 static bool classof(const Stmt *T) { 241 return T->getStmtClass() == IfStmtClass; 242 } 243 static bool classof(const IfStmt *) { return true; } 244}; 245 246/// SwitchStmt - This represents a 'switch' stmt. 247/// 248class SwitchStmt : public Stmt { 249 Expr *Cond; 250 Stmt *Body; 251 252 // This points to a linked list of case and default statements. 253 SwitchCase *FirstCase; 254public: 255 SwitchStmt(Expr *cond) 256 : Stmt(SwitchStmtClass), Cond(cond), Body(0), FirstCase(0) {} 257 258 const Expr *getCond() const { return Cond; } 259 const Stmt *getBody() const { return Body; } 260 const SwitchCase *getSwitchCaseList() const { return FirstCase; } 261 262 Expr *getCond() { return Cond; } 263 Stmt *getBody() { return Body; } 264 SwitchCase *getSwitchCaseList() { return FirstCase; } 265 266 void setBody(Stmt *S) { Body = S; } 267 268 void addSwitchCase(SwitchCase *SC) { 269 if (FirstCase) 270 SC->setNextSwitchCase(FirstCase); 271 272 FirstCase = SC; 273 } 274 275 static bool classof(const Stmt *T) { 276 return T->getStmtClass() == SwitchStmtClass; 277 } 278 static bool classof(const SwitchStmt *) { return true; } 279}; 280 281 282/// WhileStmt - This represents a 'while' stmt. 283/// 284class WhileStmt : public Stmt { 285 Expr *Cond; 286 Stmt *Body; 287public: 288 WhileStmt(Expr *cond, Stmt *body) 289 : Stmt(WhileStmtClass), Cond(cond), Body(body) {} 290 291 Expr *getCond() { return Cond; } 292 const Expr *getCond() const { return Cond; } 293 Stmt *getBody() { return Body; } 294 const Stmt *getBody() const { return Body; } 295 296 static bool classof(const Stmt *T) { 297 return T->getStmtClass() == WhileStmtClass; 298 } 299 static bool classof(const WhileStmt *) { return true; } 300}; 301 302/// DoStmt - This represents a 'do/while' stmt. 303/// 304class DoStmt : public Stmt { 305 Stmt *Body; 306 Expr *Cond; 307public: 308 DoStmt(Stmt *body, Expr *cond) 309 : Stmt(DoStmtClass), Body(body), Cond(cond) {} 310 311 Stmt *getBody() { return Body; } 312 const Stmt *getBody() const { return Body; } 313 Expr *getCond() { return Cond; } 314 const Expr *getCond() const { return Cond; } 315 316 static bool classof(const Stmt *T) { 317 return T->getStmtClass() == DoStmtClass; 318 } 319 static bool classof(const DoStmt *) { return true; } 320}; 321 322 323/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of 324/// the init/cond/inc parts of the ForStmt will be null if they were not 325/// specified in the source. 326/// 327class ForStmt : public Stmt { 328 Stmt *Init; // Expression or declstmt. 329 Expr *Cond, *Inc; 330 Stmt *Body; 331public: 332 ForStmt(Stmt *init, Expr *cond, Expr *inc, Stmt *body) 333 : Stmt(ForStmtClass), Init(init), Cond(cond), Inc(inc), Body(body) {} 334 335 Stmt *getInit() { return Init; } 336 Expr *getCond() { return Cond; } 337 Expr *getInc() { return Inc; } 338 Stmt *getBody() { return Body; } 339 340 const Stmt *getInit() const { return Init; } 341 const Expr *getCond() const { return Cond; } 342 const Expr *getInc() const { return Inc; } 343 const Stmt *getBody() const { return Body; } 344 345 static bool classof(const Stmt *T) { 346 return T->getStmtClass() == ForStmtClass; 347 } 348 static bool classof(const ForStmt *) { return true; } 349}; 350 351/// GotoStmt - This represents a direct goto. 352/// 353class GotoStmt : public Stmt { 354 LabelStmt *Label; 355public: 356 GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {} 357 358 LabelStmt *getLabel() const { return Label; } 359 360 static bool classof(const Stmt *T) { 361 return T->getStmtClass() == GotoStmtClass; 362 } 363 static bool classof(const GotoStmt *) { return true; } 364}; 365 366/// IndirectGotoStmt - This represents an indirect goto. 367/// 368class IndirectGotoStmt : public Stmt { 369 Expr *Target; 370public: 371 IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass), Target(target){} 372 373 Expr *getTarget() { return Target; } 374 const Expr *getTarget() const { return Target; } 375 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 static bool classof(const Stmt *T) { 389 return T->getStmtClass() == ContinueStmtClass; 390 } 391 static bool classof(const ContinueStmt *) { return true; } 392}; 393 394/// BreakStmt - This represents a break. 395/// 396class BreakStmt : public Stmt { 397public: 398 BreakStmt() : Stmt(BreakStmtClass) {} 399 static bool classof(const Stmt *T) { 400 return T->getStmtClass() == BreakStmtClass; 401 } 402 static bool classof(const BreakStmt *) { return true; } 403}; 404 405 406/// ReturnStmt - This represents a return, optionally of an expression. 407/// 408class ReturnStmt : public Stmt { 409 Expr *RetExpr; 410public: 411 ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {} 412 413 const Expr *getRetValue() const { return RetExpr; } 414 Expr *getRetValue() { return RetExpr; } 415 416 static bool classof(const Stmt *T) { 417 return T->getStmtClass() == ReturnStmtClass; 418 } 419 static bool classof(const ReturnStmt *) { return true; } 420}; 421 422} // end namespace clang 423 424#endif 425