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