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