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