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