Stmt.cpp revision f494b579b22f9950f5af021f0bf9879a91bb8b41
1//===--- Stmt.cpp - Statement AST Node Implementation ---------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the Stmt class and statement subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/Stmt.h" 15#include "clang/AST/ExprCXX.h" 16#include "clang/AST/ExprObjC.h" 17#include "clang/AST/StmtVisitor.h" 18#include "clang/Basic/IdentifierTable.h" 19using namespace clang; 20 21static struct StmtClassNameTable { 22 const char *Name; 23 unsigned Counter; 24 unsigned Size; 25} StmtClassInfo[Stmt::lastExprConstant+1]; 26 27static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) { 28 static bool Initialized = false; 29 if (Initialized) 30 return StmtClassInfo[E]; 31 32 // Intialize the table on the first use. 33 Initialized = true; 34#define STMT(N, CLASS, PARENT) \ 35 StmtClassInfo[N].Name = #CLASS; \ 36 StmtClassInfo[N].Size = sizeof(CLASS); 37#include "clang/AST/StmtNodes.def" 38 39 return StmtClassInfo[E]; 40} 41 42const char *Stmt::getStmtClassName() const { 43 return getStmtInfoTableEntry(sClass).Name; 44} 45 46void Stmt::DestroyChildren(ASTContext& C) { 47 for (child_iterator I = child_begin(), E = child_end(); I !=E; ++I) 48 if (Stmt* Child = *I) Child->Destroy(C); 49} 50 51void Stmt::Destroy(ASTContext& C) { 52 DestroyChildren(C); 53 // FIXME: Eventually all Stmts should be allocated with the allocator 54 // in ASTContext, just like with Decls. 55 // this->~Stmt(); 56 delete this; 57} 58 59void DeclStmt::Destroy(ASTContext& C) { 60 TheDecl->Destroy(C); 61 delete this; 62} 63 64void Stmt::PrintStats() { 65 // Ensure the table is primed. 66 getStmtInfoTableEntry(Stmt::NullStmtClass); 67 68 unsigned sum = 0; 69 fprintf(stderr, "*** Stmt/Expr Stats:\n"); 70 for (int i = 0; i != Stmt::lastExprConstant+1; i++) { 71 if (StmtClassInfo[i].Name == 0) continue; 72 sum += StmtClassInfo[i].Counter; 73 } 74 fprintf(stderr, " %d stmts/exprs total.\n", sum); 75 sum = 0; 76 for (int i = 0; i != Stmt::lastExprConstant+1; i++) { 77 if (StmtClassInfo[i].Name == 0) continue; 78 fprintf(stderr, " %d %s, %d each (%d bytes)\n", 79 StmtClassInfo[i].Counter, StmtClassInfo[i].Name, 80 StmtClassInfo[i].Size, 81 StmtClassInfo[i].Counter*StmtClassInfo[i].Size); 82 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size; 83 } 84 fprintf(stderr, "Total bytes = %d\n", sum); 85} 86 87void Stmt::addStmtClass(StmtClass s) { 88 ++getStmtInfoTableEntry(s).Counter; 89} 90 91static bool StatSwitch = false; 92 93bool Stmt::CollectingStats(bool enable) { 94 if (enable) StatSwitch = true; 95 return StatSwitch; 96} 97 98 99const char *LabelStmt::getName() const { 100 return getID()->getName(); 101} 102 103// This is defined here to avoid polluting Stmt.h with importing Expr.h 104SourceRange ReturnStmt::getSourceRange() const { 105 if (RetExpr) 106 return SourceRange(RetLoc, RetExpr->getLocEnd()); 107 else 108 return SourceRange(RetLoc); 109} 110 111bool Stmt::hasImplicitControlFlow() const { 112 switch (sClass) { 113 default: 114 return false; 115 116 case CallExprClass: 117 case ConditionalOperatorClass: 118 case ChooseExprClass: 119 case StmtExprClass: 120 case DeclStmtClass: 121 return true; 122 123 case Stmt::BinaryOperatorClass: { 124 const BinaryOperator* B = cast<BinaryOperator>(this); 125 if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma) 126 return true; 127 else 128 return false; 129 } 130 } 131} 132 133//===----------------------------------------------------------------------===// 134// Constructors 135//===----------------------------------------------------------------------===// 136 137AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 138 unsigned numoutputs, unsigned numinputs, 139 std::string *names, StringLiteral **constraints, 140 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 141 StringLiteral **clobbers, SourceLocation rparenloc) 142 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr) 143 , IsSimple(issimple), IsVolatile(isvolatile) 144 , NumOutputs(numoutputs), NumInputs(numinputs) { 145 for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) { 146 Names.push_back(names[i]); 147 Exprs.push_back(exprs[i]); 148 Constraints.push_back(constraints[i]); 149 } 150 151 for (unsigned i = 0; i != numclobbers; i++) 152 Clobbers.push_back(clobbers[i]); 153} 154 155ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, 156 Stmt *Body, SourceLocation FCL, 157 SourceLocation RPL) 158: Stmt(ObjCForCollectionStmtClass) { 159 SubExprs[ELEM] = Elem; 160 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect); 161 SubExprs[BODY] = Body; 162 ForLoc = FCL; 163 RParenLoc = RPL; 164} 165 166 167ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc, 168 SourceLocation rparenloc, 169 Stmt *catchVarStmtDecl, Stmt *atCatchStmt, 170 Stmt *atCatchList) 171: Stmt(ObjCAtCatchStmtClass) { 172 SubExprs[SELECTOR] = catchVarStmtDecl; 173 SubExprs[BODY] = atCatchStmt; 174 SubExprs[NEXT_CATCH] = NULL; 175 if (atCatchList) { 176 ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList); 177 178 while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt()) 179 AtCatchList = NextCatch; 180 181 AtCatchList->SubExprs[NEXT_CATCH] = this; 182 } 183 AtCatchLoc = atCatchLoc; 184 RParenLoc = rparenloc; 185} 186 187 188//===----------------------------------------------------------------------===// 189// Child Iterators for iterating over subexpressions/substatements 190//===----------------------------------------------------------------------===// 191 192// DeclStmt 193Stmt::child_iterator DeclStmt::child_begin() { return getDecl(); } 194Stmt::child_iterator DeclStmt::child_end() { return child_iterator(); } 195 196// NullStmt 197Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); } 198Stmt::child_iterator NullStmt::child_end() { return child_iterator(); } 199 200// CompoundStmt 201Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; } 202Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+Body.size(); } 203 204// CaseStmt 205Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; } 206Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; } 207 208// DefaultStmt 209Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; } 210Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; } 211 212// LabelStmt 213Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; } 214Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; } 215 216// IfStmt 217Stmt::child_iterator IfStmt::child_begin() { return &SubExprs[0]; } 218Stmt::child_iterator IfStmt::child_end() { return &SubExprs[0]+END_EXPR; } 219 220// SwitchStmt 221Stmt::child_iterator SwitchStmt::child_begin() { return &SubExprs[0]; } 222Stmt::child_iterator SwitchStmt::child_end() { return &SubExprs[0]+END_EXPR; } 223 224// WhileStmt 225Stmt::child_iterator WhileStmt::child_begin() { return &SubExprs[0]; } 226Stmt::child_iterator WhileStmt::child_end() { return &SubExprs[0]+END_EXPR; } 227 228// DoStmt 229Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; } 230Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; } 231 232// ForStmt 233Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; } 234Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; } 235 236// ObjCForCollectionStmt 237Stmt::child_iterator ObjCForCollectionStmt::child_begin() { 238 return &SubExprs[0]; 239} 240Stmt::child_iterator ObjCForCollectionStmt::child_end() { 241 return &SubExprs[0]+END_EXPR; 242} 243 244// GotoStmt 245Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); } 246Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); } 247 248// IndirectGotoStmt 249Stmt::child_iterator IndirectGotoStmt::child_begin() { 250 return reinterpret_cast<Stmt**>(&Target); 251} 252 253Stmt::child_iterator IndirectGotoStmt::child_end() { return ++child_begin(); } 254 255// ContinueStmt 256Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); } 257Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); } 258 259// BreakStmt 260Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); } 261Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); } 262 263// ReturnStmt 264Stmt::child_iterator ReturnStmt::child_begin() { 265 if (RetExpr) return reinterpret_cast<Stmt**>(&RetExpr); 266 else return child_iterator(); 267} 268 269Stmt::child_iterator ReturnStmt::child_end() { 270 if (RetExpr) return reinterpret_cast<Stmt**>(&RetExpr)+1; 271 else return child_iterator(); 272} 273 274// AsmStmt 275Stmt::child_iterator AsmStmt::child_begin() { return child_iterator(); } 276Stmt::child_iterator AsmStmt::child_end() { return child_iterator(); } 277 278// ObjCAtCatchStmt 279Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; } 280Stmt::child_iterator ObjCAtCatchStmt::child_end() { 281 return &SubExprs[0]+END_EXPR; 282} 283 284// ObjCAtFinallyStmt 285Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; } 286Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; } 287 288// ObjCAtTryStmt 289Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; } 290Stmt::child_iterator ObjCAtTryStmt::child_end() { 291 return &SubStmts[0]+END_EXPR; 292} 293 294// ObjCAtThrowStmt 295Stmt::child_iterator ObjCAtThrowStmt::child_begin() { 296 return &Throw; 297} 298 299Stmt::child_iterator ObjCAtThrowStmt::child_end() { 300 return &Throw+1; 301} 302 303// ObjCAtSynchronizedStmt 304Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() { 305 return &SubStmts[0]; 306} 307 308Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() { 309 return &SubStmts[0]+END_EXPR; 310} 311 312