1 //===- ScopeInfo.h - Information about a semantic context -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines FunctionScopeInfo and its subclasses, which contain
11 // information about a single function, block, lambda, or method body.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_SEMA_SCOPEINFO_H
16 #define LLVM_CLANG_SEMA_SCOPEINFO_H
18 #include "clang/AST/Expr.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 {
90 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
92 : PD(PD), Loc(Loc), stmt(stmt) {}
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.
494 // There are three categories of capture: capturing 'this', capturing
495 // local variables, and C++1y initialized captures (which can have an
496 // arbitrary initializer, and don't really capture in the traditional
499 // There are three ways to capture a local variable:
500 // - capture by copy in the C++11 sense,
501 // - capture by reference in the C++11 sense, and
502 // - __block capture.
503 // Lambdas explicitly specify capture by copy or capture by reference.
504 // For blocks, __block capture applies to variables with that annotation,
505 // variables of reference type are captured by reference, and other
506 // variables are captured by copy.
508 Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
511 IsNestedCapture = 0x1,
515 /// The variable being captured (if we are not capturing 'this') and whether
516 /// this is a nested capture, and whether we are capturing 'this'
517 llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
519 /// Expression to initialize a field of the given type, and the kind of
520 /// capture (if this is a capture and not an init-capture). The expression
521 /// is only required if we are capturing ByVal and the variable's type has
522 /// a non-trivial copy constructor.
523 llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
525 /// The source location at which the first capture occurred.
528 /// The location of the ellipsis that expands a parameter pack.
529 SourceLocation EllipsisLoc;
531 /// The type as it was captured, which is in effect the type of the
532 /// non-static data member that would hold the capture.
533 QualType CaptureType;
535 /// Whether an explicit capture has been odr-used in the body of the
537 bool ODRUsed = false;
539 /// Whether an explicit capture has been non-odr-used in the body of
541 bool NonODRUsed = false;
544 Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
545 SourceLocation Loc, SourceLocation EllipsisLoc,
546 QualType CaptureType, Expr *Cpy)
547 : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0),
548 InitExprAndCaptureKind(
549 Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
551 Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
553 enum IsThisCapture { ThisCapture };
554 Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
555 QualType CaptureType, Expr *Cpy, const bool ByCopy)
556 : VarAndNestedAndThis(
557 nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
558 InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
559 Loc(Loc), CaptureType(CaptureType) {}
561 bool isThisCapture() const {
562 return VarAndNestedAndThis.getInt() & IsThisCaptured;
565 bool isVariableCapture() const {
566 return !isThisCapture() && !isVLATypeCapture();
569 bool isCopyCapture() const {
570 return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
573 bool isReferenceCapture() const {
574 return InitExprAndCaptureKind.getInt() == Cap_ByRef;
577 bool isBlockCapture() const {
578 return InitExprAndCaptureKind.getInt() == Cap_Block;
581 bool isVLATypeCapture() const {
582 return InitExprAndCaptureKind.getInt() == Cap_VLA;
585 bool isNested() const {
586 return VarAndNestedAndThis.getInt() & IsNestedCapture;
589 bool isODRUsed() const { return ODRUsed; }
590 bool isNonODRUsed() const { return NonODRUsed; }
591 void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
593 VarDecl *getVariable() const {
594 assert(isVariableCapture());
595 return VarAndNestedAndThis.getPointer();
598 /// Retrieve the location at which this variable was captured.
599 SourceLocation getLocation() const { return Loc; }
601 /// Retrieve the source location of the ellipsis, whose presence
602 /// indicates that the capture is a pack expansion.
603 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
605 /// Retrieve the capture type for this capture, which is effectively
606 /// the type of the non-static data member in the lambda/block structure
607 /// that would store this capture.
608 QualType getCaptureType() const {
609 assert(!isThisCapture());
613 Expr *getInitExpr() const {
614 assert(!isVLATypeCapture() && "no init expression for type capture");
615 return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
619 class CapturingScopeInfo : public FunctionScopeInfo {
621 CapturingScopeInfo(const CapturingScopeInfo&) = default;
624 enum ImplicitCaptureStyle {
625 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
626 ImpCap_CapturedRegion
629 ImplicitCaptureStyle ImpCaptureStyle;
631 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
632 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
634 /// CaptureMap - A map of captured variables to (index+1) into Captures.
635 llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
637 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
638 /// zero if 'this' is not captured.
639 unsigned CXXThisCaptureIndex = 0;
641 /// Captures - The captures.
642 SmallVector<Capture, 4> Captures;
644 /// - Whether the target type of return statements in this context
645 /// is deduced (e.g. a lambda or block with omitted return type).
646 bool HasImplicitReturnType = false;
648 /// ReturnType - The target type of return statements in this context,
649 /// or null if unknown.
652 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
653 SourceLocation Loc, SourceLocation EllipsisLoc,
654 QualType CaptureType, Expr *Cpy) {
655 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
656 EllipsisLoc, CaptureType, Cpy));
657 CaptureMap[Var] = Captures.size();
660 void addVLATypeCapture(SourceLocation Loc, QualType CaptureType) {
661 Captures.push_back(Capture(/*Var*/ nullptr, /*isBlock*/ false,
662 /*isByref*/ false, /*isNested*/ false, Loc,
663 /*EllipsisLoc*/ SourceLocation(), CaptureType,
667 // Note, we do not need to add the type of 'this' since that is always
668 // retrievable from Sema::getCurrentThisType - and is also encoded within the
669 // type of the corresponding FieldDecl.
670 void addThisCapture(bool isNested, SourceLocation Loc,
671 Expr *Cpy, bool ByCopy);
673 /// Determine whether the C++ 'this' is captured.
674 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
676 /// Retrieve the capture of C++ 'this', if it has been captured.
677 Capture &getCXXThisCapture() {
678 assert(isCXXThisCaptured() && "this has not been captured");
679 return Captures[CXXThisCaptureIndex - 1];
682 /// Determine whether the given variable has been captured.
683 bool isCaptured(VarDecl *Var) const {
684 return CaptureMap.count(Var);
687 /// Determine whether the given variable-array type has been captured.
688 bool isVLATypeCaptured(const VariableArrayType *VAT) const;
690 /// Retrieve the capture of the given variable, if it has been
691 /// captured already.
692 Capture &getCapture(VarDecl *Var) {
693 assert(isCaptured(Var) && "Variable has not been captured");
694 return Captures[CaptureMap[Var] - 1];
697 const Capture &getCapture(VarDecl *Var) const {
698 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
699 = CaptureMap.find(Var);
700 assert(Known != CaptureMap.end() && "Variable has not been captured");
701 return Captures[Known->second - 1];
704 static bool classof(const FunctionScopeInfo *FSI) {
705 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
706 || FSI->Kind == SK_CapturedRegion;
710 /// Retains information about a block that is currently being parsed.
711 class BlockScopeInfo final : public CapturingScopeInfo {
715 /// TheScope - This is the scope for the block itself, which contains
719 /// BlockType - The function type of the block, if one was given.
720 /// Its return type may be BuiltinType::Dependent.
721 QualType FunctionType;
723 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
724 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
725 TheScope(BlockScope) {
729 ~BlockScopeInfo() override;
731 static bool classof(const FunctionScopeInfo *FSI) {
732 return FSI->Kind == SK_Block;
736 /// Retains information about a captured region.
737 class CapturedRegionScopeInfo final : public CapturingScopeInfo {
739 /// The CapturedDecl for this statement.
740 CapturedDecl *TheCapturedDecl;
742 /// The captured record type.
743 RecordDecl *TheRecordDecl;
745 /// This is the enclosing scope of the captured region.
748 /// The implicit parameter for the captured variables.
749 ImplicitParamDecl *ContextParam;
751 /// The kind of captured region.
752 unsigned short CapRegionKind;
754 unsigned short OpenMPLevel;
756 CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
757 RecordDecl *RD, ImplicitParamDecl *Context,
758 CapturedRegionKind K, unsigned OpenMPLevel)
759 : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
760 TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
761 ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel) {
762 Kind = SK_CapturedRegion;
765 ~CapturedRegionScopeInfo() override;
767 /// A descriptive name for the kind of captured region this is.
768 StringRef getRegionName() const {
769 switch (CapRegionKind) {
771 return "default captured statement";
772 case CR_ObjCAtFinally:
773 return "Objective-C @finally statement";
775 return "OpenMP region";
777 llvm_unreachable("Invalid captured region kind!");
780 static bool classof(const FunctionScopeInfo *FSI) {
781 return FSI->Kind == SK_CapturedRegion;
785 class LambdaScopeInfo final : public CapturingScopeInfo {
787 /// The class that describes the lambda.
788 CXXRecordDecl *Lambda = nullptr;
790 /// The lambda's compiler-generated \c operator().
791 CXXMethodDecl *CallOperator = nullptr;
793 /// Source range covering the lambda introducer [...].
794 SourceRange IntroducerRange;
796 /// Source location of the '&' or '=' specifying the default capture
798 SourceLocation CaptureDefaultLoc;
800 /// The number of captures in the \c Captures list that are
801 /// explicit captures.
802 unsigned NumExplicitCaptures = 0;
804 /// Whether this is a mutable lambda.
805 bool Mutable = false;
807 /// Whether the (empty) parameter list is explicit.
808 bool ExplicitParams = false;
810 /// Whether any of the capture expressions requires cleanups.
813 /// Whether the lambda contains an unexpanded parameter pack.
814 bool ContainsUnexpandedParameterPack = false;
816 /// If this is a generic lambda, use this as the depth of
817 /// each 'auto' parameter, during initial AST construction.
818 unsigned AutoTemplateParameterDepth = 0;
820 /// Store the list of the auto parameters for a generic lambda.
821 /// If this is a generic lambda, store the list of the auto
822 /// parameters converted into TemplateTypeParmDecls into a vector
823 /// that can be used to construct the generic lambda's template
824 /// parameter list, during initial AST construction.
825 SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams;
827 /// If this is a generic lambda, and the template parameter
828 /// list has been created (from the AutoTemplateParams) then
829 /// store a reference to it (cache it to avoid reconstructing it).
830 TemplateParameterList *GLTemplateParameterList = nullptr;
832 /// Contains all variable-referring-expressions (i.e. DeclRefExprs
833 /// or MemberExprs) that refer to local variables in a generic lambda
834 /// or a lambda in a potentially-evaluated-if-used context.
836 /// Potentially capturable variables of a nested lambda that might need
837 /// to be captured by the lambda are housed here.
838 /// This is specifically useful for generic lambdas or
839 /// lambdas within a potentially evaluated-if-used context.
840 /// If an enclosing variable is named in an expression of a lambda nested
841 /// within a generic lambda, we don't always know know whether the variable
842 /// will truly be odr-used (i.e. need to be captured) by that nested lambda,
843 /// until its instantiation. But we still need to capture it in the
844 /// enclosing lambda if all intervening lambdas can capture the variable.
845 llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
847 /// Contains all variable-referring-expressions that refer
848 /// to local variables that are usable as constant expressions and
849 /// do not involve an odr-use (they may still need to be captured
850 /// if the enclosing full-expression is instantiation dependent).
851 llvm::SmallSet<Expr *, 8> NonODRUsedCapturingExprs;
853 /// A map of explicit capture indices to their introducer source ranges.
854 llvm::DenseMap<unsigned, SourceRange> ExplicitCaptureRanges;
856 /// Contains all of the variables defined in this lambda that shadow variables
857 /// that were defined in parent contexts. Used to avoid warnings when the
858 /// shadowed variables are uncaptured by this lambda.
859 struct ShadowedOuterDecl {
861 const VarDecl *ShadowedDecl;
863 llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls;
865 SourceLocation PotentialThisCaptureLocation;
867 LambdaScopeInfo(DiagnosticsEngine &Diag)
868 : CapturingScopeInfo(Diag, ImpCap_None) {
872 /// Note when all explicit captures have been added.
873 void finishedExplicitCaptures() {
874 NumExplicitCaptures = Captures.size();
877 static bool classof(const FunctionScopeInfo *FSI) {
878 return FSI->Kind == SK_Lambda;
881 /// Is this scope known to be for a generic lambda? (This will be false until
882 /// we parse the first 'auto'-typed parameter.
883 bool isGenericLambda() const {
884 return !AutoTemplateParams.empty() || GLTemplateParameterList;
887 /// Add a variable that might potentially be captured by the
888 /// lambda and therefore the enclosing lambdas.
890 /// This is also used by enclosing lambda's to speculatively capture
891 /// variables that nested lambda's - depending on their enclosing
892 /// specialization - might need to capture.
894 /// void f(int, int); <-- don't capture
895 /// void f(const int&, double); <-- capture
897 /// const int x = 10;
898 /// auto L = [=](auto a) { // capture 'x'
899 /// return [=](auto b) {
900 /// f(x, a); // we may or may not need to capture 'x'
904 void addPotentialCapture(Expr *VarExpr) {
905 assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr));
906 PotentiallyCapturingExprs.push_back(VarExpr);
909 void addPotentialThisCapture(SourceLocation Loc) {
910 PotentialThisCaptureLocation = Loc;
913 bool hasPotentialThisCapture() const {
914 return PotentialThisCaptureLocation.isValid();
917 /// Mark a variable's reference in a lambda as non-odr using.
919 /// For generic lambdas, if a variable is named in a potentially evaluated
920 /// expression, where the enclosing full expression is dependent then we
921 /// must capture the variable (given a default capture).
922 /// This is accomplished by recording all references to variables
923 /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of
924 /// PotentialCaptures. All such variables have to be captured by that lambda,
925 /// except for as described below.
926 /// If that variable is usable as a constant expression and is named in a
927 /// manner that does not involve its odr-use (e.g. undergoes
928 /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
929 /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
930 /// if we can determine that the full expression is not instantiation-
931 /// dependent, then we can entirely avoid its capture.
937 /// Interestingly, this strategy would involve a capture of n, even though
938 /// it's obviously not odr-used here, because the full-expression is
939 /// instantiation-dependent. It could be useful to avoid capturing such
940 /// variables, even when they are referred to in an instantiation-dependent
941 /// expression, if we can unambiguously determine that they shall never be
942 /// odr-used. This would involve removal of the variable-referring-expression
943 /// from the array of PotentialCaptures during the lvalue-to-rvalue
944 /// conversions. But per the working draft N3797, (post-chicago 2013) we must
945 /// capture such variables.
946 /// Before anyone is tempted to implement a strategy for not-capturing 'n',
947 /// consider the insightful warning in:
948 /// /cfe-commits/Week-of-Mon-20131104/092596.html
949 /// "The problem is that the set of captures for a lambda is part of the ABI
950 /// (since lambda layout can be made visible through inline functions and the
951 /// like), and there are no guarantees as to which cases we'll manage to build
952 /// an lvalue-to-rvalue conversion in, when parsing a template -- some
953 /// seemingly harmless change elsewhere in Sema could cause us to start or stop
954 /// building such a node. So we need a rule that anyone can implement and get
955 /// exactly the same result".
956 void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
957 assert(isa<DeclRefExpr>(CapturingVarExpr)
958 || isa<MemberExpr>(CapturingVarExpr));
959 NonODRUsedCapturingExprs.insert(CapturingVarExpr);
961 bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
962 assert(isa<DeclRefExpr>(CapturingVarExpr)
963 || isa<MemberExpr>(CapturingVarExpr));
964 return NonODRUsedCapturingExprs.count(CapturingVarExpr);
966 void removePotentialCapture(Expr *E) {
967 PotentiallyCapturingExprs.erase(
968 std::remove(PotentiallyCapturingExprs.begin(),
969 PotentiallyCapturingExprs.end(), E),
970 PotentiallyCapturingExprs.end());
972 void clearPotentialCaptures() {
973 PotentiallyCapturingExprs.clear();
974 PotentialThisCaptureLocation = SourceLocation();
976 unsigned getNumPotentialVariableCaptures() const {
977 return PotentiallyCapturingExprs.size();
980 bool hasPotentialCaptures() const {
981 return getNumPotentialVariableCaptures() ||
982 PotentialThisCaptureLocation.isValid();
985 // When passed the index, returns the VarDecl and Expr associated
987 void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const;
990 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
991 : Base(nullptr, false) {}
993 FunctionScopeInfo::WeakObjectProfileTy
994 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
995 FunctionScopeInfo::WeakObjectProfileTy Result;
996 Result.Base.setInt(true);
1000 template <typename ExprT>
1001 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
1003 WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
1004 Uses.push_back(WeakUseTy(E, IsRead));
1008 CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
1010 const bool ByCopy) {
1011 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, QualType(),
1013 CXXThisCaptureIndex = Captures.size();
1018 } // namespace clang
1020 #endif // LLVM_CLANG_SEMA_SCOPEINFO_H