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