1 //===- ScopeInfo.h - Information about a semantic context -------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines FunctionScopeInfo and its subclasses, which contain
10 // information about a single function, block, lambda, or method body.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_SEMA_SCOPEINFO_H
15 #define LLVM_CLANG_SEMA_SCOPEINFO_H
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 "llvm/ADT/DenseMap.h"
26 #include "llvm/ADT/DenseMapInfo.h"
27 #include "llvm/ADT/MapVector.h"
28 #include "llvm/ADT/PointerIntPair.h"
29 #include "llvm/ADT/SmallPtrSet.h"
30 #include "llvm/ADT/SmallSet.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/ADT/StringRef.h"
33 #include "llvm/ADT/StringSwitch.h"
34 #include "llvm/ADT/TinyPtrVector.h"
35 #include "llvm/Support/Casting.h"
36 #include "llvm/Support/ErrorHandling.h"
47 class ImplicitParamDecl;
49 class ObjCIvarRefExpr;
50 class ObjCMessageExpr;
51 class ObjCPropertyDecl;
52 class ObjCPropertyRefExpr;
59 class TemplateParameterList;
60 class TemplateTypeParmDecl;
65 /// Contains information about the compound statement currently being
67 class CompoundScopeInfo {
69 /// Whether this compound stamement contains `for' or `while' loops
70 /// with empty bodies.
71 bool HasEmptyLoopBodies = false;
73 /// Whether this compound statement corresponds to a GNU statement
77 CompoundScopeInfo(bool IsStmtExpr) : IsStmtExpr(IsStmtExpr) {}
79 void setHasEmptyLoopBodies() {
80 HasEmptyLoopBodies = true;
84 class PossiblyUnreachableDiag {
88 llvm::TinyPtrVector<const Stmt*> Stmts;
90 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
91 ArrayRef<const Stmt *> Stmts)
92 : PD(PD), Loc(Loc), Stmts(Stmts) {}
95 /// Retains information about a function, method, or block that is
96 /// currently being parsed.
97 class FunctionScopeInfo {
107 /// What kind of scope we are describing.
110 /// Whether this function contains a VLA, \@try, try, C++
111 /// initializer, or anything else that can't be jumped past.
112 bool HasBranchProtectedScope : 1;
114 /// Whether this function contains any switches or direct gotos.
115 bool HasBranchIntoScope : 1;
117 /// Whether this function contains any indirect gotos.
118 bool HasIndirectGoto : 1;
120 /// Whether a statement was dropped because it was invalid.
121 bool HasDroppedStmt : 1;
123 /// True if current scope is for OpenMP declare reduction combiner.
124 bool HasOMPDeclareReductionCombiner : 1;
126 /// Whether there is a fallthrough statement in this function.
127 bool HasFallthroughStmt : 1;
129 /// Whether we make reference to a declaration that could be
131 bool HasPotentialAvailabilityViolations : 1;
133 /// A flag that is set when parsing a method that must call super's
134 /// implementation, such as \c -dealloc, \c -finalize, or any method marked
135 /// with \c __attribute__((objc_requires_super)).
136 bool ObjCShouldCallSuper : 1;
138 /// True when this is a method marked as a designated initializer.
139 bool ObjCIsDesignatedInit : 1;
141 /// This starts true for a method marked as designated initializer and will
142 /// be set to false if there is an invocation to a designated initializer of
144 bool ObjCWarnForNoDesignatedInitChain : 1;
146 /// True when this is an initializer method not marked as a designated
147 /// initializer within a class that has at least one initializer marked as a
148 /// designated initializer.
149 bool ObjCIsSecondaryInit : 1;
151 /// This starts true for a secondary initializer method and will be set to
152 /// false if there is an invocation of an initializer on 'self'.
153 bool ObjCWarnForNoInitDelegation : 1;
155 /// True only when this function has not already built, or attempted
156 /// to build, the initial and final coroutine suspend points
157 bool NeedsCoroutineSuspends : 1;
159 /// An enumeration represeting the kind of the first coroutine statement
160 /// in the function. One of co_return, co_await, or co_yield.
161 unsigned char FirstCoroutineStmtKind : 2;
163 /// First coroutine statement in the current function.
164 /// (ex co_return, co_await, co_yield)
165 SourceLocation FirstCoroutineStmtLoc;
167 /// First 'return' statement in the current function.
168 SourceLocation FirstReturnLoc;
170 /// First C++ 'try' statement in the current function.
171 SourceLocation FirstCXXTryLoc;
173 /// First SEH '__try' statement in the current function.
174 SourceLocation FirstSEHTryLoc;
176 /// Used to determine if errors occurred in this function or block.
177 DiagnosticErrorTrap ErrorTrap;
179 /// A SwitchStmt, along with a flag indicating if its list of case statements
180 /// is incomplete (because we dropped an invalid one while parsing).
181 using SwitchInfo = llvm::PointerIntPair<SwitchStmt*, 1, bool>;
183 /// SwitchStack - This is the current set of active switch statements in the
185 SmallVector<SwitchInfo, 8> SwitchStack;
187 /// The list of return statements that occur within the function or
188 /// block, if there is any chance of applying the named return value
189 /// optimization, or if we need to infer a return type.
190 SmallVector<ReturnStmt*, 4> Returns;
192 /// The promise object for this coroutine, if any.
193 VarDecl *CoroutinePromise = nullptr;
195 /// A mapping between the coroutine function parameters that were moved
196 /// to the coroutine frame, and their move statements.
197 llvm::SmallMapVector<ParmVarDecl *, Stmt *, 4> CoroutineParameterMoves;
199 /// The initial and final coroutine suspend points.
200 std::pair<Stmt *, Stmt *> CoroutineSuspends;
202 /// The stack of currently active compound stamement scopes in the
204 SmallVector<CompoundScopeInfo, 4> CompoundScopes;
206 /// The set of blocks that are introduced in this function.
207 llvm::SmallPtrSet<const BlockDecl *, 1> Blocks;
209 /// The set of __block variables that are introduced in this function.
210 llvm::TinyPtrVector<VarDecl *> ByrefBlockVars;
212 /// A list of PartialDiagnostics created but delayed within the
213 /// current function scope. These diagnostics are vetted for reachability
214 /// prior to being emitted.
215 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
217 /// A list of parameters which have the nonnull attribute and are
218 /// modified in the function.
219 llvm::SmallPtrSet<const ParmVarDecl *, 8> ModifiedNonNullParams;
222 /// Represents a simple identification of a weak object.
224 /// Part of the implementation of -Wrepeated-use-of-weak.
226 /// This is used to determine if two weak accesses refer to the same object.
227 /// Here are some examples of how various accesses are "profiled":
229 /// Access Expression | "Base" Decl | "Property" Decl
230 /// :---------------: | :-----------------: | :------------------------------:
231 /// self.property | self (VarDecl) | property (ObjCPropertyDecl)
232 /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl)
233 /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
234 /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl)
235 /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl)
236 /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl)
237 /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
238 /// MyClass.foo.prop | +foo (ObjCMethodDecl) | -prop (ObjCPropertyDecl)
239 /// weakVar | 0 (known) | weakVar (VarDecl)
240 /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl)
242 /// Objects are identified with only two Decls to make it reasonably fast to
244 class WeakObjectProfileTy {
245 /// The base object decl, as described in the class documentation.
247 /// The extra flag is "true" if the Base and Property are enough to uniquely
248 /// identify the object in memory.
250 /// \sa isExactProfile()
251 using BaseInfoTy = llvm::PointerIntPair<const NamedDecl *, 1, bool>;
254 /// The "property" decl, as described in the class documentation.
256 /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
257 /// case of "implicit" properties (regular methods accessed via dot syntax).
258 const NamedDecl *Property = nullptr;
260 /// Used to find the proper base profile for a given base expression.
261 static BaseInfoTy getBaseInfo(const Expr *BaseE);
263 inline WeakObjectProfileTy();
264 static inline WeakObjectProfileTy getSentinel();
267 WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
268 WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
269 WeakObjectProfileTy(const DeclRefExpr *RE);
270 WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
272 const NamedDecl *getBase() const { return Base.getPointer(); }
273 const NamedDecl *getProperty() const { return Property; }
275 /// Returns true if the object base specifies a known object in memory,
276 /// rather than, say, an instance variable or property of another object.
278 /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
279 /// considered an exact profile if \c foo is a local variable, even if
280 /// another variable \c foo2 refers to the same object as \c foo.
282 /// For increased precision, accesses with base variables that are
283 /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
284 /// be exact, though this is not true for arbitrary variables
285 /// (foo.prop1.prop2).
286 bool isExactProfile() const {
287 return Base.getInt();
290 bool operator==(const WeakObjectProfileTy &Other) const {
291 return Base == Other.Base && Property == Other.Property;
294 // For use in DenseMap.
295 // We can't specialize the usual llvm::DenseMapInfo at the end of the file
296 // because by that point the DenseMap in FunctionScopeInfo has already been
300 static inline WeakObjectProfileTy getEmptyKey() {
301 return WeakObjectProfileTy();
304 static inline WeakObjectProfileTy getTombstoneKey() {
305 return WeakObjectProfileTy::getSentinel();
308 static unsigned getHashValue(const WeakObjectProfileTy &Val) {
309 using Pair = std::pair<BaseInfoTy, const NamedDecl *>;
311 return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
315 static bool isEqual(const WeakObjectProfileTy &LHS,
316 const WeakObjectProfileTy &RHS) {
322 /// Represents a single use of a weak object.
324 /// Stores both the expression and whether the access is potentially unsafe
325 /// (i.e. it could potentially be warned about).
327 /// Part of the implementation of -Wrepeated-use-of-weak.
329 llvm::PointerIntPair<const Expr *, 1, bool> Rep;
332 WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
334 const Expr *getUseExpr() const { return Rep.getPointer(); }
335 bool isUnsafe() const { return Rep.getInt(); }
336 void markSafe() { Rep.setInt(false); }
338 bool operator==(const WeakUseTy &Other) const {
339 return Rep == Other.Rep;
343 /// Used to collect uses of a particular weak object in a function body.
345 /// Part of the implementation of -Wrepeated-use-of-weak.
346 using WeakUseVector = SmallVector<WeakUseTy, 4>;
348 /// Used to collect all uses of weak objects in a function body.
350 /// Part of the implementation of -Wrepeated-use-of-weak.
351 using WeakObjectUseMap =
352 llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
353 WeakObjectProfileTy::DenseMapInfo>;
356 /// Used to collect all uses of weak objects in this function body.
358 /// Part of the implementation of -Wrepeated-use-of-weak.
359 WeakObjectUseMap WeakObjectUses;
362 FunctionScopeInfo(const FunctionScopeInfo&) = default;
365 FunctionScopeInfo(DiagnosticsEngine &Diag)
366 : Kind(SK_Function), HasBranchProtectedScope(false),
367 HasBranchIntoScope(false), HasIndirectGoto(false),
368 HasDroppedStmt(false), HasOMPDeclareReductionCombiner(false),
369 HasFallthroughStmt(false), HasPotentialAvailabilityViolations(false),
370 ObjCShouldCallSuper(false), ObjCIsDesignatedInit(false),
371 ObjCWarnForNoDesignatedInitChain(false), ObjCIsSecondaryInit(false),
372 ObjCWarnForNoInitDelegation(false), NeedsCoroutineSuspends(true),
375 virtual ~FunctionScopeInfo();
377 /// Record that a weak object was accessed.
379 /// Part of the implementation of -Wrepeated-use-of-weak.
380 template <typename ExprT>
381 inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
383 void recordUseOfWeak(const ObjCMessageExpr *Msg,
384 const ObjCPropertyDecl *Prop);
386 /// Record that a given expression is a "safe" access of a weak object (e.g.
387 /// assigning it to a strong variable.)
389 /// Part of the implementation of -Wrepeated-use-of-weak.
390 void markSafeWeakUse(const Expr *E);
392 const WeakObjectUseMap &getWeakObjectUses() const {
393 return WeakObjectUses;
396 void setHasBranchIntoScope() {
397 HasBranchIntoScope = true;
400 void setHasBranchProtectedScope() {
401 HasBranchProtectedScope = true;
404 void setHasIndirectGoto() {
405 HasIndirectGoto = true;
408 void setHasDroppedStmt() {
409 HasDroppedStmt = true;
412 void setHasOMPDeclareReductionCombiner() {
413 HasOMPDeclareReductionCombiner = true;
416 void setHasFallthroughStmt() {
417 HasFallthroughStmt = true;
420 void setHasCXXTry(SourceLocation TryLoc) {
421 setHasBranchProtectedScope();
422 FirstCXXTryLoc = TryLoc;
425 void setHasSEHTry(SourceLocation TryLoc) {
426 setHasBranchProtectedScope();
427 FirstSEHTryLoc = TryLoc;
430 bool NeedsScopeChecking() const {
431 return !HasDroppedStmt &&
433 (HasBranchProtectedScope && HasBranchIntoScope));
436 // Add a block introduced in this function.
437 void addBlock(const BlockDecl *BD) {
441 // Add a __block variable introduced in this function.
442 void addByrefBlockVar(VarDecl *VD) {
443 ByrefBlockVars.push_back(VD);
446 bool isCoroutine() const { return !FirstCoroutineStmtLoc.isInvalid(); }
448 void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword) {
449 assert(FirstCoroutineStmtLoc.isInvalid() &&
450 "first coroutine statement location already set");
451 FirstCoroutineStmtLoc = Loc;
452 FirstCoroutineStmtKind = llvm::StringSwitch<unsigned char>(Keyword)
453 .Case("co_return", 0)
455 .Case("co_yield", 2);
458 StringRef getFirstCoroutineStmtKeyword() const {
459 assert(FirstCoroutineStmtLoc.isValid()
460 && "no coroutine statement available");
461 switch (FirstCoroutineStmtKind) {
462 case 0: return "co_return";
463 case 1: return "co_await";
464 case 2: return "co_yield";
466 llvm_unreachable("FirstCoroutineStmtKind has an invalid value");
470 void setNeedsCoroutineSuspends(bool value = true) {
471 assert((!value || CoroutineSuspends.first == nullptr) &&
472 "we already have valid suspend points");
473 NeedsCoroutineSuspends = value;
476 bool hasInvalidCoroutineSuspends() const {
477 return !NeedsCoroutineSuspends && CoroutineSuspends.first == nullptr;
480 void setCoroutineSuspends(Stmt *Initial, Stmt *Final) {
481 assert(Initial && Final && "suspend points cannot be null");
482 assert(CoroutineSuspends.first == nullptr && "suspend points already set");
483 NeedsCoroutineSuspends = false;
484 CoroutineSuspends.first = Initial;
485 CoroutineSuspends.second = Final;
488 /// Clear out the information in this function scope, making it
489 /// suitable for reuse.
492 bool isPlainFunction() const { return Kind == SK_Function; }
496 // There are three categories of capture: capturing 'this', capturing
497 // local variables, and C++1y initialized captures (which can have an
498 // arbitrary initializer, and don't really capture in the traditional
501 // There are three ways to capture a local variable:
502 // - capture by copy in the C++11 sense,
503 // - capture by reference in the C++11 sense, and
504 // - __block capture.
505 // Lambdas explicitly specify capture by copy or capture by reference.
506 // For blocks, __block capture applies to variables with that annotation,
507 // variables of reference type are captured by reference, and other
508 // variables are captured by copy.
510 Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
514 /// If Kind == Cap_VLA, the captured type.
515 const VariableArrayType *CapturedVLA;
517 /// Otherwise, the captured variable (if any).
518 VarDecl *CapturedVar;
521 /// The source location at which the first capture occurred.
524 /// The location of the ellipsis that expands a parameter pack.
525 SourceLocation EllipsisLoc;
527 /// The type as it was captured, which is the type of the non-static data
528 /// member that would hold the capture.
529 QualType CaptureType;
531 /// The CaptureKind of this capture.
534 /// Whether this is a nested capture (a capture of an enclosing capturing
535 /// scope's capture).
538 /// Whether this is a capture of '*this'.
539 unsigned CapturesThis : 1;
541 /// Whether an explicit capture has been odr-used in the body of the
543 unsigned ODRUsed : 1;
545 /// Whether an explicit capture has been non-odr-used in the body of
547 unsigned NonODRUsed : 1;
549 /// Whether the capture is invalid (a capture was required but the entity is
551 unsigned Invalid : 1;
554 Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
555 SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType,
557 : CapturedVar(Var), Loc(Loc), EllipsisLoc(EllipsisLoc),
558 CaptureType(CaptureType),
559 Kind(Block ? Cap_Block : ByRef ? Cap_ByRef : Cap_ByCopy),
560 Nested(IsNested), CapturesThis(false), ODRUsed(false),
561 NonODRUsed(false), Invalid(Invalid) {}
563 enum IsThisCapture { ThisCapture };
564 Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
565 QualType CaptureType, const bool ByCopy, bool Invalid)
566 : Loc(Loc), CaptureType(CaptureType),
567 Kind(ByCopy ? Cap_ByCopy : Cap_ByRef), Nested(IsNested),
568 CapturesThis(true), ODRUsed(false), NonODRUsed(false),
571 enum IsVLACapture { VLACapture };
572 Capture(IsVLACapture, const VariableArrayType *VLA, bool IsNested,
573 SourceLocation Loc, QualType CaptureType)
574 : CapturedVLA(VLA), Loc(Loc), CaptureType(CaptureType), Kind(Cap_VLA),
575 Nested(IsNested), CapturesThis(false), ODRUsed(false),
576 NonODRUsed(false), Invalid(false) {}
578 bool isThisCapture() const { return CapturesThis; }
579 bool isVariableCapture() const {
580 return !isThisCapture() && !isVLATypeCapture();
583 bool isCopyCapture() const { return Kind == Cap_ByCopy; }
584 bool isReferenceCapture() const { return Kind == Cap_ByRef; }
585 bool isBlockCapture() const { return Kind == Cap_Block; }
586 bool isVLATypeCapture() const { return Kind == Cap_VLA; }
588 bool isNested() const { return Nested; }
590 bool isInvalid() const { return Invalid; }
592 /// Determine whether this capture is an init-capture.
593 bool isInitCapture() const;
595 bool isODRUsed() const { return ODRUsed; }
596 bool isNonODRUsed() const { return NonODRUsed; }
597 void markUsed(bool IsODRUse) {
604 VarDecl *getVariable() const {
605 assert(isVariableCapture());
609 const VariableArrayType *getCapturedVLAType() const {
610 assert(isVLATypeCapture());
614 /// Retrieve the location at which this variable was captured.
615 SourceLocation getLocation() const { return Loc; }
617 /// Retrieve the source location of the ellipsis, whose presence
618 /// indicates that the capture is a pack expansion.
619 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
621 /// Retrieve the capture type for this capture, which is effectively
622 /// the type of the non-static data member in the lambda/block structure
623 /// that would store this capture.
624 QualType getCaptureType() const { return CaptureType; }
627 class CapturingScopeInfo : public FunctionScopeInfo {
629 CapturingScopeInfo(const CapturingScopeInfo&) = default;
632 enum ImplicitCaptureStyle {
633 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
634 ImpCap_CapturedRegion
637 ImplicitCaptureStyle ImpCaptureStyle;
639 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
640 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
642 /// CaptureMap - A map of captured variables to (index+1) into Captures.
643 llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
645 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
646 /// zero if 'this' is not captured.
647 unsigned CXXThisCaptureIndex = 0;
649 /// Captures - The captures.
650 SmallVector<Capture, 4> Captures;
652 /// - Whether the target type of return statements in this context
653 /// is deduced (e.g. a lambda or block with omitted return type).
654 bool HasImplicitReturnType = false;
656 /// ReturnType - The target type of return statements in this context,
657 /// or null if unknown.
660 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
661 SourceLocation Loc, SourceLocation EllipsisLoc,
662 QualType CaptureType, bool Invalid) {
663 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
664 EllipsisLoc, CaptureType, Invalid));
665 CaptureMap[Var] = Captures.size();
668 void addVLATypeCapture(SourceLocation Loc, const VariableArrayType *VLAType,
669 QualType CaptureType) {
670 Captures.push_back(Capture(Capture::VLACapture, VLAType,
671 /*FIXME: IsNested*/ false, Loc, CaptureType));
674 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
677 /// Determine whether the C++ 'this' is captured.
678 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
680 /// Retrieve the capture of C++ 'this', if it has been captured.
681 Capture &getCXXThisCapture() {
682 assert(isCXXThisCaptured() && "this has not been captured");
683 return Captures[CXXThisCaptureIndex - 1];
686 /// Determine whether the given variable has been captured.
687 bool isCaptured(VarDecl *Var) const {
688 return CaptureMap.count(Var);
691 /// Determine whether the given variable-array type has been captured.
692 bool isVLATypeCaptured(const VariableArrayType *VAT) const;
694 /// Retrieve the capture of the given variable, if it has been
695 /// captured already.
696 Capture &getCapture(VarDecl *Var) {
697 assert(isCaptured(Var) && "Variable has not been captured");
698 return Captures[CaptureMap[Var] - 1];
701 const Capture &getCapture(VarDecl *Var) const {
702 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
703 = CaptureMap.find(Var);
704 assert(Known != CaptureMap.end() && "Variable has not been captured");
705 return Captures[Known->second - 1];
708 static bool classof(const FunctionScopeInfo *FSI) {
709 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
710 || FSI->Kind == SK_CapturedRegion;
714 /// Retains information about a block that is currently being parsed.
715 class BlockScopeInfo final : public CapturingScopeInfo {
719 /// TheScope - This is the scope for the block itself, which contains
723 /// BlockType - The function type of the block, if one was given.
724 /// Its return type may be BuiltinType::Dependent.
725 QualType FunctionType;
727 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
728 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
729 TheScope(BlockScope) {
733 ~BlockScopeInfo() override;
735 static bool classof(const FunctionScopeInfo *FSI) {
736 return FSI->Kind == SK_Block;
740 /// Retains information about a captured region.
741 class CapturedRegionScopeInfo final : public CapturingScopeInfo {
743 /// The CapturedDecl for this statement.
744 CapturedDecl *TheCapturedDecl;
746 /// The captured record type.
747 RecordDecl *TheRecordDecl;
749 /// This is the enclosing scope of the captured region.
752 /// The implicit parameter for the captured variables.
753 ImplicitParamDecl *ContextParam;
755 /// The kind of captured region.
756 unsigned short CapRegionKind;
758 unsigned short OpenMPLevel;
760 CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
761 RecordDecl *RD, ImplicitParamDecl *Context,
762 CapturedRegionKind K, unsigned OpenMPLevel)
763 : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
764 TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
765 ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel) {
766 Kind = SK_CapturedRegion;
769 ~CapturedRegionScopeInfo() override;
771 /// A descriptive name for the kind of captured region this is.
772 StringRef getRegionName() const {
773 switch (CapRegionKind) {
775 return "default captured statement";
776 case CR_ObjCAtFinally:
777 return "Objective-C @finally statement";
779 return "OpenMP region";
781 llvm_unreachable("Invalid captured region kind!");
784 static bool classof(const FunctionScopeInfo *FSI) {
785 return FSI->Kind == SK_CapturedRegion;
789 class LambdaScopeInfo final : public CapturingScopeInfo {
791 /// The class that describes the lambda.
792 CXXRecordDecl *Lambda = nullptr;
794 /// The lambda's compiler-generated \c operator().
795 CXXMethodDecl *CallOperator = nullptr;
797 /// Source range covering the lambda introducer [...].
798 SourceRange IntroducerRange;
800 /// Source location of the '&' or '=' specifying the default capture
802 SourceLocation CaptureDefaultLoc;
804 /// The number of captures in the \c Captures list that are
805 /// explicit captures.
806 unsigned NumExplicitCaptures = 0;
808 /// Whether this is a mutable lambda.
809 bool Mutable = false;
811 /// Whether the (empty) parameter list is explicit.
812 bool ExplicitParams = false;
814 /// Whether any of the capture expressions requires cleanups.
817 /// Whether the lambda contains an unexpanded parameter pack.
818 bool ContainsUnexpandedParameterPack = false;
820 /// If this is a generic lambda, use this as the depth of
821 /// each 'auto' parameter, during initial AST construction.
822 unsigned AutoTemplateParameterDepth = 0;
824 /// The number of parameters in the template parameter list that were
825 /// explicitly specified by the user, as opposed to being invented by use
826 /// of an auto parameter.
827 unsigned NumExplicitTemplateParams = 0;
829 /// Source range covering the explicit template parameter list (if it exists).
830 SourceRange ExplicitTemplateParamsRange;
832 /// Store the list of the template parameters for a generic lambda.
833 /// If this is a generic lambda, this holds the explicit template parameters
834 /// followed by the auto parameters converted into TemplateTypeParmDecls.
835 /// It can be used to construct the generic lambda's template parameter list
836 /// during initial AST construction.
837 SmallVector<NamedDecl*, 4> TemplateParams;
839 /// If this is a generic lambda, and the template parameter
840 /// list has been created (from the TemplateParams) then store
841 /// a reference to it (cache it to avoid reconstructing it).
842 TemplateParameterList *GLTemplateParameterList = nullptr;
844 /// Contains all variable-referring-expressions (i.e. DeclRefExprs
845 /// or MemberExprs) that refer to local variables in a generic lambda
846 /// or a lambda in a potentially-evaluated-if-used context.
848 /// Potentially capturable variables of a nested lambda that might need
849 /// to be captured by the lambda are housed here.
850 /// This is specifically useful for generic lambdas or
851 /// lambdas within a potentially evaluated-if-used context.
852 /// If an enclosing variable is named in an expression of a lambda nested
853 /// within a generic lambda, we don't always know know whether the variable
854 /// will truly be odr-used (i.e. need to be captured) by that nested lambda,
855 /// until its instantiation. But we still need to capture it in the
856 /// enclosing lambda if all intervening lambdas can capture the variable.
857 llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
859 /// Contains all variable-referring-expressions that refer
860 /// to local variables that are usable as constant expressions and
861 /// do not involve an odr-use (they may still need to be captured
862 /// if the enclosing full-expression is instantiation dependent).
863 llvm::SmallSet<Expr *, 8> NonODRUsedCapturingExprs;
865 /// A map of explicit capture indices to their introducer source ranges.
866 llvm::DenseMap<unsigned, SourceRange> ExplicitCaptureRanges;
868 /// Contains all of the variables defined in this lambda that shadow variables
869 /// that were defined in parent contexts. Used to avoid warnings when the
870 /// shadowed variables are uncaptured by this lambda.
871 struct ShadowedOuterDecl {
873 const VarDecl *ShadowedDecl;
875 llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls;
877 SourceLocation PotentialThisCaptureLocation;
879 LambdaScopeInfo(DiagnosticsEngine &Diag)
880 : CapturingScopeInfo(Diag, ImpCap_None) {
884 /// Note when all explicit captures have been added.
885 void finishedExplicitCaptures() {
886 NumExplicitCaptures = Captures.size();
889 static bool classof(const FunctionScopeInfo *FSI) {
890 return FSI->Kind == SK_Lambda;
893 /// Is this scope known to be for a generic lambda? (This will be false until
894 /// we parse a template parameter list or the first 'auto'-typed parameter).
895 bool isGenericLambda() const {
896 return !TemplateParams.empty() || GLTemplateParameterList;
899 /// Add a variable that might potentially be captured by the
900 /// lambda and therefore the enclosing lambdas.
902 /// This is also used by enclosing lambda's to speculatively capture
903 /// variables that nested lambda's - depending on their enclosing
904 /// specialization - might need to capture.
906 /// void f(int, int); <-- don't capture
907 /// void f(const int&, double); <-- capture
909 /// const int x = 10;
910 /// auto L = [=](auto a) { // capture 'x'
911 /// return [=](auto b) {
912 /// f(x, a); // we may or may not need to capture 'x'
916 void addPotentialCapture(Expr *VarExpr) {
917 assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr) ||
918 isa<FunctionParmPackExpr>(VarExpr));
919 PotentiallyCapturingExprs.push_back(VarExpr);
922 void addPotentialThisCapture(SourceLocation Loc) {
923 PotentialThisCaptureLocation = Loc;
926 bool hasPotentialThisCapture() const {
927 return PotentialThisCaptureLocation.isValid();
930 /// Mark a variable's reference in a lambda as non-odr using.
932 /// For generic lambdas, if a variable is named in a potentially evaluated
933 /// expression, where the enclosing full expression is dependent then we
934 /// must capture the variable (given a default capture).
935 /// This is accomplished by recording all references to variables
936 /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of
937 /// PotentialCaptures. All such variables have to be captured by that lambda,
938 /// except for as described below.
939 /// If that variable is usable as a constant expression and is named in a
940 /// manner that does not involve its odr-use (e.g. undergoes
941 /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
942 /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
943 /// if we can determine that the full expression is not instantiation-
944 /// dependent, then we can entirely avoid its capture.
950 /// Interestingly, this strategy would involve a capture of n, even though
951 /// it's obviously not odr-used here, because the full-expression is
952 /// instantiation-dependent. It could be useful to avoid capturing such
953 /// variables, even when they are referred to in an instantiation-dependent
954 /// expression, if we can unambiguously determine that they shall never be
955 /// odr-used. This would involve removal of the variable-referring-expression
956 /// from the array of PotentialCaptures during the lvalue-to-rvalue
957 /// conversions. But per the working draft N3797, (post-chicago 2013) we must
958 /// capture such variables.
959 /// Before anyone is tempted to implement a strategy for not-capturing 'n',
960 /// consider the insightful warning in:
961 /// /cfe-commits/Week-of-Mon-20131104/092596.html
962 /// "The problem is that the set of captures for a lambda is part of the ABI
963 /// (since lambda layout can be made visible through inline functions and the
964 /// like), and there are no guarantees as to which cases we'll manage to build
965 /// an lvalue-to-rvalue conversion in, when parsing a template -- some
966 /// seemingly harmless change elsewhere in Sema could cause us to start or stop
967 /// building such a node. So we need a rule that anyone can implement and get
968 /// exactly the same result".
969 void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
970 assert(isa<DeclRefExpr>(CapturingVarExpr) ||
971 isa<MemberExpr>(CapturingVarExpr) ||
972 isa<FunctionParmPackExpr>(CapturingVarExpr));
973 NonODRUsedCapturingExprs.insert(CapturingVarExpr);
975 bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
976 assert(isa<DeclRefExpr>(CapturingVarExpr) ||
977 isa<MemberExpr>(CapturingVarExpr) ||
978 isa<FunctionParmPackExpr>(CapturingVarExpr));
979 return NonODRUsedCapturingExprs.count(CapturingVarExpr);
981 void removePotentialCapture(Expr *E) {
982 PotentiallyCapturingExprs.erase(
983 std::remove(PotentiallyCapturingExprs.begin(),
984 PotentiallyCapturingExprs.end(), E),
985 PotentiallyCapturingExprs.end());
987 void clearPotentialCaptures() {
988 PotentiallyCapturingExprs.clear();
989 PotentialThisCaptureLocation = SourceLocation();
991 unsigned getNumPotentialVariableCaptures() const {
992 return PotentiallyCapturingExprs.size();
995 bool hasPotentialCaptures() const {
996 return getNumPotentialVariableCaptures() ||
997 PotentialThisCaptureLocation.isValid();
1000 void visitPotentialCaptures(
1001 llvm::function_ref<void(VarDecl *, Expr *)> Callback) const;
1004 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
1005 : Base(nullptr, false) {}
1007 FunctionScopeInfo::WeakObjectProfileTy
1008 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
1009 FunctionScopeInfo::WeakObjectProfileTy Result;
1010 Result.Base.setInt(true);
1014 template <typename ExprT>
1015 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
1017 WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
1018 Uses.push_back(WeakUseTy(E, IsRead));
1021 inline void CapturingScopeInfo::addThisCapture(bool isNested,
1023 QualType CaptureType,
1025 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
1026 ByCopy, /*Invalid*/ false));
1027 CXXThisCaptureIndex = Captures.size();
1032 } // namespace clang
1034 #endif // LLVM_CLANG_SEMA_SCOPEINFO_H