1 //===- ScopeInfo.h - Information about a semantic context -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines FunctionScopeInfo and its subclasses, which contain 10 // information about a single function, block, lambda, or method body. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_SEMA_SCOPEINFO_H 15 #define LLVM_CLANG_SEMA_SCOPEINFO_H 16 17 #include "clang/AST/Expr.h" 18 #include "clang/AST/ExprCXX.h" 19 #include "clang/AST/Type.h" 20 #include "clang/Basic/CapturedStmt.h" 21 #include "clang/Basic/LLVM.h" 22 #include "clang/Basic/PartialDiagnostic.h" 23 #include "clang/Basic/SourceLocation.h" 24 #include "clang/Sema/CleanupInfo.h" 25 #include "clang/Sema/DeclSpec.h" 26 #include "llvm/ADT/DenseMap.h" 27 #include "llvm/ADT/DenseMapInfo.h" 28 #include "llvm/ADT/MapVector.h" 29 #include "llvm/ADT/PointerIntPair.h" 30 #include "llvm/ADT/SmallPtrSet.h" 31 #include "llvm/ADT/SmallSet.h" 32 #include "llvm/ADT/SmallVector.h" 33 #include "llvm/ADT/StringRef.h" 34 #include "llvm/ADT/StringSwitch.h" 35 #include "llvm/ADT/TinyPtrVector.h" 36 #include "llvm/Support/Casting.h" 37 #include "llvm/Support/ErrorHandling.h" 38 #include <algorithm> 39 #include <cassert> 40 #include <utility> 41 42 namespace clang { 43 44 class BlockDecl; 45 class CapturedDecl; 46 class CXXMethodDecl; 47 class CXXRecordDecl; 48 class ImplicitParamDecl; 49 class NamedDecl; 50 class ObjCIvarRefExpr; 51 class ObjCMessageExpr; 52 class ObjCPropertyDecl; 53 class ObjCPropertyRefExpr; 54 class ParmVarDecl; 55 class RecordDecl; 56 class ReturnStmt; 57 class Scope; 58 class Stmt; 59 class SwitchStmt; 60 class TemplateParameterList; 61 class VarDecl; 62 63 namespace sema { 64 65 /// Contains information about the compound statement currently being 66 /// parsed. 67 class CompoundScopeInfo { 68 public: 69 /// Whether this compound stamement contains `for' or `while' loops 70 /// with empty bodies. 71 bool HasEmptyLoopBodies = false; 72 73 /// Whether this compound statement corresponds to a GNU statement 74 /// expression. 75 bool IsStmtExpr; 76 77 /// FP options at the beginning of the compound statement, prior to 78 /// any pragma. 79 FPOptions InitialFPFeatures; 80 81 CompoundScopeInfo(bool IsStmtExpr, FPOptions FPO) 82 : IsStmtExpr(IsStmtExpr), InitialFPFeatures(FPO) {} 83 84 void setHasEmptyLoopBodies() { 85 HasEmptyLoopBodies = true; 86 } 87 }; 88 89 class PossiblyUnreachableDiag { 90 public: 91 PartialDiagnostic PD; 92 SourceLocation Loc; 93 llvm::TinyPtrVector<const Stmt*> Stmts; 94 95 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 96 ArrayRef<const Stmt *> Stmts) 97 : PD(PD), Loc(Loc), Stmts(Stmts) {} 98 }; 99 100 /// Retains information about a function, method, or block that is 101 /// currently being parsed. 102 class FunctionScopeInfo { 103 protected: 104 enum ScopeKind { 105 SK_Function, 106 SK_Block, 107 SK_Lambda, 108 SK_CapturedRegion 109 }; 110 111 public: 112 /// What kind of scope we are describing. 113 ScopeKind Kind : 3; 114 115 /// Whether this function contains a VLA, \@try, try, C++ 116 /// initializer, or anything else that can't be jumped past. 117 bool HasBranchProtectedScope : 1; 118 119 /// Whether this function contains any switches or direct gotos. 120 bool HasBranchIntoScope : 1; 121 122 /// Whether this function contains any indirect gotos. 123 bool HasIndirectGoto : 1; 124 125 /// Whether this function contains any statement marked with 126 /// \c [[clang::musttail]]. 127 bool HasMustTail : 1; 128 129 /// Whether a statement was dropped because it was invalid. 130 bool HasDroppedStmt : 1; 131 132 /// True if current scope is for OpenMP declare reduction combiner. 133 bool HasOMPDeclareReductionCombiner : 1; 134 135 /// Whether there is a fallthrough statement in this function. 136 bool HasFallthroughStmt : 1; 137 138 /// Whether this function uses constrained floating point intrinsics 139 bool UsesFPIntrin : 1; 140 141 /// Whether we make reference to a declaration that could be 142 /// unavailable. 143 bool HasPotentialAvailabilityViolations : 1; 144 145 /// A flag that is set when parsing a method that must call super's 146 /// implementation, such as \c -dealloc, \c -finalize, or any method marked 147 /// with \c __attribute__((objc_requires_super)). 148 bool ObjCShouldCallSuper : 1; 149 150 /// True when this is a method marked as a designated initializer. 151 bool ObjCIsDesignatedInit : 1; 152 153 /// This starts true for a method marked as designated initializer and will 154 /// be set to false if there is an invocation to a designated initializer of 155 /// the super class. 156 bool ObjCWarnForNoDesignatedInitChain : 1; 157 158 /// True when this is an initializer method not marked as a designated 159 /// initializer within a class that has at least one initializer marked as a 160 /// designated initializer. 161 bool ObjCIsSecondaryInit : 1; 162 163 /// This starts true for a secondary initializer method and will be set to 164 /// false if there is an invocation of an initializer on 'self'. 165 bool ObjCWarnForNoInitDelegation : 1; 166 167 /// True only when this function has not already built, or attempted 168 /// to build, the initial and final coroutine suspend points 169 bool NeedsCoroutineSuspends : 1; 170 171 /// An enumeration represeting the kind of the first coroutine statement 172 /// in the function. One of co_return, co_await, or co_yield. 173 unsigned char FirstCoroutineStmtKind : 2; 174 175 /// First coroutine statement in the current function. 176 /// (ex co_return, co_await, co_yield) 177 SourceLocation FirstCoroutineStmtLoc; 178 179 /// First 'return' statement in the current function. 180 SourceLocation FirstReturnLoc; 181 182 /// First C++ 'try' or ObjC @try statement in the current function. 183 SourceLocation FirstCXXOrObjCTryLoc; 184 enum { TryLocIsCXX, TryLocIsObjC, Unknown } FirstTryType = Unknown; 185 186 /// First SEH '__try' statement in the current function. 187 SourceLocation FirstSEHTryLoc; 188 189 private: 190 /// Used to determine if errors occurred in this function or block. 191 DiagnosticErrorTrap ErrorTrap; 192 193 public: 194 /// A SwitchStmt, along with a flag indicating if its list of case statements 195 /// is incomplete (because we dropped an invalid one while parsing). 196 using SwitchInfo = llvm::PointerIntPair<SwitchStmt*, 1, bool>; 197 198 /// SwitchStack - This is the current set of active switch statements in the 199 /// block. 200 SmallVector<SwitchInfo, 8> SwitchStack; 201 202 /// The list of return statements that occur within the function or 203 /// block, if there is any chance of applying the named return value 204 /// optimization, or if we need to infer a return type. 205 SmallVector<ReturnStmt*, 4> Returns; 206 207 /// The promise object for this coroutine, if any. 208 VarDecl *CoroutinePromise = nullptr; 209 210 /// A mapping between the coroutine function parameters that were moved 211 /// to the coroutine frame, and their move statements. 212 llvm::SmallMapVector<ParmVarDecl *, Stmt *, 4> CoroutineParameterMoves; 213 214 /// The initial and final coroutine suspend points. 215 std::pair<Stmt *, Stmt *> CoroutineSuspends; 216 217 /// The stack of currently active compound stamement scopes in the 218 /// function. 219 SmallVector<CompoundScopeInfo, 4> CompoundScopes; 220 221 /// The set of blocks that are introduced in this function. 222 llvm::SmallPtrSet<const BlockDecl *, 1> Blocks; 223 224 /// The set of __block variables that are introduced in this function. 225 llvm::TinyPtrVector<VarDecl *> ByrefBlockVars; 226 227 /// A list of PartialDiagnostics created but delayed within the 228 /// current function scope. These diagnostics are vetted for reachability 229 /// prior to being emitted. 230 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 231 232 /// A list of parameters which have the nonnull attribute and are 233 /// modified in the function. 234 llvm::SmallPtrSet<const ParmVarDecl *, 8> ModifiedNonNullParams; 235 236 /// The set of GNU address of label extension "&&label". 237 llvm::SmallVector<AddrLabelExpr *, 4> AddrLabels; 238 239 public: 240 /// Represents a simple identification of a weak object. 241 /// 242 /// Part of the implementation of -Wrepeated-use-of-weak. 243 /// 244 /// This is used to determine if two weak accesses refer to the same object. 245 /// Here are some examples of how various accesses are "profiled": 246 /// 247 /// Access Expression | "Base" Decl | "Property" Decl 248 /// :---------------: | :-----------------: | :------------------------------: 249 /// self.property | self (VarDecl) | property (ObjCPropertyDecl) 250 /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl) 251 /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl) 252 /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl) 253 /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) 254 /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) 255 /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) 256 /// MyClass.foo.prop | +foo (ObjCMethodDecl) | -prop (ObjCPropertyDecl) 257 /// weakVar | 0 (known) | weakVar (VarDecl) 258 /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) 259 /// 260 /// Objects are identified with only two Decls to make it reasonably fast to 261 /// compare them. 262 class WeakObjectProfileTy { 263 /// The base object decl, as described in the class documentation. 264 /// 265 /// The extra flag is "true" if the Base and Property are enough to uniquely 266 /// identify the object in memory. 267 /// 268 /// \sa isExactProfile() 269 using BaseInfoTy = llvm::PointerIntPair<const NamedDecl *, 1, bool>; 270 BaseInfoTy Base; 271 272 /// The "property" decl, as described in the class documentation. 273 /// 274 /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the 275 /// case of "implicit" properties (regular methods accessed via dot syntax). 276 const NamedDecl *Property = nullptr; 277 278 /// Used to find the proper base profile for a given base expression. 279 static BaseInfoTy getBaseInfo(const Expr *BaseE); 280 281 inline WeakObjectProfileTy(); 282 static inline WeakObjectProfileTy getSentinel(); 283 284 public: 285 WeakObjectProfileTy(const ObjCPropertyRefExpr *RE); 286 WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property); 287 WeakObjectProfileTy(const DeclRefExpr *RE); 288 WeakObjectProfileTy(const ObjCIvarRefExpr *RE); 289 290 const NamedDecl *getBase() const { return Base.getPointer(); } 291 const NamedDecl *getProperty() const { return Property; } 292 293 /// Returns true if the object base specifies a known object in memory, 294 /// rather than, say, an instance variable or property of another object. 295 /// 296 /// Note that this ignores the effects of aliasing; that is, \c foo.bar is 297 /// considered an exact profile if \c foo is a local variable, even if 298 /// another variable \c foo2 refers to the same object as \c foo. 299 /// 300 /// For increased precision, accesses with base variables that are 301 /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to 302 /// be exact, though this is not true for arbitrary variables 303 /// (foo.prop1.prop2). 304 bool isExactProfile() const { 305 return Base.getInt(); 306 } 307 308 bool operator==(const WeakObjectProfileTy &Other) const { 309 return Base == Other.Base && Property == Other.Property; 310 } 311 312 // For use in DenseMap. 313 // We can't specialize the usual llvm::DenseMapInfo at the end of the file 314 // because by that point the DenseMap in FunctionScopeInfo has already been 315 // instantiated. 316 class DenseMapInfo { 317 public: 318 static inline WeakObjectProfileTy getEmptyKey() { 319 return WeakObjectProfileTy(); 320 } 321 322 static inline WeakObjectProfileTy getTombstoneKey() { 323 return WeakObjectProfileTy::getSentinel(); 324 } 325 326 static unsigned getHashValue(const WeakObjectProfileTy &Val) { 327 using Pair = std::pair<BaseInfoTy, const NamedDecl *>; 328 329 return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, 330 Val.Property)); 331 } 332 333 static bool isEqual(const WeakObjectProfileTy &LHS, 334 const WeakObjectProfileTy &RHS) { 335 return LHS == RHS; 336 } 337 }; 338 }; 339 340 /// Represents a single use of a weak object. 341 /// 342 /// Stores both the expression and whether the access is potentially unsafe 343 /// (i.e. it could potentially be warned about). 344 /// 345 /// Part of the implementation of -Wrepeated-use-of-weak. 346 class WeakUseTy { 347 llvm::PointerIntPair<const Expr *, 1, bool> Rep; 348 349 public: 350 WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {} 351 352 const Expr *getUseExpr() const { return Rep.getPointer(); } 353 bool isUnsafe() const { return Rep.getInt(); } 354 void markSafe() { Rep.setInt(false); } 355 356 bool operator==(const WeakUseTy &Other) const { 357 return Rep == Other.Rep; 358 } 359 }; 360 361 /// Used to collect uses of a particular weak object in a function body. 362 /// 363 /// Part of the implementation of -Wrepeated-use-of-weak. 364 using WeakUseVector = SmallVector<WeakUseTy, 4>; 365 366 /// Used to collect all uses of weak objects in a function body. 367 /// 368 /// Part of the implementation of -Wrepeated-use-of-weak. 369 using WeakObjectUseMap = 370 llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8, 371 WeakObjectProfileTy::DenseMapInfo>; 372 373 private: 374 /// Used to collect all uses of weak objects in this function body. 375 /// 376 /// Part of the implementation of -Wrepeated-use-of-weak. 377 WeakObjectUseMap WeakObjectUses; 378 379 protected: 380 FunctionScopeInfo(const FunctionScopeInfo&) = default; 381 382 public: 383 FunctionScopeInfo(DiagnosticsEngine &Diag) 384 : Kind(SK_Function), HasBranchProtectedScope(false), 385 HasBranchIntoScope(false), HasIndirectGoto(false), HasMustTail(false), 386 HasDroppedStmt(false), HasOMPDeclareReductionCombiner(false), 387 HasFallthroughStmt(false), UsesFPIntrin(false), 388 HasPotentialAvailabilityViolations(false), ObjCShouldCallSuper(false), 389 ObjCIsDesignatedInit(false), ObjCWarnForNoDesignatedInitChain(false), 390 ObjCIsSecondaryInit(false), ObjCWarnForNoInitDelegation(false), 391 NeedsCoroutineSuspends(true), ErrorTrap(Diag) {} 392 393 virtual ~FunctionScopeInfo(); 394 395 /// Determine whether an unrecoverable error has occurred within this 396 /// function. Note that this may return false even if the function body is 397 /// invalid, because the errors may be suppressed if they're caused by prior 398 /// invalid declarations. 399 /// 400 /// FIXME: Migrate the caller of this to use containsErrors() instead once 401 /// it's ready. 402 bool hasUnrecoverableErrorOccurred() const { 403 return ErrorTrap.hasUnrecoverableErrorOccurred(); 404 } 405 406 /// Record that a weak object was accessed. 407 /// 408 /// Part of the implementation of -Wrepeated-use-of-weak. 409 template <typename ExprT> 410 inline void recordUseOfWeak(const ExprT *E, bool IsRead = true); 411 412 void recordUseOfWeak(const ObjCMessageExpr *Msg, 413 const ObjCPropertyDecl *Prop); 414 415 /// Record that a given expression is a "safe" access of a weak object (e.g. 416 /// assigning it to a strong variable.) 417 /// 418 /// Part of the implementation of -Wrepeated-use-of-weak. 419 void markSafeWeakUse(const Expr *E); 420 421 const WeakObjectUseMap &getWeakObjectUses() const { 422 return WeakObjectUses; 423 } 424 425 void setHasBranchIntoScope() { 426 HasBranchIntoScope = true; 427 } 428 429 void setHasBranchProtectedScope() { 430 HasBranchProtectedScope = true; 431 } 432 433 void setHasIndirectGoto() { 434 HasIndirectGoto = true; 435 } 436 437 void setHasMustTail() { HasMustTail = true; } 438 439 void setHasDroppedStmt() { 440 HasDroppedStmt = true; 441 } 442 443 void setHasOMPDeclareReductionCombiner() { 444 HasOMPDeclareReductionCombiner = true; 445 } 446 447 void setHasFallthroughStmt() { 448 HasFallthroughStmt = true; 449 } 450 451 void setUsesFPIntrin() { 452 UsesFPIntrin = true; 453 } 454 455 void setHasCXXTry(SourceLocation TryLoc) { 456 setHasBranchProtectedScope(); 457 FirstCXXOrObjCTryLoc = TryLoc; 458 FirstTryType = TryLocIsCXX; 459 } 460 461 void setHasObjCTry(SourceLocation TryLoc) { 462 setHasBranchProtectedScope(); 463 FirstCXXOrObjCTryLoc = TryLoc; 464 FirstTryType = TryLocIsObjC; 465 } 466 467 void setHasSEHTry(SourceLocation TryLoc) { 468 setHasBranchProtectedScope(); 469 FirstSEHTryLoc = TryLoc; 470 } 471 472 bool NeedsScopeChecking() const { 473 return !HasDroppedStmt && (HasIndirectGoto || HasMustTail || 474 (HasBranchProtectedScope && HasBranchIntoScope)); 475 } 476 477 // Add a block introduced in this function. 478 void addBlock(const BlockDecl *BD) { 479 Blocks.insert(BD); 480 } 481 482 // Add a __block variable introduced in this function. 483 void addByrefBlockVar(VarDecl *VD) { 484 ByrefBlockVars.push_back(VD); 485 } 486 487 bool isCoroutine() const { return !FirstCoroutineStmtLoc.isInvalid(); } 488 489 void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword) { 490 assert(FirstCoroutineStmtLoc.isInvalid() && 491 "first coroutine statement location already set"); 492 FirstCoroutineStmtLoc = Loc; 493 FirstCoroutineStmtKind = llvm::StringSwitch<unsigned char>(Keyword) 494 .Case("co_return", 0) 495 .Case("co_await", 1) 496 .Case("co_yield", 2); 497 } 498 499 StringRef getFirstCoroutineStmtKeyword() const { 500 assert(FirstCoroutineStmtLoc.isValid() 501 && "no coroutine statement available"); 502 switch (FirstCoroutineStmtKind) { 503 case 0: return "co_return"; 504 case 1: return "co_await"; 505 case 2: return "co_yield"; 506 default: 507 llvm_unreachable("FirstCoroutineStmtKind has an invalid value"); 508 }; 509 } 510 511 void setNeedsCoroutineSuspends(bool value = true) { 512 assert((!value || CoroutineSuspends.first == nullptr) && 513 "we already have valid suspend points"); 514 NeedsCoroutineSuspends = value; 515 } 516 517 bool hasInvalidCoroutineSuspends() const { 518 return !NeedsCoroutineSuspends && CoroutineSuspends.first == nullptr; 519 } 520 521 void setCoroutineSuspends(Stmt *Initial, Stmt *Final) { 522 assert(Initial && Final && "suspend points cannot be null"); 523 assert(CoroutineSuspends.first == nullptr && "suspend points already set"); 524 NeedsCoroutineSuspends = false; 525 CoroutineSuspends.first = Initial; 526 CoroutineSuspends.second = Final; 527 } 528 529 /// Clear out the information in this function scope, making it 530 /// suitable for reuse. 531 void Clear(); 532 533 bool isPlainFunction() const { return Kind == SK_Function; } 534 }; 535 536 class Capture { 537 // There are three categories of capture: capturing 'this', capturing 538 // local variables, and C++1y initialized captures (which can have an 539 // arbitrary initializer, and don't really capture in the traditional 540 // sense at all). 541 // 542 // There are three ways to capture a local variable: 543 // - capture by copy in the C++11 sense, 544 // - capture by reference in the C++11 sense, and 545 // - __block capture. 546 // Lambdas explicitly specify capture by copy or capture by reference. 547 // For blocks, __block capture applies to variables with that annotation, 548 // variables of reference type are captured by reference, and other 549 // variables are captured by copy. 550 enum CaptureKind { 551 Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA 552 }; 553 554 union { 555 /// If Kind == Cap_VLA, the captured type. 556 const VariableArrayType *CapturedVLA; 557 558 /// Otherwise, the captured variable (if any). 559 ValueDecl *CapturedVar; 560 }; 561 562 /// The source location at which the first capture occurred. 563 SourceLocation Loc; 564 565 /// The location of the ellipsis that expands a parameter pack. 566 SourceLocation EllipsisLoc; 567 568 /// The type as it was captured, which is the type of the non-static data 569 /// member that would hold the capture. 570 QualType CaptureType; 571 572 /// The CaptureKind of this capture. 573 unsigned Kind : 2; 574 575 /// Whether this is a nested capture (a capture of an enclosing capturing 576 /// scope's capture). 577 unsigned Nested : 1; 578 579 /// Whether this is a capture of '*this'. 580 unsigned CapturesThis : 1; 581 582 /// Whether an explicit capture has been odr-used in the body of the 583 /// lambda. 584 unsigned ODRUsed : 1; 585 586 /// Whether an explicit capture has been non-odr-used in the body of 587 /// the lambda. 588 unsigned NonODRUsed : 1; 589 590 /// Whether the capture is invalid (a capture was required but the entity is 591 /// non-capturable). 592 unsigned Invalid : 1; 593 594 public: 595 Capture(ValueDecl *Var, bool Block, bool ByRef, bool IsNested, 596 SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, 597 bool Invalid) 598 : CapturedVar(Var), Loc(Loc), EllipsisLoc(EllipsisLoc), 599 CaptureType(CaptureType), Kind(Block ? Cap_Block 600 : ByRef ? Cap_ByRef 601 : Cap_ByCopy), 602 Nested(IsNested), CapturesThis(false), ODRUsed(false), 603 NonODRUsed(false), Invalid(Invalid) {} 604 605 enum IsThisCapture { ThisCapture }; 606 Capture(IsThisCapture, bool IsNested, SourceLocation Loc, 607 QualType CaptureType, const bool ByCopy, bool Invalid) 608 : Loc(Loc), CaptureType(CaptureType), 609 Kind(ByCopy ? Cap_ByCopy : Cap_ByRef), Nested(IsNested), 610 CapturesThis(true), ODRUsed(false), NonODRUsed(false), 611 Invalid(Invalid) {} 612 613 enum IsVLACapture { VLACapture }; 614 Capture(IsVLACapture, const VariableArrayType *VLA, bool IsNested, 615 SourceLocation Loc, QualType CaptureType) 616 : CapturedVLA(VLA), Loc(Loc), CaptureType(CaptureType), Kind(Cap_VLA), 617 Nested(IsNested), CapturesThis(false), ODRUsed(false), 618 NonODRUsed(false), Invalid(false) {} 619 620 bool isThisCapture() const { return CapturesThis; } 621 bool isVariableCapture() const { 622 return !isThisCapture() && !isVLATypeCapture(); 623 } 624 625 bool isCopyCapture() const { return Kind == Cap_ByCopy; } 626 bool isReferenceCapture() const { return Kind == Cap_ByRef; } 627 bool isBlockCapture() const { return Kind == Cap_Block; } 628 bool isVLATypeCapture() const { return Kind == Cap_VLA; } 629 630 bool isNested() const { return Nested; } 631 632 bool isInvalid() const { return Invalid; } 633 634 /// Determine whether this capture is an init-capture. 635 bool isInitCapture() const; 636 637 bool isODRUsed() const { return ODRUsed; } 638 bool isNonODRUsed() const { return NonODRUsed; } 639 void markUsed(bool IsODRUse) { 640 if (IsODRUse) 641 ODRUsed = true; 642 else 643 NonODRUsed = true; 644 } 645 646 ValueDecl *getVariable() const { 647 assert(isVariableCapture()); 648 return CapturedVar; 649 } 650 651 const VariableArrayType *getCapturedVLAType() const { 652 assert(isVLATypeCapture()); 653 return CapturedVLA; 654 } 655 656 /// Retrieve the location at which this variable was captured. 657 SourceLocation getLocation() const { return Loc; } 658 659 /// Retrieve the source location of the ellipsis, whose presence 660 /// indicates that the capture is a pack expansion. 661 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 662 663 /// Retrieve the capture type for this capture, which is effectively 664 /// the type of the non-static data member in the lambda/block structure 665 /// that would store this capture. 666 QualType getCaptureType() const { return CaptureType; } 667 }; 668 669 class CapturingScopeInfo : public FunctionScopeInfo { 670 protected: 671 CapturingScopeInfo(const CapturingScopeInfo&) = default; 672 673 public: 674 enum ImplicitCaptureStyle { 675 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block, 676 ImpCap_CapturedRegion 677 }; 678 679 ImplicitCaptureStyle ImpCaptureStyle; 680 681 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 682 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {} 683 684 /// CaptureMap - A map of captured variables to (index+1) into Captures. 685 llvm::DenseMap<ValueDecl *, unsigned> CaptureMap; 686 687 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 688 /// zero if 'this' is not captured. 689 unsigned CXXThisCaptureIndex = 0; 690 691 /// Captures - The captures. 692 SmallVector<Capture, 4> Captures; 693 694 /// - Whether the target type of return statements in this context 695 /// is deduced (e.g. a lambda or block with omitted return type). 696 bool HasImplicitReturnType = false; 697 698 /// ReturnType - The target type of return statements in this context, 699 /// or null if unknown. 700 QualType ReturnType; 701 702 void addCapture(ValueDecl *Var, bool isBlock, bool isByref, bool isNested, 703 SourceLocation Loc, SourceLocation EllipsisLoc, 704 QualType CaptureType, bool Invalid) { 705 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 706 EllipsisLoc, CaptureType, Invalid)); 707 CaptureMap[Var] = Captures.size(); 708 } 709 710 void addVLATypeCapture(SourceLocation Loc, const VariableArrayType *VLAType, 711 QualType CaptureType) { 712 Captures.push_back(Capture(Capture::VLACapture, VLAType, 713 /*FIXME: IsNested*/ false, Loc, CaptureType)); 714 } 715 716 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, 717 bool ByCopy); 718 719 /// Determine whether the C++ 'this' is captured. 720 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 721 722 /// Retrieve the capture of C++ 'this', if it has been captured. 723 Capture &getCXXThisCapture() { 724 assert(isCXXThisCaptured() && "this has not been captured"); 725 return Captures[CXXThisCaptureIndex - 1]; 726 } 727 728 /// Determine whether the given variable has been captured. 729 bool isCaptured(ValueDecl *Var) const { return CaptureMap.count(Var); } 730 731 /// Determine whether the given variable-array type has been captured. 732 bool isVLATypeCaptured(const VariableArrayType *VAT) const; 733 734 /// Retrieve the capture of the given variable, if it has been 735 /// captured already. 736 Capture &getCapture(ValueDecl *Var) { 737 assert(isCaptured(Var) && "Variable has not been captured"); 738 return Captures[CaptureMap[Var] - 1]; 739 } 740 741 const Capture &getCapture(ValueDecl *Var) const { 742 llvm::DenseMap<ValueDecl *, unsigned>::const_iterator Known = 743 CaptureMap.find(Var); 744 assert(Known != CaptureMap.end() && "Variable has not been captured"); 745 return Captures[Known->second - 1]; 746 } 747 748 static bool classof(const FunctionScopeInfo *FSI) { 749 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda 750 || FSI->Kind == SK_CapturedRegion; 751 } 752 }; 753 754 /// Retains information about a block that is currently being parsed. 755 class BlockScopeInfo final : public CapturingScopeInfo { 756 public: 757 BlockDecl *TheDecl; 758 759 /// TheScope - This is the scope for the block itself, which contains 760 /// arguments etc. 761 Scope *TheScope; 762 763 /// BlockType - The function type of the block, if one was given. 764 /// Its return type may be BuiltinType::Dependent. 765 QualType FunctionType; 766 767 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 768 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 769 TheScope(BlockScope) { 770 Kind = SK_Block; 771 } 772 773 ~BlockScopeInfo() override; 774 775 static bool classof(const FunctionScopeInfo *FSI) { 776 return FSI->Kind == SK_Block; 777 } 778 }; 779 780 /// Retains information about a captured region. 781 class CapturedRegionScopeInfo final : public CapturingScopeInfo { 782 public: 783 /// The CapturedDecl for this statement. 784 CapturedDecl *TheCapturedDecl; 785 786 /// The captured record type. 787 RecordDecl *TheRecordDecl; 788 789 /// This is the enclosing scope of the captured region. 790 Scope *TheScope; 791 792 /// The implicit parameter for the captured variables. 793 ImplicitParamDecl *ContextParam; 794 795 /// The kind of captured region. 796 unsigned short CapRegionKind; 797 798 unsigned short OpenMPLevel; 799 unsigned short OpenMPCaptureLevel; 800 801 CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, 802 RecordDecl *RD, ImplicitParamDecl *Context, 803 CapturedRegionKind K, unsigned OpenMPLevel, 804 unsigned OpenMPCaptureLevel) 805 : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), 806 TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), 807 ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel), 808 OpenMPCaptureLevel(OpenMPCaptureLevel) { 809 Kind = SK_CapturedRegion; 810 } 811 812 ~CapturedRegionScopeInfo() override; 813 814 /// A descriptive name for the kind of captured region this is. 815 StringRef getRegionName() const { 816 switch (CapRegionKind) { 817 case CR_Default: 818 return "default captured statement"; 819 case CR_ObjCAtFinally: 820 return "Objective-C @finally statement"; 821 case CR_OpenMP: 822 return "OpenMP region"; 823 } 824 llvm_unreachable("Invalid captured region kind!"); 825 } 826 827 static bool classof(const FunctionScopeInfo *FSI) { 828 return FSI->Kind == SK_CapturedRegion; 829 } 830 }; 831 832 class LambdaScopeInfo final : 833 public CapturingScopeInfo, public InventedTemplateParameterInfo { 834 public: 835 /// The class that describes the lambda. 836 CXXRecordDecl *Lambda = nullptr; 837 838 /// The lambda's compiler-generated \c operator(). 839 CXXMethodDecl *CallOperator = nullptr; 840 841 /// Source range covering the lambda introducer [...]. 842 SourceRange IntroducerRange; 843 844 /// Source location of the '&' or '=' specifying the default capture 845 /// type, if any. 846 SourceLocation CaptureDefaultLoc; 847 848 /// The number of captures in the \c Captures list that are 849 /// explicit captures. 850 unsigned NumExplicitCaptures = 0; 851 852 /// Whether this is a mutable lambda. 853 bool Mutable = false; 854 855 /// Whether the (empty) parameter list is explicit. 856 bool ExplicitParams = false; 857 858 /// Whether any of the capture expressions requires cleanups. 859 CleanupInfo Cleanup; 860 861 /// Whether the lambda contains an unexpanded parameter pack. 862 bool ContainsUnexpandedParameterPack = false; 863 864 /// Packs introduced by this lambda, if any. 865 SmallVector<NamedDecl*, 4> LocalPacks; 866 867 /// Source range covering the explicit template parameter list (if it exists). 868 SourceRange ExplicitTemplateParamsRange; 869 870 /// The requires-clause immediately following the explicit template parameter 871 /// list, if any. (Note that there may be another requires-clause included as 872 /// part of the lambda-declarator.) 873 ExprResult RequiresClause; 874 875 /// If this is a generic lambda, and the template parameter 876 /// list has been created (from the TemplateParams) then store 877 /// a reference to it (cache it to avoid reconstructing it). 878 TemplateParameterList *GLTemplateParameterList = nullptr; 879 880 /// Contains all variable-referring-expressions (i.e. DeclRefExprs 881 /// or MemberExprs) that refer to local variables in a generic lambda 882 /// or a lambda in a potentially-evaluated-if-used context. 883 /// 884 /// Potentially capturable variables of a nested lambda that might need 885 /// to be captured by the lambda are housed here. 886 /// This is specifically useful for generic lambdas or 887 /// lambdas within a potentially evaluated-if-used context. 888 /// If an enclosing variable is named in an expression of a lambda nested 889 /// within a generic lambda, we don't always know whether the variable 890 /// will truly be odr-used (i.e. need to be captured) by that nested lambda, 891 /// until its instantiation. But we still need to capture it in the 892 /// enclosing lambda if all intervening lambdas can capture the variable. 893 llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs; 894 895 /// Contains all variable-referring-expressions that refer 896 /// to local variables that are usable as constant expressions and 897 /// do not involve an odr-use (they may still need to be captured 898 /// if the enclosing full-expression is instantiation dependent). 899 llvm::SmallSet<Expr *, 8> NonODRUsedCapturingExprs; 900 901 /// A map of explicit capture indices to their introducer source ranges. 902 llvm::DenseMap<unsigned, SourceRange> ExplicitCaptureRanges; 903 904 /// Contains all of the variables defined in this lambda that shadow variables 905 /// that were defined in parent contexts. Used to avoid warnings when the 906 /// shadowed variables are uncaptured by this lambda. 907 struct ShadowedOuterDecl { 908 const VarDecl *VD; 909 const VarDecl *ShadowedDecl; 910 }; 911 llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls; 912 913 SourceLocation PotentialThisCaptureLocation; 914 915 LambdaScopeInfo(DiagnosticsEngine &Diag) 916 : CapturingScopeInfo(Diag, ImpCap_None) { 917 Kind = SK_Lambda; 918 } 919 920 /// Note when all explicit captures have been added. 921 void finishedExplicitCaptures() { 922 NumExplicitCaptures = Captures.size(); 923 } 924 925 static bool classof(const FunctionScopeInfo *FSI) { 926 return FSI->Kind == SK_Lambda; 927 } 928 929 /// Is this scope known to be for a generic lambda? (This will be false until 930 /// we parse a template parameter list or the first 'auto'-typed parameter). 931 bool isGenericLambda() const { 932 return !TemplateParams.empty() || GLTemplateParameterList; 933 } 934 935 /// Add a variable that might potentially be captured by the 936 /// lambda and therefore the enclosing lambdas. 937 /// 938 /// This is also used by enclosing lambda's to speculatively capture 939 /// variables that nested lambda's - depending on their enclosing 940 /// specialization - might need to capture. 941 /// Consider: 942 /// void f(int, int); <-- don't capture 943 /// void f(const int&, double); <-- capture 944 /// void foo() { 945 /// const int x = 10; 946 /// auto L = [=](auto a) { // capture 'x' 947 /// return [=](auto b) { 948 /// f(x, a); // we may or may not need to capture 'x' 949 /// }; 950 /// }; 951 /// } 952 void addPotentialCapture(Expr *VarExpr) { 953 assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr) || 954 isa<FunctionParmPackExpr>(VarExpr)); 955 PotentiallyCapturingExprs.push_back(VarExpr); 956 } 957 958 void addPotentialThisCapture(SourceLocation Loc) { 959 PotentialThisCaptureLocation = Loc; 960 } 961 962 bool hasPotentialThisCapture() const { 963 return PotentialThisCaptureLocation.isValid(); 964 } 965 966 /// Mark a variable's reference in a lambda as non-odr using. 967 /// 968 /// For generic lambdas, if a variable is named in a potentially evaluated 969 /// expression, where the enclosing full expression is dependent then we 970 /// must capture the variable (given a default capture). 971 /// This is accomplished by recording all references to variables 972 /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of 973 /// PotentialCaptures. All such variables have to be captured by that lambda, 974 /// except for as described below. 975 /// If that variable is usable as a constant expression and is named in a 976 /// manner that does not involve its odr-use (e.g. undergoes 977 /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the 978 /// act of analyzing the enclosing full expression (ActOnFinishFullExpr) 979 /// if we can determine that the full expression is not instantiation- 980 /// dependent, then we can entirely avoid its capture. 981 /// 982 /// const int n = 0; 983 /// [&] (auto x) { 984 /// (void)+n + x; 985 /// }; 986 /// Interestingly, this strategy would involve a capture of n, even though 987 /// it's obviously not odr-used here, because the full-expression is 988 /// instantiation-dependent. It could be useful to avoid capturing such 989 /// variables, even when they are referred to in an instantiation-dependent 990 /// expression, if we can unambiguously determine that they shall never be 991 /// odr-used. This would involve removal of the variable-referring-expression 992 /// from the array of PotentialCaptures during the lvalue-to-rvalue 993 /// conversions. But per the working draft N3797, (post-chicago 2013) we must 994 /// capture such variables. 995 /// Before anyone is tempted to implement a strategy for not-capturing 'n', 996 /// consider the insightful warning in: 997 /// /cfe-commits/Week-of-Mon-20131104/092596.html 998 /// "The problem is that the set of captures for a lambda is part of the ABI 999 /// (since lambda layout can be made visible through inline functions and the 1000 /// like), and there are no guarantees as to which cases we'll manage to build 1001 /// an lvalue-to-rvalue conversion in, when parsing a template -- some 1002 /// seemingly harmless change elsewhere in Sema could cause us to start or stop 1003 /// building such a node. So we need a rule that anyone can implement and get 1004 /// exactly the same result". 1005 void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) { 1006 assert(isa<DeclRefExpr>(CapturingVarExpr) || 1007 isa<MemberExpr>(CapturingVarExpr) || 1008 isa<FunctionParmPackExpr>(CapturingVarExpr)); 1009 NonODRUsedCapturingExprs.insert(CapturingVarExpr); 1010 } 1011 bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const { 1012 assert(isa<DeclRefExpr>(CapturingVarExpr) || 1013 isa<MemberExpr>(CapturingVarExpr) || 1014 isa<FunctionParmPackExpr>(CapturingVarExpr)); 1015 return NonODRUsedCapturingExprs.count(CapturingVarExpr); 1016 } 1017 void removePotentialCapture(Expr *E) { 1018 llvm::erase_value(PotentiallyCapturingExprs, E); 1019 } 1020 void clearPotentialCaptures() { 1021 PotentiallyCapturingExprs.clear(); 1022 PotentialThisCaptureLocation = SourceLocation(); 1023 } 1024 unsigned getNumPotentialVariableCaptures() const { 1025 return PotentiallyCapturingExprs.size(); 1026 } 1027 1028 bool hasPotentialCaptures() const { 1029 return getNumPotentialVariableCaptures() || 1030 PotentialThisCaptureLocation.isValid(); 1031 } 1032 1033 void visitPotentialCaptures( 1034 llvm::function_ref<void(ValueDecl *, Expr *)> Callback) const; 1035 }; 1036 1037 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() 1038 : Base(nullptr, false) {} 1039 1040 FunctionScopeInfo::WeakObjectProfileTy 1041 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() { 1042 FunctionScopeInfo::WeakObjectProfileTy Result; 1043 Result.Base.setInt(true); 1044 return Result; 1045 } 1046 1047 template <typename ExprT> 1048 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { 1049 assert(E); 1050 WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)]; 1051 Uses.push_back(WeakUseTy(E, IsRead)); 1052 } 1053 1054 inline void CapturingScopeInfo::addThisCapture(bool isNested, 1055 SourceLocation Loc, 1056 QualType CaptureType, 1057 bool ByCopy) { 1058 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, 1059 ByCopy, /*Invalid*/ false)); 1060 CXXThisCaptureIndex = Captures.size(); 1061 } 1062 1063 } // namespace sema 1064 1065 } // namespace clang 1066 1067 #endif // LLVM_CLANG_SEMA_SCOPEINFO_H 1068