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 "clang/Basic/TargetInfo.h" 23 #include "llvm/Support/raw_ostream.h" 24 using namespace clang; 25 26 static struct StmtClassNameTable { 27 const char *Name; 28 unsigned Counter; 29 unsigned Size; 30 } StmtClassInfo[Stmt::lastStmtConstant+1]; 31 32 static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) { 33 static bool Initialized = false; 34 if (Initialized) 35 return StmtClassInfo[E]; 36 37 // Intialize the table on the first use. 38 Initialized = true; 39 #define ABSTRACT_STMT(STMT) 40 #define STMT(CLASS, PARENT) \ 41 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \ 42 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS); 43 #include "clang/AST/StmtNodes.inc" 44 45 return StmtClassInfo[E]; 46 } 47 48 const char *Stmt::getStmtClassName() const { 49 return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name; 50 } 51 52 void Stmt::PrintStats() { 53 // Ensure the table is primed. 54 getStmtInfoTableEntry(Stmt::NullStmtClass); 55 56 unsigned sum = 0; 57 llvm::errs() << "\n*** Stmt/Expr Stats:\n"; 58 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { 59 if (StmtClassInfo[i].Name == 0) continue; 60 sum += StmtClassInfo[i].Counter; 61 } 62 llvm::errs() << " " << sum << " stmts/exprs total.\n"; 63 sum = 0; 64 for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { 65 if (StmtClassInfo[i].Name == 0) continue; 66 if (StmtClassInfo[i].Counter == 0) continue; 67 llvm::errs() << " " << StmtClassInfo[i].Counter << " " 68 << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size 69 << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size 70 << " bytes)\n"; 71 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size; 72 } 73 74 llvm::errs() << "Total bytes = " << sum << "\n"; 75 } 76 77 void Stmt::addStmtClass(StmtClass s) { 78 ++getStmtInfoTableEntry(s).Counter; 79 } 80 81 bool Stmt::StatisticsEnabled = false; 82 void Stmt::EnableStatistics() { 83 StatisticsEnabled = true; 84 } 85 86 Stmt *Stmt::IgnoreImplicit() { 87 Stmt *s = this; 88 89 if (ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(s)) 90 s = ewc->getSubExpr(); 91 92 while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(s)) 93 s = ice->getSubExpr(); 94 95 return s; 96 } 97 98 /// \brief Strip off all label-like statements. 99 /// 100 /// This will strip off label statements, case statements, attributed 101 /// statements and default statements recursively. 102 const Stmt *Stmt::stripLabelLikeStatements() const { 103 const Stmt *S = this; 104 while (true) { 105 if (const LabelStmt *LS = dyn_cast<LabelStmt>(S)) 106 S = LS->getSubStmt(); 107 else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) 108 S = SC->getSubStmt(); 109 else if (const AttributedStmt *AS = dyn_cast<AttributedStmt>(S)) 110 S = AS->getSubStmt(); 111 else 112 return S; 113 } 114 } 115 116 namespace { 117 struct good {}; 118 struct bad {}; 119 120 // These silly little functions have to be static inline to suppress 121 // unused warnings, and they have to be defined to suppress other 122 // warnings. 123 static inline good is_good(good) { return good(); } 124 125 typedef Stmt::child_range children_t(); 126 template <class T> good implements_children(children_t T::*) { 127 return good(); 128 } 129 static inline bad implements_children(children_t Stmt::*) { 130 return bad(); 131 } 132 133 typedef SourceRange getSourceRange_t() const; 134 template <class T> good implements_getSourceRange(getSourceRange_t T::*) { 135 return good(); 136 } 137 static inline bad implements_getSourceRange(getSourceRange_t Stmt::*) { 138 return bad(); 139 } 140 141 #define ASSERT_IMPLEMENTS_children(type) \ 142 (void) sizeof(is_good(implements_children(&type::children))) 143 #define ASSERT_IMPLEMENTS_getSourceRange(type) \ 144 (void) sizeof(is_good(implements_getSourceRange(&type::getSourceRange))) 145 } 146 147 /// Check whether the various Stmt classes implement their member 148 /// functions. 149 static inline void check_implementations() { 150 #define ABSTRACT_STMT(type) 151 #define STMT(type, base) \ 152 ASSERT_IMPLEMENTS_children(type); \ 153 ASSERT_IMPLEMENTS_getSourceRange(type); 154 #include "clang/AST/StmtNodes.inc" 155 } 156 157 Stmt::child_range Stmt::children() { 158 switch (getStmtClass()) { 159 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 160 #define ABSTRACT_STMT(type) 161 #define STMT(type, base) \ 162 case Stmt::type##Class: \ 163 return static_cast<type*>(this)->children(); 164 #include "clang/AST/StmtNodes.inc" 165 } 166 llvm_unreachable("unknown statement kind!"); 167 } 168 169 SourceRange Stmt::getSourceRange() const { 170 switch (getStmtClass()) { 171 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 172 #define ABSTRACT_STMT(type) 173 #define STMT(type, base) \ 174 case Stmt::type##Class: \ 175 return static_cast<const type*>(this)->getSourceRange(); 176 #include "clang/AST/StmtNodes.inc" 177 } 178 llvm_unreachable("unknown statement kind!"); 179 } 180 181 // Amusing macro metaprogramming hack: check whether a class provides 182 // a more specific implementation of getLocStart() and getLocEnd(). 183 // 184 // See also Expr.cpp:getExprLoc(). 185 namespace { 186 /// This implementation is used when a class provides a custom 187 /// implementation of getLocStart. 188 template <class S, class T> 189 SourceLocation getLocStartImpl(const Stmt *stmt, 190 SourceLocation (T::*v)() const) { 191 return static_cast<const S*>(stmt)->getLocStart(); 192 } 193 194 /// This implementation is used when a class doesn't provide a custom 195 /// implementation of getLocStart. Overload resolution should pick it over 196 /// the implementation above because it's more specialized according to 197 /// function template partial ordering. 198 template <class S> 199 SourceLocation getLocStartImpl(const Stmt *stmt, 200 SourceLocation (Stmt::*v)() const) { 201 return static_cast<const S*>(stmt)->getSourceRange().getBegin(); 202 } 203 204 /// This implementation is used when a class provides a custom 205 /// implementation of getLocEnd. 206 template <class S, class T> 207 SourceLocation getLocEndImpl(const Stmt *stmt, 208 SourceLocation (T::*v)() const) { 209 return static_cast<const S*>(stmt)->getLocEnd(); 210 } 211 212 /// This implementation is used when a class doesn't provide a custom 213 /// implementation of getLocEnd. Overload resolution should pick it over 214 /// the implementation above because it's more specialized according to 215 /// function template partial ordering. 216 template <class S> 217 SourceLocation getLocEndImpl(const Stmt *stmt, 218 SourceLocation (Stmt::*v)() const) { 219 return static_cast<const S*>(stmt)->getSourceRange().getEnd(); 220 } 221 } 222 223 SourceLocation Stmt::getLocStart() const { 224 switch (getStmtClass()) { 225 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 226 #define ABSTRACT_STMT(type) 227 #define STMT(type, base) \ 228 case Stmt::type##Class: \ 229 return getLocStartImpl<type>(this, &type::getLocStart); 230 #include "clang/AST/StmtNodes.inc" 231 } 232 llvm_unreachable("unknown statement kind"); 233 } 234 235 SourceLocation Stmt::getLocEnd() const { 236 switch (getStmtClass()) { 237 case Stmt::NoStmtClass: llvm_unreachable("statement without class"); 238 #define ABSTRACT_STMT(type) 239 #define STMT(type, base) \ 240 case Stmt::type##Class: \ 241 return getLocEndImpl<type>(this, &type::getLocEnd); 242 #include "clang/AST/StmtNodes.inc" 243 } 244 llvm_unreachable("unknown statement kind"); 245 } 246 247 CompoundStmt::CompoundStmt(ASTContext &C, Stmt **StmtStart, unsigned NumStmts, 248 SourceLocation LB, SourceLocation RB) 249 : Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) { 250 CompoundStmtBits.NumStmts = NumStmts; 251 assert(CompoundStmtBits.NumStmts == NumStmts && 252 "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!"); 253 254 if (NumStmts == 0) { 255 Body = 0; 256 return; 257 } 258 259 Body = new (C) Stmt*[NumStmts]; 260 memcpy(Body, StmtStart, NumStmts * sizeof(*Body)); 261 } 262 263 void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) { 264 if (this->Body) 265 C.Deallocate(Body); 266 this->CompoundStmtBits.NumStmts = NumStmts; 267 268 Body = new (C) Stmt*[NumStmts]; 269 memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts); 270 } 271 272 const char *LabelStmt::getName() const { 273 return getDecl()->getIdentifier()->getNameStart(); 274 } 275 276 AttributedStmt *AttributedStmt::Create(ASTContext &C, SourceLocation Loc, 277 ArrayRef<const Attr*> Attrs, 278 Stmt *SubStmt) { 279 void *Mem = C.Allocate(sizeof(AttributedStmt) + 280 sizeof(Attr*) * (Attrs.size() - 1), 281 llvm::alignOf<AttributedStmt>()); 282 return new (Mem) AttributedStmt(Loc, Attrs, SubStmt); 283 } 284 285 AttributedStmt *AttributedStmt::CreateEmpty(ASTContext &C, unsigned NumAttrs) { 286 assert(NumAttrs > 0 && "NumAttrs should be greater than zero"); 287 void *Mem = C.Allocate(sizeof(AttributedStmt) + 288 sizeof(Attr*) * (NumAttrs - 1), 289 llvm::alignOf<AttributedStmt>()); 290 return new (Mem) AttributedStmt(EmptyShell(), NumAttrs); 291 } 292 293 // This is defined here to avoid polluting Stmt.h with importing Expr.h 294 SourceRange ReturnStmt::getSourceRange() const { 295 if (RetExpr) 296 return SourceRange(RetLoc, RetExpr->getLocEnd()); 297 else 298 return SourceRange(RetLoc); 299 } 300 301 bool Stmt::hasImplicitControlFlow() const { 302 switch (StmtBits.sClass) { 303 default: 304 return false; 305 306 case CallExprClass: 307 case ConditionalOperatorClass: 308 case ChooseExprClass: 309 case StmtExprClass: 310 case DeclStmtClass: 311 return true; 312 313 case Stmt::BinaryOperatorClass: { 314 const BinaryOperator* B = cast<BinaryOperator>(this); 315 if (B->isLogicalOp() || B->getOpcode() == BO_Comma) 316 return true; 317 else 318 return false; 319 } 320 } 321 } 322 323 Expr *AsmStmt::getOutputExpr(unsigned i) { 324 return cast<Expr>(Exprs[i]); 325 } 326 327 /// getOutputConstraint - Return the constraint string for the specified 328 /// output operand. All output constraints are known to be non-empty (either 329 /// '=' or '+'). 330 StringRef AsmStmt::getOutputConstraint(unsigned i) const { 331 return getOutputConstraintLiteral(i)->getString(); 332 } 333 334 /// getNumPlusOperands - Return the number of output operands that have a "+" 335 /// constraint. 336 unsigned AsmStmt::getNumPlusOperands() const { 337 unsigned Res = 0; 338 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) 339 if (isOutputPlusConstraint(i)) 340 ++Res; 341 return Res; 342 } 343 344 Expr *AsmStmt::getInputExpr(unsigned i) { 345 return cast<Expr>(Exprs[i + NumOutputs]); 346 } 347 void AsmStmt::setInputExpr(unsigned i, Expr *E) { 348 Exprs[i + NumOutputs] = E; 349 } 350 351 352 /// getInputConstraint - Return the specified input constraint. Unlike output 353 /// constraints, these can be empty. 354 StringRef AsmStmt::getInputConstraint(unsigned i) const { 355 return getInputConstraintLiteral(i)->getString(); 356 } 357 358 359 void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C, 360 IdentifierInfo **Names, 361 StringLiteral **Constraints, 362 Stmt **Exprs, 363 unsigned NumOutputs, 364 unsigned NumInputs, 365 StringLiteral **Clobbers, 366 unsigned NumClobbers) { 367 this->NumOutputs = NumOutputs; 368 this->NumInputs = NumInputs; 369 this->NumClobbers = NumClobbers; 370 371 unsigned NumExprs = NumOutputs + NumInputs; 372 373 C.Deallocate(this->Names); 374 this->Names = new (C) IdentifierInfo*[NumExprs]; 375 std::copy(Names, Names + NumExprs, this->Names); 376 377 C.Deallocate(this->Exprs); 378 this->Exprs = new (C) Stmt*[NumExprs]; 379 std::copy(Exprs, Exprs + NumExprs, this->Exprs); 380 381 C.Deallocate(this->Constraints); 382 this->Constraints = new (C) StringLiteral*[NumExprs]; 383 std::copy(Constraints, Constraints + NumExprs, this->Constraints); 384 385 C.Deallocate(this->Clobbers); 386 this->Clobbers = new (C) StringLiteral*[NumClobbers]; 387 std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers); 388 } 389 390 /// getNamedOperand - Given a symbolic operand reference like %[foo], 391 /// translate this into a numeric value needed to reference the same operand. 392 /// This returns -1 if the operand name is invalid. 393 int AsmStmt::getNamedOperand(StringRef SymbolicName) const { 394 unsigned NumPlusOperands = 0; 395 396 // Check if this is an output operand. 397 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) { 398 if (getOutputName(i) == SymbolicName) 399 return i; 400 } 401 402 for (unsigned i = 0, e = getNumInputs(); i != e; ++i) 403 if (getInputName(i) == SymbolicName) 404 return getNumOutputs() + NumPlusOperands + i; 405 406 // Not found. 407 return -1; 408 } 409 410 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing 411 /// it into pieces. If the asm string is erroneous, emit errors and return 412 /// true, otherwise return false. 413 unsigned AsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces, 414 ASTContext &C, unsigned &DiagOffs) const { 415 StringRef Str = getAsmString()->getString(); 416 const char *StrStart = Str.begin(); 417 const char *StrEnd = Str.end(); 418 const char *CurPtr = StrStart; 419 420 // "Simple" inline asms have no constraints or operands, just convert the asm 421 // string to escape $'s. 422 if (isSimple()) { 423 std::string Result; 424 for (; CurPtr != StrEnd; ++CurPtr) { 425 switch (*CurPtr) { 426 case '$': 427 Result += "$$"; 428 break; 429 default: 430 Result += *CurPtr; 431 break; 432 } 433 } 434 Pieces.push_back(AsmStringPiece(Result)); 435 return 0; 436 } 437 438 // CurStringPiece - The current string that we are building up as we scan the 439 // asm string. 440 std::string CurStringPiece; 441 442 bool HasVariants = !C.getTargetInfo().hasNoAsmVariants(); 443 444 while (1) { 445 // Done with the string? 446 if (CurPtr == StrEnd) { 447 if (!CurStringPiece.empty()) 448 Pieces.push_back(AsmStringPiece(CurStringPiece)); 449 return 0; 450 } 451 452 char CurChar = *CurPtr++; 453 switch (CurChar) { 454 case '$': CurStringPiece += "$$"; continue; 455 case '{': CurStringPiece += (HasVariants ? "$(" : "{"); continue; 456 case '|': CurStringPiece += (HasVariants ? "$|" : "|"); continue; 457 case '}': CurStringPiece += (HasVariants ? "$)" : "}"); continue; 458 case '%': 459 break; 460 default: 461 CurStringPiece += CurChar; 462 continue; 463 } 464 465 // Escaped "%" character in asm string. 466 if (CurPtr == StrEnd) { 467 // % at end of string is invalid (no escape). 468 DiagOffs = CurPtr-StrStart-1; 469 return diag::err_asm_invalid_escape; 470 } 471 472 char EscapedChar = *CurPtr++; 473 if (EscapedChar == '%') { // %% -> % 474 // Escaped percentage sign. 475 CurStringPiece += '%'; 476 continue; 477 } 478 479 if (EscapedChar == '=') { // %= -> Generate an unique ID. 480 CurStringPiece += "${:uid}"; 481 continue; 482 } 483 484 // Otherwise, we have an operand. If we have accumulated a string so far, 485 // add it to the Pieces list. 486 if (!CurStringPiece.empty()) { 487 Pieces.push_back(AsmStringPiece(CurStringPiece)); 488 CurStringPiece.clear(); 489 } 490 491 // Handle %x4 and %x[foo] by capturing x as the modifier character. 492 char Modifier = '\0'; 493 if (isalpha(EscapedChar)) { 494 if (CurPtr == StrEnd) { // Premature end. 495 DiagOffs = CurPtr-StrStart-1; 496 return diag::err_asm_invalid_escape; 497 } 498 Modifier = EscapedChar; 499 EscapedChar = *CurPtr++; 500 } 501 502 if (isdigit(EscapedChar)) { 503 // %n - Assembler operand n 504 unsigned N = 0; 505 506 --CurPtr; 507 while (CurPtr != StrEnd && isdigit(*CurPtr)) 508 N = N*10 + ((*CurPtr++)-'0'); 509 510 unsigned NumOperands = 511 getNumOutputs() + getNumPlusOperands() + getNumInputs(); 512 if (N >= NumOperands) { 513 DiagOffs = CurPtr-StrStart-1; 514 return diag::err_asm_invalid_operand_number; 515 } 516 517 Pieces.push_back(AsmStringPiece(N, Modifier)); 518 continue; 519 } 520 521 // Handle %[foo], a symbolic operand reference. 522 if (EscapedChar == '[') { 523 DiagOffs = CurPtr-StrStart-1; 524 525 // Find the ']'. 526 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr); 527 if (NameEnd == 0) 528 return diag::err_asm_unterminated_symbolic_operand_name; 529 if (NameEnd == CurPtr) 530 return diag::err_asm_empty_symbolic_operand_name; 531 532 StringRef SymbolicName(CurPtr, NameEnd - CurPtr); 533 534 int N = getNamedOperand(SymbolicName); 535 if (N == -1) { 536 // Verify that an operand with that name exists. 537 DiagOffs = CurPtr-StrStart; 538 return diag::err_asm_unknown_symbolic_operand_name; 539 } 540 Pieces.push_back(AsmStringPiece(N, Modifier)); 541 542 CurPtr = NameEnd+1; 543 continue; 544 } 545 546 DiagOffs = CurPtr-StrStart-1; 547 return diag::err_asm_invalid_escape; 548 } 549 } 550 551 QualType CXXCatchStmt::getCaughtType() const { 552 if (ExceptionDecl) 553 return ExceptionDecl->getType(); 554 return QualType(); 555 } 556 557 //===----------------------------------------------------------------------===// 558 // Constructors 559 //===----------------------------------------------------------------------===// 560 561 AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, 562 bool isvolatile, unsigned numoutputs, unsigned numinputs, 563 IdentifierInfo **names, StringLiteral **constraints, 564 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, 565 StringLiteral **clobbers, SourceLocation rparenloc) 566 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr) 567 , IsSimple(issimple), IsVolatile(isvolatile), NumOutputs(numoutputs) 568 , NumInputs(numinputs), NumClobbers(numclobbers) { 569 570 unsigned NumExprs = NumOutputs + NumInputs; 571 572 Names = new (C) IdentifierInfo*[NumExprs]; 573 std::copy(names, names + NumExprs, Names); 574 575 Exprs = new (C) Stmt*[NumExprs]; 576 std::copy(exprs, exprs + NumExprs, Exprs); 577 578 Constraints = new (C) StringLiteral*[NumExprs]; 579 std::copy(constraints, constraints + NumExprs, Constraints); 580 581 Clobbers = new (C) StringLiteral*[NumClobbers]; 582 std::copy(clobbers, clobbers + NumClobbers, Clobbers); 583 } 584 585 MSAsmStmt::MSAsmStmt(ASTContext &C, SourceLocation asmloc, 586 SourceLocation lbraceloc, bool issimple, bool isvolatile, 587 ArrayRef<Token> asmtoks, ArrayRef<IdentifierInfo*> inputs, 588 ArrayRef<IdentifierInfo*> outputs, StringRef asmstr, 589 ArrayRef<StringRef> clobbers, SourceLocation endloc) 590 : Stmt(MSAsmStmtClass), AsmLoc(asmloc), LBraceLoc(lbraceloc), EndLoc(endloc), 591 AsmStr(asmstr.str()), IsSimple(issimple), IsVolatile(isvolatile), 592 NumAsmToks(asmtoks.size()), NumInputs(inputs.size()), 593 NumOutputs(outputs.size()), NumClobbers(clobbers.size()) { 594 595 unsigned NumExprs = NumOutputs + NumInputs; 596 597 Names = new (C) IdentifierInfo*[NumExprs]; 598 for (unsigned i = 0, e = NumOutputs; i != e; ++i) 599 Names[i] = outputs[i]; 600 for (unsigned i = NumOutputs, e = NumExprs; i != e; ++i) 601 Names[i] = inputs[i]; 602 603 AsmToks = new (C) Token[NumAsmToks]; 604 for (unsigned i = 0, e = NumAsmToks; i != e; ++i) 605 AsmToks[i] = asmtoks[i]; 606 607 Clobbers = new (C) StringRef[NumClobbers]; 608 for (unsigned i = 0, e = NumClobbers; i != e; ++i) { 609 // FIXME: Avoid the allocation/copy if at all possible. 610 size_t size = clobbers[i].size(); 611 char *dest = new (C) char[size]; 612 std::strncpy(dest, clobbers[i].data(), size); 613 Clobbers[i] = StringRef(dest, size); 614 } 615 } 616 617 ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, 618 Stmt *Body, SourceLocation FCL, 619 SourceLocation RPL) 620 : Stmt(ObjCForCollectionStmtClass) { 621 SubExprs[ELEM] = Elem; 622 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect); 623 SubExprs[BODY] = Body; 624 ForLoc = FCL; 625 RParenLoc = RPL; 626 } 627 628 ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, 629 Stmt **CatchStmts, unsigned NumCatchStmts, 630 Stmt *atFinallyStmt) 631 : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc), 632 NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0) 633 { 634 Stmt **Stmts = getStmts(); 635 Stmts[0] = atTryStmt; 636 for (unsigned I = 0; I != NumCatchStmts; ++I) 637 Stmts[I + 1] = CatchStmts[I]; 638 639 if (HasFinally) 640 Stmts[NumCatchStmts + 1] = atFinallyStmt; 641 } 642 643 ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context, 644 SourceLocation atTryLoc, 645 Stmt *atTryStmt, 646 Stmt **CatchStmts, 647 unsigned NumCatchStmts, 648 Stmt *atFinallyStmt) { 649 unsigned Size = sizeof(ObjCAtTryStmt) + 650 (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *); 651 void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>()); 652 return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts, 653 atFinallyStmt); 654 } 655 656 ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context, 657 unsigned NumCatchStmts, 658 bool HasFinally) { 659 unsigned Size = sizeof(ObjCAtTryStmt) + 660 (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *); 661 void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>()); 662 return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally); 663 } 664 665 SourceRange ObjCAtTryStmt::getSourceRange() const { 666 SourceLocation EndLoc; 667 if (HasFinally) 668 EndLoc = getFinallyStmt()->getLocEnd(); 669 else if (NumCatchStmts) 670 EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd(); 671 else 672 EndLoc = getTryBody()->getLocEnd(); 673 674 return SourceRange(AtTryLoc, EndLoc); 675 } 676 677 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc, 678 Stmt *tryBlock, Stmt **handlers, 679 unsigned numHandlers) { 680 std::size_t Size = sizeof(CXXTryStmt); 681 Size += ((numHandlers + 1) * sizeof(Stmt)); 682 683 void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>()); 684 return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers); 685 } 686 687 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty, 688 unsigned numHandlers) { 689 std::size_t Size = sizeof(CXXTryStmt); 690 Size += ((numHandlers + 1) * sizeof(Stmt)); 691 692 void *Mem = C.Allocate(Size, llvm::alignOf<CXXTryStmt>()); 693 return new (Mem) CXXTryStmt(Empty, numHandlers); 694 } 695 696 CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, 697 Stmt **handlers, unsigned numHandlers) 698 : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) { 699 Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1); 700 Stmts[0] = tryBlock; 701 std::copy(handlers, handlers + NumHandlers, Stmts + 1); 702 } 703 704 CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt, 705 Expr *Cond, Expr *Inc, DeclStmt *LoopVar, 706 Stmt *Body, SourceLocation FL, 707 SourceLocation CL, SourceLocation RPL) 708 : Stmt(CXXForRangeStmtClass), ForLoc(FL), ColonLoc(CL), RParenLoc(RPL) { 709 SubExprs[RANGE] = Range; 710 SubExprs[BEGINEND] = BeginEndStmt; 711 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 712 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 713 SubExprs[LOOPVAR] = LoopVar; 714 SubExprs[BODY] = Body; 715 } 716 717 Expr *CXXForRangeStmt::getRangeInit() { 718 DeclStmt *RangeStmt = getRangeStmt(); 719 VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl()); 720 assert(RangeDecl &&& "for-range should have a single var decl"); 721 return RangeDecl->getInit(); 722 } 723 724 const Expr *CXXForRangeStmt::getRangeInit() const { 725 return const_cast<CXXForRangeStmt*>(this)->getRangeInit(); 726 } 727 728 VarDecl *CXXForRangeStmt::getLoopVariable() { 729 Decl *LV = cast<DeclStmt>(getLoopVarStmt())->getSingleDecl(); 730 assert(LV && "No loop variable in CXXForRangeStmt"); 731 return cast<VarDecl>(LV); 732 } 733 734 const VarDecl *CXXForRangeStmt::getLoopVariable() const { 735 return const_cast<CXXForRangeStmt*>(this)->getLoopVariable(); 736 } 737 738 IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 739 Stmt *then, SourceLocation EL, Stmt *elsev) 740 : Stmt(IfStmtClass), IfLoc(IL), ElseLoc(EL) 741 { 742 setConditionVariable(C, var); 743 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 744 SubExprs[THEN] = then; 745 SubExprs[ELSE] = elsev; 746 } 747 748 VarDecl *IfStmt::getConditionVariable() const { 749 if (!SubExprs[VAR]) 750 return 0; 751 752 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]); 753 return cast<VarDecl>(DS->getSingleDecl()); 754 } 755 756 void IfStmt::setConditionVariable(ASTContext &C, VarDecl *V) { 757 if (!V) { 758 SubExprs[VAR] = 0; 759 return; 760 } 761 762 SourceRange VarRange = V->getSourceRange(); 763 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), 764 VarRange.getEnd()); 765 } 766 767 ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, 768 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, 769 SourceLocation RP) 770 : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP) 771 { 772 SubExprs[INIT] = Init; 773 setConditionVariable(C, condVar); 774 SubExprs[COND] = reinterpret_cast<Stmt*>(Cond); 775 SubExprs[INC] = reinterpret_cast<Stmt*>(Inc); 776 SubExprs[BODY] = Body; 777 } 778 779 VarDecl *ForStmt::getConditionVariable() const { 780 if (!SubExprs[CONDVAR]) 781 return 0; 782 783 DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]); 784 return cast<VarDecl>(DS->getSingleDecl()); 785 } 786 787 void ForStmt::setConditionVariable(ASTContext &C, VarDecl *V) { 788 if (!V) { 789 SubExprs[CONDVAR] = 0; 790 return; 791 } 792 793 SourceRange VarRange = V->getSourceRange(); 794 SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), 795 VarRange.getEnd()); 796 } 797 798 SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond) 799 : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0) 800 { 801 setConditionVariable(C, Var); 802 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 803 SubExprs[BODY] = NULL; 804 } 805 806 VarDecl *SwitchStmt::getConditionVariable() const { 807 if (!SubExprs[VAR]) 808 return 0; 809 810 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]); 811 return cast<VarDecl>(DS->getSingleDecl()); 812 } 813 814 void SwitchStmt::setConditionVariable(ASTContext &C, VarDecl *V) { 815 if (!V) { 816 SubExprs[VAR] = 0; 817 return; 818 } 819 820 SourceRange VarRange = V->getSourceRange(); 821 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), 822 VarRange.getEnd()); 823 } 824 825 Stmt *SwitchCase::getSubStmt() { 826 if (isa<CaseStmt>(this)) 827 return cast<CaseStmt>(this)->getSubStmt(); 828 return cast<DefaultStmt>(this)->getSubStmt(); 829 } 830 831 WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 832 SourceLocation WL) 833 : Stmt(WhileStmtClass) { 834 setConditionVariable(C, Var); 835 SubExprs[COND] = reinterpret_cast<Stmt*>(cond); 836 SubExprs[BODY] = body; 837 WhileLoc = WL; 838 } 839 840 VarDecl *WhileStmt::getConditionVariable() const { 841 if (!SubExprs[VAR]) 842 return 0; 843 844 DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]); 845 return cast<VarDecl>(DS->getSingleDecl()); 846 } 847 848 void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) { 849 if (!V) { 850 SubExprs[VAR] = 0; 851 return; 852 } 853 854 SourceRange VarRange = V->getSourceRange(); 855 SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), 856 VarRange.getEnd()); 857 } 858 859 // IndirectGotoStmt 860 LabelDecl *IndirectGotoStmt::getConstantTarget() { 861 if (AddrLabelExpr *E = 862 dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts())) 863 return E->getLabel(); 864 return 0; 865 } 866 867 // ReturnStmt 868 const Expr* ReturnStmt::getRetValue() const { 869 return cast_or_null<Expr>(RetExpr); 870 } 871 Expr* ReturnStmt::getRetValue() { 872 return cast_or_null<Expr>(RetExpr); 873 } 874 875 SEHTryStmt::SEHTryStmt(bool IsCXXTry, 876 SourceLocation TryLoc, 877 Stmt *TryBlock, 878 Stmt *Handler) 879 : Stmt(SEHTryStmtClass), 880 IsCXXTry(IsCXXTry), 881 TryLoc(TryLoc) 882 { 883 Children[TRY] = TryBlock; 884 Children[HANDLER] = Handler; 885 } 886 887 SEHTryStmt* SEHTryStmt::Create(ASTContext &C, 888 bool IsCXXTry, 889 SourceLocation TryLoc, 890 Stmt *TryBlock, 891 Stmt *Handler) { 892 return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler); 893 } 894 895 SEHExceptStmt* SEHTryStmt::getExceptHandler() const { 896 return dyn_cast<SEHExceptStmt>(getHandler()); 897 } 898 899 SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const { 900 return dyn_cast<SEHFinallyStmt>(getHandler()); 901 } 902 903 SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, 904 Expr *FilterExpr, 905 Stmt *Block) 906 : Stmt(SEHExceptStmtClass), 907 Loc(Loc) 908 { 909 Children[FILTER_EXPR] = reinterpret_cast<Stmt*>(FilterExpr); 910 Children[BLOCK] = Block; 911 } 912 913 SEHExceptStmt* SEHExceptStmt::Create(ASTContext &C, 914 SourceLocation Loc, 915 Expr *FilterExpr, 916 Stmt *Block) { 917 return new(C) SEHExceptStmt(Loc,FilterExpr,Block); 918 } 919 920 SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, 921 Stmt *Block) 922 : Stmt(SEHFinallyStmtClass), 923 Loc(Loc), 924 Block(Block) 925 {} 926 927 SEHFinallyStmt* SEHFinallyStmt::Create(ASTContext &C, 928 SourceLocation Loc, 929 Stmt *Block) { 930 return new(C)SEHFinallyStmt(Loc,Block); 931 } 932