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/PartialDiagnostic.h"
22 #include "clang/Sema/Ownership.h"
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/SmallSet.h"
25 #include "llvm/ADT/SmallVector.h"
35 class ObjCPropertyDecl;
37 class ImplicitParamDecl;
42 class TemplateTypeParmDecl;
43 class TemplateParameterList;
45 class ObjCIvarRefExpr;
46 class ObjCPropertyRefExpr;
47 class ObjCMessageExpr;
51 /// \brief Contains information about the compound statement currently being
53 class CompoundScopeInfo {
56 : HasEmptyLoopBodies(false) { }
58 /// \brief Whether this compound stamement contains `for' or `while' loops
59 /// with empty bodies.
60 bool HasEmptyLoopBodies;
62 void setHasEmptyLoopBodies() {
63 HasEmptyLoopBodies = true;
67 class PossiblyUnreachableDiag {
73 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
75 : PD(PD), Loc(Loc), stmt(stmt) {}
78 /// \brief Retains information about a function, method, or block that is
79 /// currently being parsed.
80 class FunctionScopeInfo {
90 /// \brief What kind of scope we are describing.
94 /// \brief Whether this function contains a VLA, \@try, try, C++
95 /// initializer, or anything else that can't be jumped past.
96 bool HasBranchProtectedScope;
98 /// \brief Whether this function contains any switches or direct gotos.
99 bool HasBranchIntoScope;
101 /// \brief Whether this function contains any indirect gotos.
102 bool HasIndirectGoto;
104 /// \brief Whether a statement was dropped because it was invalid.
107 /// A flag that is set when parsing a method that must call super's
108 /// implementation, such as \c -dealloc, \c -finalize, or any method marked
109 /// with \c __attribute__((objc_requires_super)).
110 bool ObjCShouldCallSuper;
112 /// True when this is a method marked as a designated initializer.
113 bool ObjCIsDesignatedInit;
114 /// This starts true for a method marked as designated initializer and will
115 /// be set to false if there is an invocation to a designated initializer of
117 bool ObjCWarnForNoDesignatedInitChain;
119 /// True when this is an initializer method not marked as a designated
120 /// initializer within a class that has at least one initializer marked as a
121 /// designated initializer.
122 bool ObjCIsSecondaryInit;
123 /// This starts true for a secondary initializer method and will be set to
124 /// false if there is an invocation of an initializer on 'self'.
125 bool ObjCWarnForNoInitDelegation;
127 /// \brief Used to determine if errors occurred in this function or block.
128 DiagnosticErrorTrap ErrorTrap;
130 /// SwitchStack - This is the current set of active switch statements in the
132 SmallVector<SwitchStmt*, 8> SwitchStack;
134 /// \brief The list of return statements that occur within the function or
135 /// block, if there is any chance of applying the named return value
136 /// optimization, or if we need to infer a return type.
137 SmallVector<ReturnStmt*, 4> Returns;
139 /// \brief The stack of currently active compound stamement scopes in the
141 SmallVector<CompoundScopeInfo, 4> CompoundScopes;
143 /// \brief A list of PartialDiagnostics created but delayed within the
144 /// current function scope. These diagnostics are vetted for reachability
145 /// prior to being emitted.
146 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
149 /// Represents a simple identification of a weak object.
151 /// Part of the implementation of -Wrepeated-use-of-weak.
153 /// This is used to determine if two weak accesses refer to the same object.
154 /// Here are some examples of how various accesses are "profiled":
156 /// Access Expression | "Base" Decl | "Property" Decl
157 /// :---------------: | :-----------------: | :------------------------------:
158 /// self.property | self (VarDecl) | property (ObjCPropertyDecl)
159 /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl)
160 /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
161 /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl)
162 /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl)
163 /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl)
164 /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
165 /// weakVar | 0 (known) | weakVar (VarDecl)
166 /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl)
168 /// Objects are identified with only two Decls to make it reasonably fast to
170 class WeakObjectProfileTy {
171 /// The base object decl, as described in the class documentation.
173 /// The extra flag is "true" if the Base and Property are enough to uniquely
174 /// identify the object in memory.
176 /// \sa isExactProfile()
177 typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
180 /// The "property" decl, as described in the class documentation.
182 /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
183 /// case of "implicit" properties (regular methods accessed via dot syntax).
184 const NamedDecl *Property;
186 /// Used to find the proper base profile for a given base expression.
187 static BaseInfoTy getBaseInfo(const Expr *BaseE);
189 inline WeakObjectProfileTy();
190 static inline WeakObjectProfileTy getSentinel();
193 WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
194 WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
195 WeakObjectProfileTy(const DeclRefExpr *RE);
196 WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
198 const NamedDecl *getBase() const { return Base.getPointer(); }
199 const NamedDecl *getProperty() const { return Property; }
201 /// Returns true if the object base specifies a known object in memory,
202 /// rather than, say, an instance variable or property of another object.
204 /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
205 /// considered an exact profile if \c foo is a local variable, even if
206 /// another variable \c foo2 refers to the same object as \c foo.
208 /// For increased precision, accesses with base variables that are
209 /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
210 /// be exact, though this is not true for arbitrary variables
211 /// (foo.prop1.prop2).
212 bool isExactProfile() const {
213 return Base.getInt();
216 bool operator==(const WeakObjectProfileTy &Other) const {
217 return Base == Other.Base && Property == Other.Property;
220 // For use in DenseMap.
221 // We can't specialize the usual llvm::DenseMapInfo at the end of the file
222 // because by that point the DenseMap in FunctionScopeInfo has already been
226 static inline WeakObjectProfileTy getEmptyKey() {
227 return WeakObjectProfileTy();
229 static inline WeakObjectProfileTy getTombstoneKey() {
230 return WeakObjectProfileTy::getSentinel();
233 static unsigned getHashValue(const WeakObjectProfileTy &Val) {
234 typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
235 return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
239 static bool isEqual(const WeakObjectProfileTy &LHS,
240 const WeakObjectProfileTy &RHS) {
246 /// Represents a single use of a weak object.
248 /// Stores both the expression and whether the access is potentially unsafe
249 /// (i.e. it could potentially be warned about).
251 /// Part of the implementation of -Wrepeated-use-of-weak.
253 llvm::PointerIntPair<const Expr *, 1, bool> Rep;
255 WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
257 const Expr *getUseExpr() const { return Rep.getPointer(); }
258 bool isUnsafe() const { return Rep.getInt(); }
259 void markSafe() { Rep.setInt(false); }
261 bool operator==(const WeakUseTy &Other) const {
262 return Rep == Other.Rep;
266 /// Used to collect uses of a particular weak object in a function body.
268 /// Part of the implementation of -Wrepeated-use-of-weak.
269 typedef SmallVector<WeakUseTy, 4> WeakUseVector;
271 /// Used to collect all uses of weak objects in a function body.
273 /// Part of the implementation of -Wrepeated-use-of-weak.
274 typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
275 WeakObjectProfileTy::DenseMapInfo>
279 /// Used to collect all uses of weak objects in this function body.
281 /// Part of the implementation of -Wrepeated-use-of-weak.
282 WeakObjectUseMap WeakObjectUses;
285 /// Record that a weak object was accessed.
287 /// Part of the implementation of -Wrepeated-use-of-weak.
288 template <typename ExprT>
289 inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
291 void recordUseOfWeak(const ObjCMessageExpr *Msg,
292 const ObjCPropertyDecl *Prop);
294 /// Record that a given expression is a "safe" access of a weak object (e.g.
295 /// assigning it to a strong variable.)
297 /// Part of the implementation of -Wrepeated-use-of-weak.
298 void markSafeWeakUse(const Expr *E);
300 const WeakObjectUseMap &getWeakObjectUses() const {
301 return WeakObjectUses;
304 void setHasBranchIntoScope() {
305 HasBranchIntoScope = true;
308 void setHasBranchProtectedScope() {
309 HasBranchProtectedScope = true;
312 void setHasIndirectGoto() {
313 HasIndirectGoto = true;
316 void setHasDroppedStmt() {
317 HasDroppedStmt = true;
320 bool NeedsScopeChecking() const {
321 return !HasDroppedStmt &&
323 (HasBranchProtectedScope && HasBranchIntoScope));
326 FunctionScopeInfo(DiagnosticsEngine &Diag)
328 HasBranchProtectedScope(false),
329 HasBranchIntoScope(false),
330 HasIndirectGoto(false),
331 HasDroppedStmt(false),
332 ObjCShouldCallSuper(false),
333 ObjCIsDesignatedInit(false),
334 ObjCWarnForNoDesignatedInitChain(false),
335 ObjCIsSecondaryInit(false),
336 ObjCWarnForNoInitDelegation(false),
339 virtual ~FunctionScopeInfo();
341 /// \brief Clear out the information in this function scope, making it
342 /// suitable for reuse.
346 class CapturingScopeInfo : public FunctionScopeInfo {
348 enum ImplicitCaptureStyle {
349 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
350 ImpCap_CapturedRegion
353 ImplicitCaptureStyle ImpCaptureStyle;
356 // There are three categories of capture: capturing 'this', capturing
357 // local variables, and C++1y initialized captures (which can have an
358 // arbitrary initializer, and don't really capture in the traditional
361 // There are three ways to capture a local variable:
362 // - capture by copy in the C++11 sense,
363 // - capture by reference in the C++11 sense, and
364 // - __block capture.
365 // Lambdas explicitly specify capture by copy or capture by reference.
366 // For blocks, __block capture applies to variables with that annotation,
367 // variables of reference type are captured by reference, and other
368 // variables are captured by copy.
370 Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This
373 /// The variable being captured (if we are not capturing 'this') and whether
374 /// this is a nested capture.
375 llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested;
377 /// Expression to initialize a field of the given type, and the kind of
378 /// capture (if this is a capture and not an init-capture). The expression
379 /// is only required if we are capturing ByVal and the variable's type has
380 /// a non-trivial copy constructor.
381 llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind;
383 /// \brief The source location at which the first capture occurred.
386 /// \brief The location of the ellipsis that expands a parameter pack.
387 SourceLocation EllipsisLoc;
389 /// \brief The type as it was captured, which is in effect the type of the
390 /// non-static data member that would hold the capture.
391 QualType CaptureType;
394 Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
395 SourceLocation Loc, SourceLocation EllipsisLoc,
396 QualType CaptureType, Expr *Cpy)
397 : VarAndNested(Var, IsNested),
398 InitExprAndCaptureKind(Cpy, Block ? Cap_Block :
399 ByRef ? Cap_ByRef : Cap_ByCopy),
400 Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
402 enum IsThisCapture { ThisCapture };
403 Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
404 QualType CaptureType, Expr *Cpy)
405 : VarAndNested(nullptr, IsNested),
406 InitExprAndCaptureKind(Cpy, Cap_This),
407 Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
409 bool isThisCapture() const {
410 return InitExprAndCaptureKind.getInt() == Cap_This;
412 bool isVariableCapture() const {
413 return InitExprAndCaptureKind.getInt() != Cap_This;
415 bool isCopyCapture() const {
416 return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
418 bool isReferenceCapture() const {
419 return InitExprAndCaptureKind.getInt() == Cap_ByRef;
421 bool isBlockCapture() const {
422 return InitExprAndCaptureKind.getInt() == Cap_Block;
424 bool isNested() { return VarAndNested.getInt(); }
426 VarDecl *getVariable() const {
427 return VarAndNested.getPointer();
430 /// \brief Retrieve the location at which this variable was captured.
431 SourceLocation getLocation() const { return Loc; }
433 /// \brief Retrieve the source location of the ellipsis, whose presence
434 /// indicates that the capture is a pack expansion.
435 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
437 /// \brief Retrieve the capture type for this capture, which is effectively
438 /// the type of the non-static data member in the lambda/block structure
439 /// that would store this capture.
440 QualType getCaptureType() const { return CaptureType; }
442 Expr *getInitExpr() const {
443 return InitExprAndCaptureKind.getPointer();
447 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
448 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
449 HasImplicitReturnType(false)
452 /// CaptureMap - A map of captured variables to (index+1) into Captures.
453 llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
455 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
456 /// zero if 'this' is not captured.
457 unsigned CXXThisCaptureIndex;
459 /// Captures - The captures.
460 SmallVector<Capture, 4> Captures;
462 /// \brief - Whether the target type of return statements in this context
463 /// is deduced (e.g. a lambda or block with omitted return type).
464 bool HasImplicitReturnType;
466 /// ReturnType - The target type of return statements in this context,
467 /// or null if unknown.
470 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
471 SourceLocation Loc, SourceLocation EllipsisLoc,
472 QualType CaptureType, Expr *Cpy) {
473 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
474 EllipsisLoc, CaptureType, Cpy));
475 CaptureMap[Var] = Captures.size();
478 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
481 /// \brief Determine whether the C++ 'this' is captured.
482 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
484 /// \brief Retrieve the capture of C++ 'this', if it has been captured.
485 Capture &getCXXThisCapture() {
486 assert(isCXXThisCaptured() && "this has not been captured");
487 return Captures[CXXThisCaptureIndex - 1];
490 /// \brief Determine whether the given variable has been captured.
491 bool isCaptured(VarDecl *Var) const {
492 return CaptureMap.count(Var);
495 /// \brief Retrieve the capture of the given variable, if it has been
496 /// captured already.
497 Capture &getCapture(VarDecl *Var) {
498 assert(isCaptured(Var) && "Variable has not been captured");
499 return Captures[CaptureMap[Var] - 1];
502 const Capture &getCapture(VarDecl *Var) const {
503 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
504 = CaptureMap.find(Var);
505 assert(Known != CaptureMap.end() && "Variable has not been captured");
506 return Captures[Known->second - 1];
509 static bool classof(const FunctionScopeInfo *FSI) {
510 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
511 || FSI->Kind == SK_CapturedRegion;
515 /// \brief Retains information about a block that is currently being parsed.
516 class BlockScopeInfo : public CapturingScopeInfo {
520 /// TheScope - This is the scope for the block itself, which contains
524 /// BlockType - The function type of the block, if one was given.
525 /// Its return type may be BuiltinType::Dependent.
526 QualType FunctionType;
528 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
529 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
535 virtual ~BlockScopeInfo();
537 static bool classof(const FunctionScopeInfo *FSI) {
538 return FSI->Kind == SK_Block;
542 /// \brief Retains information about a captured region.
543 class CapturedRegionScopeInfo: public CapturingScopeInfo {
545 /// \brief The CapturedDecl for this statement.
546 CapturedDecl *TheCapturedDecl;
547 /// \brief The captured record type.
548 RecordDecl *TheRecordDecl;
549 /// \brief This is the enclosing scope of the captured region.
551 /// \brief The implicit parameter for the captured variables.
552 ImplicitParamDecl *ContextParam;
553 /// \brief The kind of captured region.
554 CapturedRegionKind CapRegionKind;
556 CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
557 RecordDecl *RD, ImplicitParamDecl *Context,
558 CapturedRegionKind K)
559 : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
560 TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
561 ContextParam(Context), CapRegionKind(K)
563 Kind = SK_CapturedRegion;
566 virtual ~CapturedRegionScopeInfo();
568 /// \brief A descriptive name for the kind of captured region this is.
569 StringRef getRegionName() const {
570 switch (CapRegionKind) {
572 return "default captured statement";
574 return "OpenMP region";
576 llvm_unreachable("Invalid captured region kind!");
579 static bool classof(const FunctionScopeInfo *FSI) {
580 return FSI->Kind == SK_CapturedRegion;
584 class LambdaScopeInfo : public CapturingScopeInfo {
586 /// \brief The class that describes the lambda.
587 CXXRecordDecl *Lambda;
589 /// \brief The lambda's compiler-generated \c operator().
590 CXXMethodDecl *CallOperator;
592 /// \brief Source range covering the lambda introducer [...].
593 SourceRange IntroducerRange;
595 /// \brief Source location of the '&' or '=' specifying the default capture
597 SourceLocation CaptureDefaultLoc;
599 /// \brief The number of captures in the \c Captures list that are
600 /// explicit captures.
601 unsigned NumExplicitCaptures;
603 /// \brief Whether this is a mutable lambda.
606 /// \brief Whether the (empty) parameter list is explicit.
609 /// \brief Whether any of the capture expressions requires cleanups.
610 bool ExprNeedsCleanups;
612 /// \brief Whether the lambda contains an unexpanded parameter pack.
613 bool ContainsUnexpandedParameterPack;
615 /// \brief Variables used to index into by-copy array captures.
616 SmallVector<VarDecl *, 4> ArrayIndexVars;
618 /// \brief Offsets into the ArrayIndexVars array at which each capture starts
619 /// its list of array index variables.
620 SmallVector<unsigned, 4> ArrayIndexStarts;
622 /// \brief If this is a generic lambda, use this as the depth of
623 /// each 'auto' parameter, during initial AST construction.
624 unsigned AutoTemplateParameterDepth;
626 /// \brief Store the list of the auto parameters for a generic lambda.
627 /// If this is a generic lambda, store the list of the auto
628 /// parameters converted into TemplateTypeParmDecls into a vector
629 /// that can be used to construct the generic lambda's template
630 /// parameter list, during initial AST construction.
631 SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams;
633 /// If this is a generic lambda, and the template parameter
634 /// list has been created (from the AutoTemplateParams) then
635 /// store a reference to it (cache it to avoid reconstructing it).
636 TemplateParameterList *GLTemplateParameterList;
638 /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs
639 /// or MemberExprs) that refer to local variables in a generic lambda
640 /// or a lambda in a potentially-evaluated-if-used context.
642 /// Potentially capturable variables of a nested lambda that might need
643 /// to be captured by the lambda are housed here.
644 /// This is specifically useful for generic lambdas or
645 /// lambdas within a a potentially evaluated-if-used context.
646 /// If an enclosing variable is named in an expression of a lambda nested
647 /// within a generic lambda, we don't always know know whether the variable
648 /// will truly be odr-used (i.e. need to be captured) by that nested lambda,
649 /// until its instantiation. But we still need to capture it in the
650 /// enclosing lambda if all intervening lambdas can capture the variable.
652 llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
654 /// \brief Contains all variable-referring-expressions that refer
655 /// to local variables that are usable as constant expressions and
656 /// do not involve an odr-use (they may still need to be captured
657 /// if the enclosing full-expression is instantiation dependent).
658 llvm::SmallSet<Expr*, 8> NonODRUsedCapturingExprs;
660 SourceLocation PotentialThisCaptureLocation;
662 LambdaScopeInfo(DiagnosticsEngine &Diag)
663 : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
664 CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
665 ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false),
666 AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr)
671 virtual ~LambdaScopeInfo();
673 /// \brief Note when all explicit captures have been added.
674 void finishedExplicitCaptures() {
675 NumExplicitCaptures = Captures.size();
678 static bool classof(const FunctionScopeInfo *FSI) {
679 return FSI->Kind == SK_Lambda;
683 /// \brief Add a variable that might potentially be captured by the
684 /// lambda and therefore the enclosing lambdas.
686 /// This is also used by enclosing lambda's to speculatively capture
687 /// variables that nested lambda's - depending on their enclosing
688 /// specialization - might need to capture.
690 /// void f(int, int); <-- don't capture
691 /// void f(const int&, double); <-- capture
693 /// const int x = 10;
694 /// auto L = [=](auto a) { // capture 'x'
695 /// return [=](auto b) {
696 /// f(x, a); // we may or may not need to capture 'x'
700 void addPotentialCapture(Expr *VarExpr) {
701 assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr));
702 PotentiallyCapturingExprs.push_back(VarExpr);
705 void addPotentialThisCapture(SourceLocation Loc) {
706 PotentialThisCaptureLocation = Loc;
708 bool hasPotentialThisCapture() const {
709 return PotentialThisCaptureLocation.isValid();
712 /// \brief Mark a variable's reference in a lambda as non-odr using.
714 /// For generic lambdas, if a variable is named in a potentially evaluated
715 /// expression, where the enclosing full expression is dependent then we
716 /// must capture the variable (given a default capture).
717 /// This is accomplished by recording all references to variables
718 /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of
719 /// PotentialCaptures. All such variables have to be captured by that lambda,
720 /// except for as described below.
721 /// If that variable is usable as a constant expression and is named in a
722 /// manner that does not involve its odr-use (e.g. undergoes
723 /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
724 /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
725 /// if we can determine that the full expression is not instantiation-
726 /// dependent, then we can entirely avoid its capture.
732 /// Interestingly, this strategy would involve a capture of n, even though
733 /// it's obviously not odr-used here, because the full-expression is
734 /// instantiation-dependent. It could be useful to avoid capturing such
735 /// variables, even when they are referred to in an instantiation-dependent
736 /// expression, if we can unambiguously determine that they shall never be
737 /// odr-used. This would involve removal of the variable-referring-expression
738 /// from the array of PotentialCaptures during the lvalue-to-rvalue
739 /// conversions. But per the working draft N3797, (post-chicago 2013) we must
740 /// capture such variables.
741 /// Before anyone is tempted to implement a strategy for not-capturing 'n',
742 /// consider the insightful warning in:
743 /// /cfe-commits/Week-of-Mon-20131104/092596.html
744 /// "The problem is that the set of captures for a lambda is part of the ABI
745 /// (since lambda layout can be made visible through inline functions and the
746 /// like), and there are no guarantees as to which cases we'll manage to build
747 /// an lvalue-to-rvalue conversion in, when parsing a template -- some
748 /// seemingly harmless change elsewhere in Sema could cause us to start or stop
749 /// building such a node. So we need a rule that anyone can implement and get
750 /// exactly the same result".
752 void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
753 assert(isa<DeclRefExpr>(CapturingVarExpr)
754 || isa<MemberExpr>(CapturingVarExpr));
755 NonODRUsedCapturingExprs.insert(CapturingVarExpr);
757 bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
758 assert(isa<DeclRefExpr>(CapturingVarExpr)
759 || isa<MemberExpr>(CapturingVarExpr));
760 return NonODRUsedCapturingExprs.count(CapturingVarExpr);
762 void removePotentialCapture(Expr *E) {
763 PotentiallyCapturingExprs.erase(
764 std::remove(PotentiallyCapturingExprs.begin(),
765 PotentiallyCapturingExprs.end(), E),
766 PotentiallyCapturingExprs.end());
768 void clearPotentialCaptures() {
769 PotentiallyCapturingExprs.clear();
770 PotentialThisCaptureLocation = SourceLocation();
772 unsigned getNumPotentialVariableCaptures() const {
773 return PotentiallyCapturingExprs.size();
776 bool hasPotentialCaptures() const {
777 return getNumPotentialVariableCaptures() ||
778 PotentialThisCaptureLocation.isValid();
781 // When passed the index, returns the VarDecl and Expr associated
783 void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const;
786 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
787 : Base(nullptr, false), Property(nullptr) {}
789 FunctionScopeInfo::WeakObjectProfileTy
790 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
791 FunctionScopeInfo::WeakObjectProfileTy Result;
792 Result.Base.setInt(true);
796 template <typename ExprT>
797 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
799 WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
800 Uses.push_back(WeakUseTy(E, IsRead));
804 CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
805 QualType CaptureType, Expr *Cpy) {
806 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
808 CXXThisCaptureIndex = Captures.size();
810 if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
811 LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
814 } // end namespace sema
815 } // end namespace clang