Stmt.cpp revision 6515afe50c8d69dbb029b85f879cb2e083854b6c
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/StmtCXX.h" 18#include "clang/AST/StmtObjC.h" 19#include "clang/AST/Type.h" 20#include "clang/AST/ASTContext.h" 21#include "clang/AST/ASTDiagnostic.h" 22#include <cstdio> 23using namespace clang; 24 25static struct StmtClassNameTable { 26 const char *Name; 27 unsigned Counter; 28 unsigned Size; 29} StmtClassInfo[Stmt::lastExprConstant+1]; 30 31static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) { 32 static bool Initialized = false; 33 if (Initialized) 34 return StmtClassInfo[E]; 35 36 // Intialize the table on the first use. 37 Initialized = true; 38#define STMT(CLASS, PARENT) \ 39 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \ 40 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS); 41#include "clang/AST/StmtNodes.def" 42 43 return StmtClassInfo[E]; 44} 45 46const char *Stmt::getStmtClassName() const { 47 return getStmtInfoTableEntry((StmtClass)sClass).Name; 48} 49 50void Stmt::DestroyChildren(ASTContext &C) { 51 for (child_iterator I = child_begin(), E = child_end(); I !=E; ) 52 if (Stmt* Child = *I++) Child->Destroy(C); 53} 54 55void Stmt::DoDestroy(ASTContext &C) { 56 DestroyChildren(C); 57 this->~Stmt(); 58 C.Deallocate((void *)this); 59} 60 61void Stmt::PrintStats() { 62 // Ensure the table is primed. 63 getStmtInfoTableEntry(Stmt::NullStmtClass); 64 65 unsigned sum = 0; 66 fprintf(stderr, "*** Stmt/Expr Stats:\n"); 67 for (int i = 0; i != Stmt::lastExprConstant+1; i++) { 68 if (StmtClassInfo[i].Name == 0) continue; 69 sum += StmtClassInfo[i].Counter; 70 } 71 fprintf(stderr, " %d stmts/exprs total.\n", sum); 72 sum = 0; 73 for (int i = 0; i != Stmt::lastExprConstant+1; i++) { 74 if (StmtClassInfo[i].Name == 0) continue; 75 if (StmtClassInfo[i].Counter == 0) continue; 76 fprintf(stderr, " %d %s, %d each (%d bytes)\n", 77 StmtClassInfo[i].Counter, StmtClassInfo[i].Name, 78 StmtClassInfo[i].Size, 79 StmtClassInfo[i].Counter*StmtClassInfo[i].Size); 80 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size; 81 } 82 fprintf(stderr, "Total bytes = %d\n", sum); 83} 84 85void Stmt::addStmtClass(StmtClass s) { 86 ++getStmtInfoTableEntry(s).Counter; 87} 88 89static bool StatSwitch = false; 90 91bool Stmt::CollectingStats(bool Enable) { 92 if (Enable) StatSwitch = true; 93 return StatSwitch; 94} 95 96void SwitchStmt::DoDestroy(ASTContext &Ctx) { 97 // Destroy the SwitchCase statements in this switch. In the normal 98 // case, this loop will merely decrement the reference counts from 99 // the Retain() calls in addSwitchCase(); 100 SwitchCase *SC = FirstCase; 101 while (SC) { 102 SwitchCase *Next = SC->getNextSwitchCase(); 103 SC->Destroy(Ctx); 104 SC = Next; 105 } 106 107 Stmt::DoDestroy(Ctx); 108} 109 110void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) { 111 if (this->Body) 112 C.Deallocate(Body); 113 this->NumStmts = NumStmts; 114 115 Body = new (C) Stmt*[NumStmts]; 116 memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts); 117} 118 119const char *LabelStmt::getName() const { 120 return getID()->getNameStart(); 121} 122 123// This is defined here to avoid polluting Stmt.h with importing Expr.h 124SourceRange ReturnStmt::getSourceRange() const { 125 if (RetExpr) 126 return SourceRange(RetLoc, RetExpr->getLocEnd()); 127 else 128 return SourceRange(RetLoc); 129} 130 131bool Stmt::hasImplicitControlFlow() const { 132 switch (sClass) { 133 default: 134 return false; 135 136 case CallExprClass: 137 case ConditionalOperatorClass: 138 case ChooseExprClass: 139 case StmtExprClass: 140 case DeclStmtClass: 141 return true; 142 143 case Stmt::BinaryOperatorClass: { 144 const BinaryOperator* B = cast<BinaryOperator>(this); 145 if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma) 146 return true; 147 else 148 return false; 149 } 150 } 151} 152 153Expr *AsmStmt::getOutputExpr(unsigned i) { 154 return cast<Expr>(Exprs[i]); 155} 156 157/// getOutputConstraint - Return the constraint string for the specified 158/// output operand. All output constraints are known to be non-empty (either 159/// '=' or '+'). 160std::string AsmStmt::getOutputConstraint(unsigned i) const { 161 return std::string(Constraints[i]->getStrData(), 162 Constraints[i]->getByteLength()); 163} 164 165/// getNumPlusOperands - Return the number of output operands that have a "+" 166/// constraint. 167unsigned AsmStmt::getNumPlusOperands() const { 168 unsigned Res = 0; 169 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) 170 if (isOutputPlusConstraint(i)) 171 ++Res; 172 return Res; 173} 174 175 176 177Expr *AsmStmt::getInputExpr(unsigned i) { 178 return cast<Expr>(Exprs[i + NumOutputs]); 179} 180 181/// getInputConstraint - Return the specified input constraint. Unlike output 182/// constraints, these can be empty. 183std::string AsmStmt::getInputConstraint(unsigned i) const { 184 return std::string(Constraints[i + NumOutputs]->getStrData(), 185 Constraints[i + NumOutputs]->getByteLength()); 186} 187 188 189void AsmStmt::setOutputsAndInputs(unsigned NumOutputs, 190 unsigned NumInputs, 191 const std::string *Names, 192 StringLiteral **Constraints, 193 Stmt **Exprs) { 194 this->NumOutputs = NumOutputs; 195 this->NumInputs = NumInputs; 196 this->Names.clear(); 197 this->Names.insert(this->Names.end(), Names, Names + NumOutputs + NumInputs); 198 this->Constraints.clear(); 199 this->Constraints.insert(this->Constraints.end(), 200 Constraints, Constraints + NumOutputs + NumInputs); 201 this->Exprs.clear(); 202 this->Exprs.insert(this->Exprs.end(), Exprs, Exprs + NumOutputs + NumInputs); 203} 204 205/// getNamedOperand - Given a symbolic operand reference like %[foo], 206/// translate this into a numeric value needed to reference the same operand. 207/// This returns -1 if the operand name is invalid. 208int AsmStmt::getNamedOperand(const std::string &SymbolicName) const { 209 unsigned NumPlusOperands = 0; 210 211 // Check if this is an output operand. 212 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) { 213 if (getOutputName(i) == SymbolicName) 214 return i; 215 } 216 217 for (unsigned i = 0, e = getNumInputs(); i != e; ++i) 218 if (getInputName(i) == SymbolicName) 219 return getNumOutputs() + NumPlusOperands + i; 220 221 // Not found. 222 return -1; 223} 224 225void AsmStmt::setClobbers(StringLiteral **Clobbers, unsigned NumClobbers) { 226 this->Clobbers.clear(); 227 this->Clobbers.insert(this->Clobbers.end(), Clobbers, Clobbers + NumClobbers); 228} 229 230/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing 231/// it into pieces. If the asm string is erroneous, emit errors and return 232/// true, otherwise return false. 233unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces, 234 ASTContext &C, unsigned &DiagOffs) const { 235 const char *StrStart = getAsmString()->getStrData(); 236 const char *StrEnd = StrStart + getAsmString()->getByteLength(); 237 const char *CurPtr = StrStart; 238 239 // "Simple" inline asms have no constraints or operands, just convert the asm 240 // string to escape $'s. 241 if (isSimple()) { 242 std::string Result; 243 for (; CurPtr != StrEnd; ++CurPtr) { 244 switch (*CurPtr) { 245 case '$': 246 Result += "$$"; 247 break; 248 default: 249 Result += *CurPtr; 250 break; 251 } 252 } 253 Pieces.push_back(AsmStringPiece(Result)); 254 return 0; 255 } 256 257 // CurStringPiece - The current string that we are building up as we scan the 258 // asm string. 259 std::string CurStringPiece; 260 261 while (1) { 262 // Done with the string? 263 if (CurPtr == StrEnd) { 264 if (!CurStringPiece.empty()) 265 Pieces.push_back(AsmStringPiece(CurStringPiece)); 266 return 0; 267 } 268 269 char CurChar = *CurPtr++; 270 if (CurChar == '$') { 271 CurStringPiece += "$$"; 272 continue; 273 } else if (CurChar != '%') { 274 CurStringPiece += CurChar; 275 continue; 276 } 277 278 // Escaped "%" character in asm string. 279 if (CurPtr == StrEnd) { 280 // % at end of string is invalid (no escape). 281 DiagOffs = CurPtr-StrStart-1; 282 return diag::err_asm_invalid_escape; 283 } 284 285 char EscapedChar = *CurPtr++; 286 if (EscapedChar == '%') { // %% -> % 287 // Escaped percentage sign. 288 CurStringPiece += '%'; 289 continue; 290 } 291 292 if (EscapedChar == '=') { // %= -> Generate an unique ID. 293 CurStringPiece += "${:uid}"; 294 continue; 295 } 296 297 // Otherwise, we have an operand. If we have accumulated a string so far, 298 // add it to the Pieces list. 299 if (!CurStringPiece.empty()) { 300 Pieces.push_back(AsmStringPiece(CurStringPiece)); 301 CurStringPiece.clear(); 302 } 303 304 // Handle %x4 and %x[foo] by capturing x as the modifier character. 305 char Modifier = '\0'; 306 if (isalpha(EscapedChar)) { 307 Modifier = EscapedChar; 308 EscapedChar = *CurPtr++; 309 } 310 311 if (isdigit(EscapedChar)) { 312 // %n - Assembler operand n 313 unsigned N = 0; 314 315 --CurPtr; 316 while (CurPtr != StrEnd && isdigit(*CurPtr)) 317 N = N*10 + ((*CurPtr++)-'0'); 318 319 unsigned NumOperands = 320 getNumOutputs() + getNumPlusOperands() + getNumInputs(); 321 if (N >= NumOperands) { 322 DiagOffs = CurPtr-StrStart-1; 323 return diag::err_asm_invalid_operand_number; 324 } 325 326 Pieces.push_back(AsmStringPiece(N, Modifier)); 327 continue; 328 } 329 330 // Handle %[foo], a symbolic operand reference. 331 if (EscapedChar == '[') { 332 DiagOffs = CurPtr-StrStart-1; 333 334 // Find the ']'. 335 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr); 336 if (NameEnd == 0) 337 return diag::err_asm_unterminated_symbolic_operand_name; 338 if (NameEnd == CurPtr) 339 return diag::err_asm_empty_symbolic_operand_name; 340 341 std::string SymbolicName(CurPtr, NameEnd); 342 343 int N = getNamedOperand(SymbolicName); 344 if (N == -1) { 345 // Verify that an operand with that name exists. 346 DiagOffs = CurPtr-StrStart; 347 return diag::err_asm_unknown_symbolic_operand_name; 348 } 349 Pieces.push_back(AsmStringPiece(N, Modifier)); 350 351 CurPtr = NameEnd+1; 352 continue; 353 } 354 355 DiagOffs = CurPtr-StrStart-1; 356 return diag::err_asm_invalid_escape; 357 } 358} 359 360//===----------------------------------------------------------------------===// 361// Constructors 362//===----------------------------------------------------------------------===// 363 364AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, 365 unsigned numoutputs, unsigned numinputs, 366 std::string *names, StringLiteral **constraints, 367 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 368 StringLiteral **clobbers, SourceLocation rparenloc) 369 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr) 370 , IsSimple(issimple), IsVolatile(isvolatile) 371 , NumOutputs(numoutputs), NumInputs(numinputs) { 372 for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) { 373 Names.push_back(names[i]); 374 Exprs.push_back(exprs[i]); 375 Constraints.push_back(constraints[i]); 376 } 377 378 for (unsigned i = 0; i != numclobbers; i++) 379 Clobbers.push_back(clobbers[i]); 380} 381 382ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, 383 Stmt *Body, SourceLocation FCL, 384 SourceLocation RPL) 385: Stmt(ObjCForCollectionStmtClass) { 386 SubExprs[ELEM] = Elem; 387 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect); 388 SubExprs[BODY] = Body; 389 ForLoc = FCL; 390 RParenLoc = RPL; 391} 392 393 394ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc, 395 SourceLocation rparenloc, 396 ParmVarDecl *catchVarDecl, Stmt *atCatchStmt, 397 Stmt *atCatchList) 398: Stmt(ObjCAtCatchStmtClass) { 399 ExceptionDecl = catchVarDecl; 400 SubExprs[BODY] = atCatchStmt; 401 SubExprs[NEXT_CATCH] = NULL; 402 // FIXME: O(N^2) in number of catch blocks. 403 if (atCatchList) { 404 ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList); 405 406 while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt()) 407 AtCatchList = NextCatch; 408 409 AtCatchList->SubExprs[NEXT_CATCH] = this; 410 } 411 AtCatchLoc = atCatchLoc; 412 RParenLoc = rparenloc; 413} 414 415 416//===----------------------------------------------------------------------===// 417// Child Iterators for iterating over subexpressions/substatements 418//===----------------------------------------------------------------------===// 419 420// DeclStmt 421Stmt::child_iterator DeclStmt::child_begin() { 422 return StmtIterator(DG.begin(), DG.end()); 423} 424 425Stmt::child_iterator DeclStmt::child_end() { 426 return StmtIterator(DG.end(), DG.end()); 427} 428 429// NullStmt 430Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); } 431Stmt::child_iterator NullStmt::child_end() { return child_iterator(); } 432 433// CompoundStmt 434Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; } 435Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; } 436 437// CaseStmt 438Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; } 439Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; } 440 441// DefaultStmt 442Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; } 443Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; } 444 445// LabelStmt 446Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; } 447Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; } 448 449// IfStmt 450Stmt::child_iterator IfStmt::child_begin() { return &SubExprs[0]; } 451Stmt::child_iterator IfStmt::child_end() { return &SubExprs[0]+END_EXPR; } 452 453// SwitchStmt 454Stmt::child_iterator SwitchStmt::child_begin() { return &SubExprs[0]; } 455Stmt::child_iterator SwitchStmt::child_end() { return &SubExprs[0]+END_EXPR; } 456 457// WhileStmt 458Stmt::child_iterator WhileStmt::child_begin() { return &SubExprs[0]; } 459Stmt::child_iterator WhileStmt::child_end() { return &SubExprs[0]+END_EXPR; } 460 461// DoStmt 462Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; } 463Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; } 464 465// ForStmt 466Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; } 467Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; } 468 469// ObjCForCollectionStmt 470Stmt::child_iterator ObjCForCollectionStmt::child_begin() { 471 return &SubExprs[0]; 472} 473Stmt::child_iterator ObjCForCollectionStmt::child_end() { 474 return &SubExprs[0]+END_EXPR; 475} 476 477// GotoStmt 478Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); } 479Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); } 480 481// IndirectGotoStmt 482Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); } 483const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); } 484 485Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; } 486Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; } 487 488// ContinueStmt 489Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); } 490Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); } 491 492// BreakStmt 493Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); } 494Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); } 495 496// ReturnStmt 497const Expr* ReturnStmt::getRetValue() const { 498 return cast_or_null<Expr>(RetExpr); 499} 500Expr* ReturnStmt::getRetValue() { 501 return cast_or_null<Expr>(RetExpr); 502} 503 504Stmt::child_iterator ReturnStmt::child_begin() { 505 return &RetExpr; 506} 507Stmt::child_iterator ReturnStmt::child_end() { 508 return RetExpr ? &RetExpr+1 : &RetExpr; 509} 510 511// AsmStmt 512Stmt::child_iterator AsmStmt::child_begin() { 513 return Exprs.empty() ? 0 : &Exprs[0]; 514} 515Stmt::child_iterator AsmStmt::child_end() { 516 return Exprs.empty() ? 0 : &Exprs[0] + Exprs.size(); 517} 518 519// ObjCAtCatchStmt 520Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; } 521Stmt::child_iterator ObjCAtCatchStmt::child_end() { 522 return &SubExprs[0]+END_EXPR; 523} 524 525// ObjCAtFinallyStmt 526Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; } 527Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; } 528 529// ObjCAtTryStmt 530Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; } 531Stmt::child_iterator ObjCAtTryStmt::child_end() { 532 return &SubStmts[0]+END_EXPR; 533} 534 535// ObjCAtThrowStmt 536Stmt::child_iterator ObjCAtThrowStmt::child_begin() { 537 return &Throw; 538} 539 540Stmt::child_iterator ObjCAtThrowStmt::child_end() { 541 return &Throw+1; 542} 543 544// ObjCAtSynchronizedStmt 545Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() { 546 return &SubStmts[0]; 547} 548 549Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() { 550 return &SubStmts[0]+END_EXPR; 551} 552 553// CXXCatchStmt 554Stmt::child_iterator CXXCatchStmt::child_begin() { 555 return &HandlerBlock; 556} 557 558Stmt::child_iterator CXXCatchStmt::child_end() { 559 return &HandlerBlock + 1; 560} 561 562QualType CXXCatchStmt::getCaughtType() const { 563 if (ExceptionDecl) 564 return ExceptionDecl->getType(); 565 return QualType(); 566} 567 568void CXXCatchStmt::DoDestroy(ASTContext& C) { 569 if (ExceptionDecl) 570 ExceptionDecl->Destroy(C); 571 Stmt::DoDestroy(C); 572} 573 574// CXXTryStmt 575Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; } 576Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+Stmts.size(); } 577 578CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, 579 Stmt **handlers, unsigned numHandlers) 580 : Stmt(CXXTryStmtClass), TryLoc(tryLoc) { 581 Stmts.push_back(tryBlock); 582 Stmts.insert(Stmts.end(), handlers, handlers + numHandlers); 583} 584