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