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