Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:01

0001 //===- ScopeInfo.h - Information about a semantic context -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines FunctionScopeInfo and its subclasses, which contain
0010 // information about a single function, block, lambda, or method body.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_SEMA_SCOPEINFO_H
0015 #define LLVM_CLANG_SEMA_SCOPEINFO_H
0016 
0017 #include "clang/AST/Expr.h"
0018 #include "clang/AST/ExprCXX.h"
0019 #include "clang/AST/Type.h"
0020 #include "clang/Basic/CapturedStmt.h"
0021 #include "clang/Basic/LLVM.h"
0022 #include "clang/Basic/PartialDiagnostic.h"
0023 #include "clang/Basic/SourceLocation.h"
0024 #include "clang/Sema/CleanupInfo.h"
0025 #include "clang/Sema/DeclSpec.h"
0026 #include "llvm/ADT/DenseMap.h"
0027 #include "llvm/ADT/DenseMapInfo.h"
0028 #include "llvm/ADT/MapVector.h"
0029 #include "llvm/ADT/PointerIntPair.h"
0030 #include "llvm/ADT/SmallPtrSet.h"
0031 #include "llvm/ADT/SmallSet.h"
0032 #include "llvm/ADT/SmallVector.h"
0033 #include "llvm/ADT/StringRef.h"
0034 #include "llvm/ADT/StringSwitch.h"
0035 #include "llvm/ADT/TinyPtrVector.h"
0036 #include "llvm/Support/Casting.h"
0037 #include "llvm/Support/ErrorHandling.h"
0038 #include <algorithm>
0039 #include <cassert>
0040 #include <utility>
0041 
0042 namespace clang {
0043 
0044 class BlockDecl;
0045 class CapturedDecl;
0046 class CXXMethodDecl;
0047 class CXXRecordDecl;
0048 class ImplicitParamDecl;
0049 class NamedDecl;
0050 class ObjCIvarRefExpr;
0051 class ObjCMessageExpr;
0052 class ObjCPropertyDecl;
0053 class ObjCPropertyRefExpr;
0054 class ParmVarDecl;
0055 class RecordDecl;
0056 class ReturnStmt;
0057 class Scope;
0058 class Stmt;
0059 class SwitchStmt;
0060 class TemplateParameterList;
0061 class VarDecl;
0062 
0063 namespace sema {
0064 
0065 /// Contains information about the compound statement currently being
0066 /// parsed.
0067 class CompoundScopeInfo {
0068 public:
0069   /// Whether this compound statement contains `for' or `while' loops
0070   /// with empty bodies.
0071   bool HasEmptyLoopBodies = false;
0072 
0073   /// Whether this compound statement corresponds to a GNU statement
0074   /// expression.
0075   bool IsStmtExpr;
0076 
0077   /// FP options at the beginning of the compound statement, prior to
0078   /// any pragma.
0079   FPOptions InitialFPFeatures;
0080 
0081   CompoundScopeInfo(bool IsStmtExpr, FPOptions FPO)
0082       : IsStmtExpr(IsStmtExpr), InitialFPFeatures(FPO) {}
0083 
0084   void setHasEmptyLoopBodies() {
0085     HasEmptyLoopBodies = true;
0086   }
0087 };
0088 
0089 class PossiblyUnreachableDiag {
0090 public:
0091   PartialDiagnostic PD;
0092   SourceLocation Loc;
0093   llvm::TinyPtrVector<const Stmt*> Stmts;
0094 
0095   PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
0096                           ArrayRef<const Stmt *> Stmts)
0097       : PD(PD), Loc(Loc), Stmts(Stmts) {}
0098 };
0099 
0100 enum class FirstCoroutineStmtKind { CoReturn, CoAwait, CoYield };
0101 
0102 /// Retains information about a function, method, or block that is
0103 /// currently being parsed.
0104 class FunctionScopeInfo {
0105 protected:
0106   enum ScopeKind {
0107     SK_Function,
0108     SK_Block,
0109     SK_Lambda,
0110     SK_CapturedRegion
0111   };
0112 
0113 public:
0114   /// What kind of scope we are describing.
0115   ScopeKind Kind : 3;
0116 
0117   /// Whether this function contains a VLA, \@try, try, C++
0118   /// initializer, or anything else that can't be jumped past.
0119   bool HasBranchProtectedScope : 1;
0120 
0121   /// Whether this function contains any switches or direct gotos.
0122   bool HasBranchIntoScope : 1;
0123 
0124   /// Whether this function contains any indirect gotos.
0125   bool HasIndirectGoto : 1;
0126 
0127   /// Whether this function contains any statement marked with
0128   /// \c [[clang::musttail]].
0129   bool HasMustTail : 1;
0130 
0131   /// Whether a statement was dropped because it was invalid.
0132   bool HasDroppedStmt : 1;
0133 
0134   /// True if current scope is for OpenMP declare reduction combiner.
0135   bool HasOMPDeclareReductionCombiner : 1;
0136 
0137   /// Whether there is a fallthrough statement in this function.
0138   bool HasFallthroughStmt : 1;
0139 
0140   /// Whether this function uses constrained floating point intrinsics
0141   bool UsesFPIntrin : 1;
0142 
0143   /// Whether we make reference to a declaration that could be
0144   /// unavailable.
0145   bool HasPotentialAvailabilityViolations : 1;
0146 
0147   /// A flag that is set when parsing a method that must call super's
0148   /// implementation, such as \c -dealloc, \c -finalize, or any method marked
0149   /// with \c __attribute__((objc_requires_super)).
0150   bool ObjCShouldCallSuper : 1;
0151 
0152   /// True when this is a method marked as a designated initializer.
0153   bool ObjCIsDesignatedInit : 1;
0154 
0155   /// This starts true for a method marked as designated initializer and will
0156   /// be set to false if there is an invocation to a designated initializer of
0157   /// the super class.
0158   bool ObjCWarnForNoDesignatedInitChain : 1;
0159 
0160   /// True when this is an initializer method not marked as a designated
0161   /// initializer within a class that has at least one initializer marked as a
0162   /// designated initializer.
0163   bool ObjCIsSecondaryInit : 1;
0164 
0165   /// This starts true for a secondary initializer method and will be set to
0166   /// false if there is an invocation of an initializer on 'self'.
0167   bool ObjCWarnForNoInitDelegation : 1;
0168 
0169   /// True only when this function has not already built, or attempted
0170   /// to build, the initial and final coroutine suspend points
0171   bool NeedsCoroutineSuspends : 1;
0172 
0173   /// An enumeration representing the kind of the first coroutine statement
0174   /// in the function. One of co_return, co_await, or co_yield.
0175   LLVM_PREFERRED_TYPE(FirstCoroutineStmtKind)
0176   unsigned char FirstCoroutineStmtKind : 2;
0177 
0178   /// Whether we found an immediate-escalating expression.
0179   bool FoundImmediateEscalatingExpression : 1;
0180 
0181   /// First coroutine statement in the current function.
0182   /// (ex co_return, co_await, co_yield)
0183   SourceLocation FirstCoroutineStmtLoc;
0184 
0185   /// First 'return' statement in the current function.
0186   SourceLocation FirstReturnLoc;
0187 
0188   /// First C++ 'try' or ObjC @try statement in the current function.
0189   SourceLocation FirstCXXOrObjCTryLoc;
0190   enum { TryLocIsCXX, TryLocIsObjC, Unknown } FirstTryType = Unknown;
0191 
0192   /// First SEH '__try' statement in the current function.
0193   SourceLocation FirstSEHTryLoc;
0194 
0195   /// First use of a VLA within the current function.
0196   SourceLocation FirstVLALoc;
0197 
0198 private:
0199   /// Used to determine if errors occurred in this function or block.
0200   DiagnosticErrorTrap ErrorTrap;
0201 
0202 public:
0203   /// A SwitchStmt, along with a flag indicating if its list of case statements
0204   /// is incomplete (because we dropped an invalid one while parsing).
0205   using SwitchInfo = llvm::PointerIntPair<SwitchStmt*, 1, bool>;
0206 
0207   /// SwitchStack - This is the current set of active switch statements in the
0208   /// block.
0209   SmallVector<SwitchInfo, 8> SwitchStack;
0210 
0211   /// The list of return statements that occur within the function or
0212   /// block, if there is any chance of applying the named return value
0213   /// optimization, or if we need to infer a return type.
0214   SmallVector<ReturnStmt*, 4> Returns;
0215 
0216   /// The promise object for this coroutine, if any.
0217   VarDecl *CoroutinePromise = nullptr;
0218 
0219   /// A mapping between the coroutine function parameters that were moved
0220   /// to the coroutine frame, and their move statements.
0221   llvm::SmallMapVector<ParmVarDecl *, Stmt *, 4> CoroutineParameterMoves;
0222 
0223   /// The initial and final coroutine suspend points.
0224   std::pair<Stmt *, Stmt *> CoroutineSuspends;
0225 
0226   /// The stack of currently active compound statement scopes in the
0227   /// function.
0228   SmallVector<CompoundScopeInfo, 4> CompoundScopes;
0229 
0230   /// The set of blocks that are introduced in this function.
0231   llvm::SmallPtrSet<const BlockDecl *, 1> Blocks;
0232 
0233   /// The set of __block variables that are introduced in this function.
0234   llvm::TinyPtrVector<VarDecl *> ByrefBlockVars;
0235 
0236   /// A list of PartialDiagnostics created but delayed within the
0237   /// current function scope.  These diagnostics are vetted for reachability
0238   /// prior to being emitted.
0239   SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
0240 
0241   /// A list of parameters which have the nonnull attribute and are
0242   /// modified in the function.
0243   llvm::SmallPtrSet<const ParmVarDecl *, 8> ModifiedNonNullParams;
0244 
0245   /// The set of GNU address of label extension "&&label".
0246   llvm::SmallVector<AddrLabelExpr *, 4> AddrLabels;
0247 
0248 public:
0249   /// Represents a simple identification of a weak object.
0250   ///
0251   /// Part of the implementation of -Wrepeated-use-of-weak.
0252   ///
0253   /// This is used to determine if two weak accesses refer to the same object.
0254   /// Here are some examples of how various accesses are "profiled":
0255   ///
0256   /// Access Expression |     "Base" Decl     |          "Property" Decl
0257   /// :---------------: | :-----------------: | :------------------------------:
0258   /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
0259   /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
0260   /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
0261   /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
0262   /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
0263   /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
0264   /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
0265   /// MyClass.foo.prop  | +foo (ObjCMethodDecl)       | -prop (ObjCPropertyDecl)
0266   /// weakVar           | 0 (known)           | weakVar (VarDecl)
0267   /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
0268   ///
0269   /// Objects are identified with only two Decls to make it reasonably fast to
0270   /// compare them.
0271   class WeakObjectProfileTy {
0272     /// The base object decl, as described in the class documentation.
0273     ///
0274     /// The extra flag is "true" if the Base and Property are enough to uniquely
0275     /// identify the object in memory.
0276     ///
0277     /// \sa isExactProfile()
0278     using BaseInfoTy = llvm::PointerIntPair<const NamedDecl *, 1, bool>;
0279     BaseInfoTy Base;
0280 
0281     /// The "property" decl, as described in the class documentation.
0282     ///
0283     /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
0284     /// case of "implicit" properties (regular methods accessed via dot syntax).
0285     const NamedDecl *Property = nullptr;
0286 
0287     /// Used to find the proper base profile for a given base expression.
0288     static BaseInfoTy getBaseInfo(const Expr *BaseE);
0289 
0290     inline WeakObjectProfileTy();
0291     static inline WeakObjectProfileTy getSentinel();
0292 
0293   public:
0294     WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
0295     WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
0296     WeakObjectProfileTy(const DeclRefExpr *RE);
0297     WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
0298 
0299     const NamedDecl *getBase() const { return Base.getPointer(); }
0300     const NamedDecl *getProperty() const { return Property; }
0301 
0302     /// Returns true if the object base specifies a known object in memory,
0303     /// rather than, say, an instance variable or property of another object.
0304     ///
0305     /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
0306     /// considered an exact profile if \c foo is a local variable, even if
0307     /// another variable \c foo2 refers to the same object as \c foo.
0308     ///
0309     /// For increased precision, accesses with base variables that are
0310     /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
0311     /// be exact, though this is not true for arbitrary variables
0312     /// (foo.prop1.prop2).
0313     bool isExactProfile() const {
0314       return Base.getInt();
0315     }
0316 
0317     bool operator==(const WeakObjectProfileTy &Other) const {
0318       return Base == Other.Base && Property == Other.Property;
0319     }
0320 
0321     // For use in DenseMap.
0322     // We can't specialize the usual llvm::DenseMapInfo at the end of the file
0323     // because by that point the DenseMap in FunctionScopeInfo has already been
0324     // instantiated.
0325     class DenseMapInfo {
0326     public:
0327       static inline WeakObjectProfileTy getEmptyKey() {
0328         return WeakObjectProfileTy();
0329       }
0330 
0331       static inline WeakObjectProfileTy getTombstoneKey() {
0332         return WeakObjectProfileTy::getSentinel();
0333       }
0334 
0335       static unsigned getHashValue(const WeakObjectProfileTy &Val) {
0336         using Pair = std::pair<BaseInfoTy, const NamedDecl *>;
0337 
0338         return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
0339                                                            Val.Property));
0340       }
0341 
0342       static bool isEqual(const WeakObjectProfileTy &LHS,
0343                           const WeakObjectProfileTy &RHS) {
0344         return LHS == RHS;
0345       }
0346     };
0347   };
0348 
0349   /// Represents a single use of a weak object.
0350   ///
0351   /// Stores both the expression and whether the access is potentially unsafe
0352   /// (i.e. it could potentially be warned about).
0353   ///
0354   /// Part of the implementation of -Wrepeated-use-of-weak.
0355   class WeakUseTy {
0356     llvm::PointerIntPair<const Expr *, 1, bool> Rep;
0357 
0358   public:
0359     WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
0360 
0361     const Expr *getUseExpr() const { return Rep.getPointer(); }
0362     bool isUnsafe() const { return Rep.getInt(); }
0363     void markSafe() { Rep.setInt(false); }
0364 
0365     bool operator==(const WeakUseTy &Other) const {
0366       return Rep == Other.Rep;
0367     }
0368   };
0369 
0370   /// Used to collect uses of a particular weak object in a function body.
0371   ///
0372   /// Part of the implementation of -Wrepeated-use-of-weak.
0373   using WeakUseVector = SmallVector<WeakUseTy, 4>;
0374 
0375   /// Used to collect all uses of weak objects in a function body.
0376   ///
0377   /// Part of the implementation of -Wrepeated-use-of-weak.
0378   using WeakObjectUseMap =
0379       llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
0380                           WeakObjectProfileTy::DenseMapInfo>;
0381 
0382 private:
0383   /// Used to collect all uses of weak objects in this function body.
0384   ///
0385   /// Part of the implementation of -Wrepeated-use-of-weak.
0386   WeakObjectUseMap WeakObjectUses;
0387 
0388 protected:
0389   FunctionScopeInfo(const FunctionScopeInfo&) = default;
0390 
0391 public:
0392   FunctionScopeInfo(DiagnosticsEngine &Diag)
0393       : Kind(SK_Function), HasBranchProtectedScope(false),
0394         HasBranchIntoScope(false), HasIndirectGoto(false), HasMustTail(false),
0395         HasDroppedStmt(false), HasOMPDeclareReductionCombiner(false),
0396         HasFallthroughStmt(false), UsesFPIntrin(false),
0397         HasPotentialAvailabilityViolations(false), ObjCShouldCallSuper(false),
0398         ObjCIsDesignatedInit(false), ObjCWarnForNoDesignatedInitChain(false),
0399         ObjCIsSecondaryInit(false), ObjCWarnForNoInitDelegation(false),
0400         NeedsCoroutineSuspends(true), FoundImmediateEscalatingExpression(false),
0401         ErrorTrap(Diag) {}
0402 
0403   virtual ~FunctionScopeInfo();
0404 
0405   /// Determine whether an unrecoverable error has occurred within this
0406   /// function. Note that this may return false even if the function body is
0407   /// invalid, because the errors may be suppressed if they're caused by prior
0408   /// invalid declarations.
0409   ///
0410   /// FIXME: Migrate the caller of this to use containsErrors() instead once
0411   /// it's ready.
0412   bool hasUnrecoverableErrorOccurred() const {
0413     return ErrorTrap.hasUnrecoverableErrorOccurred();
0414   }
0415 
0416   /// Record that a weak object was accessed.
0417   ///
0418   /// Part of the implementation of -Wrepeated-use-of-weak.
0419   template <typename ExprT>
0420   inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
0421 
0422   void recordUseOfWeak(const ObjCMessageExpr *Msg,
0423                        const ObjCPropertyDecl *Prop);
0424 
0425   /// Record that a given expression is a "safe" access of a weak object (e.g.
0426   /// assigning it to a strong variable.)
0427   ///
0428   /// Part of the implementation of -Wrepeated-use-of-weak.
0429   void markSafeWeakUse(const Expr *E);
0430 
0431   const WeakObjectUseMap &getWeakObjectUses() const {
0432     return WeakObjectUses;
0433   }
0434 
0435   void setHasBranchIntoScope() {
0436     HasBranchIntoScope = true;
0437   }
0438 
0439   void setHasBranchProtectedScope() {
0440     HasBranchProtectedScope = true;
0441   }
0442 
0443   void setHasIndirectGoto() {
0444     HasIndirectGoto = true;
0445   }
0446 
0447   void setHasMustTail() { HasMustTail = true; }
0448 
0449   void setHasDroppedStmt() {
0450     HasDroppedStmt = true;
0451   }
0452 
0453   void setHasOMPDeclareReductionCombiner() {
0454     HasOMPDeclareReductionCombiner = true;
0455   }
0456 
0457   void setHasFallthroughStmt() {
0458     HasFallthroughStmt = true;
0459   }
0460 
0461   void setUsesFPIntrin() {
0462     UsesFPIntrin = true;
0463   }
0464 
0465   void setHasCXXTry(SourceLocation TryLoc) {
0466     setHasBranchProtectedScope();
0467     FirstCXXOrObjCTryLoc = TryLoc;
0468     FirstTryType = TryLocIsCXX;
0469   }
0470 
0471   void setHasObjCTry(SourceLocation TryLoc) {
0472     setHasBranchProtectedScope();
0473     FirstCXXOrObjCTryLoc = TryLoc;
0474     FirstTryType = TryLocIsObjC;
0475   }
0476 
0477   void setHasSEHTry(SourceLocation TryLoc) {
0478     setHasBranchProtectedScope();
0479     FirstSEHTryLoc = TryLoc;
0480   }
0481 
0482   void setHasVLA(SourceLocation VLALoc) {
0483     if (FirstVLALoc.isInvalid())
0484       FirstVLALoc = VLALoc;
0485   }
0486 
0487   bool NeedsScopeChecking() const {
0488     return !HasDroppedStmt && (HasIndirectGoto || HasMustTail ||
0489                                (HasBranchProtectedScope && HasBranchIntoScope));
0490   }
0491 
0492   // Add a block introduced in this function.
0493   void addBlock(const BlockDecl *BD) {
0494     Blocks.insert(BD);
0495   }
0496 
0497   // Add a __block variable introduced in this function.
0498   void addByrefBlockVar(VarDecl *VD) {
0499     ByrefBlockVars.push_back(VD);
0500   }
0501 
0502   bool isCoroutine() const { return !FirstCoroutineStmtLoc.isInvalid(); }
0503 
0504   void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword) {
0505     assert(FirstCoroutineStmtLoc.isInvalid() &&
0506                    "first coroutine statement location already set");
0507     FirstCoroutineStmtLoc = Loc;
0508     FirstCoroutineStmtKind =
0509         llvm::StringSwitch<unsigned char>(Keyword)
0510             .Case("co_return",
0511                   llvm::to_underlying(FirstCoroutineStmtKind::CoReturn))
0512             .Case("co_await",
0513                   llvm::to_underlying(FirstCoroutineStmtKind::CoAwait))
0514             .Case("co_yield",
0515                   llvm::to_underlying(FirstCoroutineStmtKind::CoYield));
0516   }
0517 
0518   StringRef getFirstCoroutineStmtKeyword() const {
0519     assert(FirstCoroutineStmtLoc.isValid()
0520                    && "no coroutine statement available");
0521     auto Value =
0522         static_cast<enum FirstCoroutineStmtKind>(FirstCoroutineStmtKind);
0523     switch (Value) {
0524     case FirstCoroutineStmtKind::CoReturn:
0525       return "co_return";
0526     case FirstCoroutineStmtKind::CoAwait:
0527       return "co_await";
0528     case FirstCoroutineStmtKind::CoYield:
0529       return "co_yield";
0530     };
0531     llvm_unreachable("FirstCoroutineStmtKind has an invalid value");
0532   }
0533 
0534   void setNeedsCoroutineSuspends(bool value = true) {
0535     assert((!value || CoroutineSuspends.first == nullptr) &&
0536             "we already have valid suspend points");
0537     NeedsCoroutineSuspends = value;
0538   }
0539 
0540   bool hasInvalidCoroutineSuspends() const {
0541     return !NeedsCoroutineSuspends && CoroutineSuspends.first == nullptr;
0542   }
0543 
0544   void setCoroutineSuspends(Stmt *Initial, Stmt *Final) {
0545     assert(Initial && Final && "suspend points cannot be null");
0546     assert(CoroutineSuspends.first == nullptr && "suspend points already set");
0547     NeedsCoroutineSuspends = false;
0548     CoroutineSuspends.first = Initial;
0549     CoroutineSuspends.second = Final;
0550   }
0551 
0552   /// Clear out the information in this function scope, making it
0553   /// suitable for reuse.
0554   void Clear();
0555 
0556   bool isPlainFunction() const { return Kind == SK_Function; }
0557 };
0558 
0559 class Capture {
0560   // There are three categories of capture: capturing 'this', capturing
0561   // local variables, and C++1y initialized captures (which can have an
0562   // arbitrary initializer, and don't really capture in the traditional
0563   // sense at all).
0564   //
0565   // There are three ways to capture a local variable:
0566   //  - capture by copy in the C++11 sense,
0567   //  - capture by reference in the C++11 sense, and
0568   //  - __block capture.
0569   // Lambdas explicitly specify capture by copy or capture by reference.
0570   // For blocks, __block capture applies to variables with that annotation,
0571   // variables of reference type are captured by reference, and other
0572   // variables are captured by copy.
0573   enum CaptureKind {
0574     Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
0575   };
0576 
0577   union {
0578     /// If Kind == Cap_VLA, the captured type.
0579     const VariableArrayType *CapturedVLA;
0580 
0581     /// Otherwise, the captured variable (if any).
0582     ValueDecl *CapturedVar;
0583   };
0584 
0585   /// The source location at which the first capture occurred.
0586   SourceLocation Loc;
0587 
0588   /// The location of the ellipsis that expands a parameter pack.
0589   SourceLocation EllipsisLoc;
0590 
0591   /// The type as it was captured, which is the type of the non-static data
0592   /// member that would hold the capture.
0593   QualType CaptureType;
0594 
0595   /// The CaptureKind of this capture.
0596   LLVM_PREFERRED_TYPE(CaptureKind)
0597   unsigned Kind : 2;
0598 
0599   /// Whether this is a nested capture (a capture of an enclosing capturing
0600   /// scope's capture).
0601   LLVM_PREFERRED_TYPE(bool)
0602   unsigned Nested : 1;
0603 
0604   /// Whether this is a capture of '*this'.
0605   LLVM_PREFERRED_TYPE(bool)
0606   unsigned CapturesThis : 1;
0607 
0608   /// Whether an explicit capture has been odr-used in the body of the
0609   /// lambda.
0610   LLVM_PREFERRED_TYPE(bool)
0611   unsigned ODRUsed : 1;
0612 
0613   /// Whether an explicit capture has been non-odr-used in the body of
0614   /// the lambda.
0615   LLVM_PREFERRED_TYPE(bool)
0616   unsigned NonODRUsed : 1;
0617 
0618   /// Whether the capture is invalid (a capture was required but the entity is
0619   /// non-capturable).
0620   LLVM_PREFERRED_TYPE(bool)
0621   unsigned Invalid : 1;
0622 
0623 public:
0624   Capture(ValueDecl *Var, bool Block, bool ByRef, bool IsNested,
0625           SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType,
0626           bool Invalid)
0627       : CapturedVar(Var), Loc(Loc), EllipsisLoc(EllipsisLoc),
0628         CaptureType(CaptureType), Kind(Block   ? Cap_Block
0629                                        : ByRef ? Cap_ByRef
0630                                                : Cap_ByCopy),
0631         Nested(IsNested), CapturesThis(false), ODRUsed(false),
0632         NonODRUsed(false), Invalid(Invalid) {}
0633 
0634   enum IsThisCapture { ThisCapture };
0635   Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
0636           QualType CaptureType, const bool ByCopy, bool Invalid)
0637       : Loc(Loc), CaptureType(CaptureType),
0638         Kind(ByCopy ? Cap_ByCopy : Cap_ByRef), Nested(IsNested),
0639         CapturesThis(true), ODRUsed(false), NonODRUsed(false),
0640         Invalid(Invalid) {}
0641 
0642   enum IsVLACapture { VLACapture };
0643   Capture(IsVLACapture, const VariableArrayType *VLA, bool IsNested,
0644           SourceLocation Loc, QualType CaptureType)
0645       : CapturedVLA(VLA), Loc(Loc), CaptureType(CaptureType), Kind(Cap_VLA),
0646         Nested(IsNested), CapturesThis(false), ODRUsed(false),
0647         NonODRUsed(false), Invalid(false) {}
0648 
0649   bool isThisCapture() const { return CapturesThis; }
0650   bool isVariableCapture() const {
0651     return !isThisCapture() && !isVLATypeCapture();
0652   }
0653 
0654   bool isCopyCapture() const { return Kind == Cap_ByCopy; }
0655   bool isReferenceCapture() const { return Kind == Cap_ByRef; }
0656   bool isBlockCapture() const { return Kind == Cap_Block; }
0657   bool isVLATypeCapture() const { return Kind == Cap_VLA; }
0658 
0659   bool isNested() const { return Nested; }
0660 
0661   bool isInvalid() const { return Invalid; }
0662 
0663   /// Determine whether this capture is an init-capture.
0664   bool isInitCapture() const;
0665 
0666   bool isODRUsed() const { return ODRUsed; }
0667   bool isNonODRUsed() const { return NonODRUsed; }
0668   void markUsed(bool IsODRUse) {
0669     if (IsODRUse)
0670       ODRUsed = true;
0671     else
0672       NonODRUsed = true;
0673   }
0674 
0675   ValueDecl *getVariable() const {
0676     assert(isVariableCapture());
0677     return CapturedVar;
0678   }
0679 
0680   const VariableArrayType *getCapturedVLAType() const {
0681     assert(isVLATypeCapture());
0682     return CapturedVLA;
0683   }
0684 
0685   /// Retrieve the location at which this variable was captured.
0686   SourceLocation getLocation() const { return Loc; }
0687 
0688   /// Retrieve the source location of the ellipsis, whose presence
0689   /// indicates that the capture is a pack expansion.
0690   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
0691 
0692   /// Retrieve the capture type for this capture, which is effectively
0693   /// the type of the non-static data member in the lambda/block structure
0694   /// that would store this capture.
0695   QualType getCaptureType() const { return CaptureType; }
0696 };
0697 
0698 class CapturingScopeInfo : public FunctionScopeInfo {
0699 protected:
0700   CapturingScopeInfo(const CapturingScopeInfo&) = default;
0701 
0702 public:
0703   enum ImplicitCaptureStyle {
0704     ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
0705     ImpCap_CapturedRegion
0706   };
0707 
0708   ImplicitCaptureStyle ImpCaptureStyle;
0709 
0710   CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
0711       : FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
0712 
0713   /// CaptureMap - A map of captured variables to (index+1) into Captures.
0714   llvm::DenseMap<ValueDecl *, unsigned> CaptureMap;
0715 
0716   /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
0717   /// zero if 'this' is not captured.
0718   unsigned CXXThisCaptureIndex = 0;
0719 
0720   /// Captures - The captures.
0721   SmallVector<Capture, 4> Captures;
0722 
0723   /// - Whether the target type of return statements in this context
0724   /// is deduced (e.g. a lambda or block with omitted return type).
0725   bool HasImplicitReturnType = false;
0726 
0727   /// Whether this contains an unexpanded parameter pack.
0728   bool ContainsUnexpandedParameterPack = false;
0729 
0730   /// ReturnType - The target type of return statements in this context,
0731   /// or null if unknown.
0732   QualType ReturnType;
0733 
0734   /// Packs introduced by this, if any.
0735   SmallVector<NamedDecl *, 4> LocalPacks;
0736 
0737   void addCapture(ValueDecl *Var, bool isBlock, bool isByref, bool isNested,
0738                   SourceLocation Loc, SourceLocation EllipsisLoc,
0739                   QualType CaptureType, bool Invalid) {
0740     Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
0741                                EllipsisLoc, CaptureType, Invalid));
0742     CaptureMap[Var] = Captures.size();
0743   }
0744 
0745   void addVLATypeCapture(SourceLocation Loc, const VariableArrayType *VLAType,
0746                          QualType CaptureType) {
0747     Captures.push_back(Capture(Capture::VLACapture, VLAType,
0748                                /*FIXME: IsNested*/ false, Loc, CaptureType));
0749   }
0750 
0751   void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
0752                       bool ByCopy);
0753 
0754   /// Determine whether the C++ 'this' is captured.
0755   bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
0756 
0757   /// Retrieve the capture of C++ 'this', if it has been captured.
0758   Capture &getCXXThisCapture() {
0759     assert(isCXXThisCaptured() && "this has not been captured");
0760     return Captures[CXXThisCaptureIndex - 1];
0761   }
0762 
0763   /// Determine whether the given variable has been captured.
0764   bool isCaptured(ValueDecl *Var) const { return CaptureMap.count(Var); }
0765 
0766   /// Determine whether the given variable-array type has been captured.
0767   bool isVLATypeCaptured(const VariableArrayType *VAT) const;
0768 
0769   /// Retrieve the capture of the given variable, if it has been
0770   /// captured already.
0771   Capture &getCapture(ValueDecl *Var) {
0772     assert(isCaptured(Var) && "Variable has not been captured");
0773     return Captures[CaptureMap[Var] - 1];
0774   }
0775 
0776   const Capture &getCapture(ValueDecl *Var) const {
0777     llvm::DenseMap<ValueDecl *, unsigned>::const_iterator Known =
0778         CaptureMap.find(Var);
0779     assert(Known != CaptureMap.end() && "Variable has not been captured");
0780     return Captures[Known->second - 1];
0781   }
0782 
0783   static bool classof(const FunctionScopeInfo *FSI) {
0784     return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
0785                                  || FSI->Kind == SK_CapturedRegion;
0786   }
0787 };
0788 
0789 /// Retains information about a block that is currently being parsed.
0790 class BlockScopeInfo final : public CapturingScopeInfo {
0791 public:
0792   BlockDecl *TheDecl;
0793 
0794   /// TheScope - This is the scope for the block itself, which contains
0795   /// arguments etc.
0796   Scope *TheScope;
0797 
0798   /// BlockType - The function type of the block, if one was given.
0799   /// Its return type may be BuiltinType::Dependent.
0800   QualType FunctionType;
0801 
0802   BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
0803       : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
0804         TheScope(BlockScope) {
0805     Kind = SK_Block;
0806   }
0807 
0808   ~BlockScopeInfo() override;
0809 
0810   static bool classof(const FunctionScopeInfo *FSI) {
0811     return FSI->Kind == SK_Block;
0812   }
0813 };
0814 
0815 /// Retains information about a captured region.
0816 class CapturedRegionScopeInfo final : public CapturingScopeInfo {
0817 public:
0818   /// The CapturedDecl for this statement.
0819   CapturedDecl *TheCapturedDecl;
0820 
0821   /// The captured record type.
0822   RecordDecl *TheRecordDecl;
0823 
0824   /// This is the enclosing scope of the captured region.
0825   Scope *TheScope;
0826 
0827   /// The implicit parameter for the captured variables.
0828   ImplicitParamDecl *ContextParam;
0829 
0830   /// The kind of captured region.
0831   unsigned short CapRegionKind;
0832 
0833   unsigned short OpenMPLevel;
0834   unsigned short OpenMPCaptureLevel;
0835 
0836   CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
0837                           RecordDecl *RD, ImplicitParamDecl *Context,
0838                           CapturedRegionKind K, unsigned OpenMPLevel,
0839                           unsigned OpenMPCaptureLevel)
0840       : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
0841         TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
0842         ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel),
0843         OpenMPCaptureLevel(OpenMPCaptureLevel) {
0844     Kind = SK_CapturedRegion;
0845   }
0846 
0847   ~CapturedRegionScopeInfo() override;
0848 
0849   /// A descriptive name for the kind of captured region this is.
0850   StringRef getRegionName() const {
0851     switch (CapRegionKind) {
0852     case CR_Default:
0853       return "default captured statement";
0854     case CR_ObjCAtFinally:
0855       return "Objective-C @finally statement";
0856     case CR_OpenMP:
0857       return "OpenMP region";
0858     }
0859     llvm_unreachable("Invalid captured region kind!");
0860   }
0861 
0862   static bool classof(const FunctionScopeInfo *FSI) {
0863     return FSI->Kind == SK_CapturedRegion;
0864   }
0865 };
0866 
0867 class LambdaScopeInfo final :
0868     public CapturingScopeInfo, public InventedTemplateParameterInfo {
0869 public:
0870   /// The class that describes the lambda.
0871   CXXRecordDecl *Lambda = nullptr;
0872 
0873   /// The lambda's compiler-generated \c operator().
0874   CXXMethodDecl *CallOperator = nullptr;
0875 
0876   /// Indicate that we parsed the parameter list
0877   /// at which point the mutability of the lambda
0878   /// is known.
0879   bool AfterParameterList = true;
0880 
0881   ParmVarDecl *ExplicitObjectParameter = nullptr;
0882 
0883   /// Source range covering the lambda introducer [...].
0884   SourceRange IntroducerRange;
0885 
0886   /// Source location of the '&' or '=' specifying the default capture
0887   /// type, if any.
0888   SourceLocation CaptureDefaultLoc;
0889 
0890   /// The number of captures in the \c Captures list that are
0891   /// explicit captures.
0892   unsigned NumExplicitCaptures = 0;
0893 
0894   /// Whether this is a mutable lambda. Until the mutable keyword is parsed,
0895   /// we assume the lambda is mutable.
0896   bool Mutable = true;
0897 
0898   /// Whether the (empty) parameter list is explicit.
0899   bool ExplicitParams = false;
0900 
0901   /// Whether any of the capture expressions requires cleanups.
0902   CleanupInfo Cleanup;
0903 
0904   /// Source range covering the explicit template parameter list (if it exists).
0905   SourceRange ExplicitTemplateParamsRange;
0906 
0907   /// The requires-clause immediately following the explicit template parameter
0908   /// list, if any. (Note that there may be another requires-clause included as
0909   /// part of the lambda-declarator.)
0910   ExprResult RequiresClause;
0911 
0912   /// If this is a generic lambda, and the template parameter
0913   /// list has been created (from the TemplateParams) then store
0914   /// a reference to it (cache it to avoid reconstructing it).
0915   TemplateParameterList *GLTemplateParameterList = nullptr;
0916 
0917   /// Contains all variable-referring-expressions (i.e. DeclRefExprs
0918   ///  or MemberExprs) that refer to local variables in a generic lambda
0919   ///  or a lambda in a potentially-evaluated-if-used context.
0920   ///
0921   ///  Potentially capturable variables of a nested lambda that might need
0922   ///   to be captured by the lambda are housed here.
0923   ///  This is specifically useful for generic lambdas or
0924   ///  lambdas within a potentially evaluated-if-used context.
0925   ///  If an enclosing variable is named in an expression of a lambda nested
0926   ///  within a generic lambda, we don't always know whether the variable
0927   ///  will truly be odr-used (i.e. need to be captured) by that nested lambda,
0928   ///  until its instantiation. But we still need to capture it in the
0929   ///  enclosing lambda if all intervening lambdas can capture the variable.
0930   llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
0931 
0932   /// Contains all variable-referring-expressions that refer
0933   ///  to local variables that are usable as constant expressions and
0934   ///  do not involve an odr-use (they may still need to be captured
0935   ///  if the enclosing full-expression is instantiation dependent).
0936   llvm::SmallSet<Expr *, 8> NonODRUsedCapturingExprs;
0937 
0938   /// A map of explicit capture indices to their introducer source ranges.
0939   llvm::DenseMap<unsigned, SourceRange> ExplicitCaptureRanges;
0940 
0941   /// Contains all of the variables defined in this lambda that shadow variables
0942   /// that were defined in parent contexts. Used to avoid warnings when the
0943   /// shadowed variables are uncaptured by this lambda.
0944   struct ShadowedOuterDecl {
0945     const NamedDecl *VD;
0946     const NamedDecl *ShadowedDecl;
0947   };
0948   llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls;
0949 
0950   SourceLocation PotentialThisCaptureLocation;
0951 
0952   LambdaScopeInfo(DiagnosticsEngine &Diag)
0953       : CapturingScopeInfo(Diag, ImpCap_None) {
0954     Kind = SK_Lambda;
0955   }
0956 
0957   /// Note when all explicit captures have been added.
0958   void finishedExplicitCaptures() {
0959     NumExplicitCaptures = Captures.size();
0960   }
0961 
0962   static bool classof(const FunctionScopeInfo *FSI) {
0963     return FSI->Kind == SK_Lambda;
0964   }
0965 
0966   /// Is this scope known to be for a generic lambda? (This will be false until
0967   /// we parse a template parameter list or the first 'auto'-typed parameter).
0968   bool isGenericLambda() const {
0969     return !TemplateParams.empty() || GLTemplateParameterList;
0970   }
0971 
0972   /// Add a variable that might potentially be captured by the
0973   /// lambda and therefore the enclosing lambdas.
0974   ///
0975   /// This is also used by enclosing lambda's to speculatively capture
0976   /// variables that nested lambda's - depending on their enclosing
0977   /// specialization - might need to capture.
0978   /// Consider:
0979   /// void f(int, int); <-- don't capture
0980   /// void f(const int&, double); <-- capture
0981   /// void foo() {
0982   ///   const int x = 10;
0983   ///   auto L = [=](auto a) { // capture 'x'
0984   ///      return [=](auto b) {
0985   ///        f(x, a);  // we may or may not need to capture 'x'
0986   ///      };
0987   ///   };
0988   /// }
0989   void addPotentialCapture(Expr *VarExpr) {
0990     assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr) ||
0991            isa<FunctionParmPackExpr>(VarExpr));
0992     PotentiallyCapturingExprs.push_back(VarExpr);
0993   }
0994 
0995   void addPotentialThisCapture(SourceLocation Loc) {
0996     PotentialThisCaptureLocation = Loc;
0997   }
0998 
0999   bool hasPotentialThisCapture() const {
1000     return PotentialThisCaptureLocation.isValid();
1001   }
1002 
1003   /// Mark a variable's reference in a lambda as non-odr using.
1004   ///
1005   /// For generic lambdas, if a variable is named in a potentially evaluated
1006   /// expression, where the enclosing full expression is dependent then we
1007   /// must capture the variable (given a default capture).
1008   /// This is accomplished by recording all references to variables
1009   /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of
1010   /// PotentialCaptures. All such variables have to be captured by that lambda,
1011   /// except for as described below.
1012   /// If that variable is usable as a constant expression and is named in a
1013   /// manner that does not involve its odr-use (e.g. undergoes
1014   /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
1015   /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
1016   /// if we can determine that the full expression is not instantiation-
1017   /// dependent, then we can entirely avoid its capture.
1018   ///
1019   ///   const int n = 0;
1020   ///   [&] (auto x) {
1021   ///     (void)+n + x;
1022   ///   };
1023   /// Interestingly, this strategy would involve a capture of n, even though
1024   /// it's obviously not odr-used here, because the full-expression is
1025   /// instantiation-dependent.  It could be useful to avoid capturing such
1026   /// variables, even when they are referred to in an instantiation-dependent
1027   /// expression, if we can unambiguously determine that they shall never be
1028   /// odr-used.  This would involve removal of the variable-referring-expression
1029   /// from the array of PotentialCaptures during the lvalue-to-rvalue
1030   /// conversions.  But per the working draft N3797, (post-chicago 2013) we must
1031   /// capture such variables.
1032   /// Before anyone is tempted to implement a strategy for not-capturing 'n',
1033   /// consider the insightful warning in:
1034   ///    /cfe-commits/Week-of-Mon-20131104/092596.html
1035   /// "The problem is that the set of captures for a lambda is part of the ABI
1036   ///  (since lambda layout can be made visible through inline functions and the
1037   ///  like), and there are no guarantees as to which cases we'll manage to build
1038   ///  an lvalue-to-rvalue conversion in, when parsing a template -- some
1039   ///  seemingly harmless change elsewhere in Sema could cause us to start or stop
1040   ///  building such a node. So we need a rule that anyone can implement and get
1041   ///  exactly the same result".
1042   void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
1043     assert(isa<DeclRefExpr>(CapturingVarExpr) ||
1044            isa<MemberExpr>(CapturingVarExpr) ||
1045            isa<FunctionParmPackExpr>(CapturingVarExpr));
1046     NonODRUsedCapturingExprs.insert(CapturingVarExpr);
1047   }
1048   bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
1049     assert(isa<DeclRefExpr>(CapturingVarExpr) ||
1050            isa<MemberExpr>(CapturingVarExpr) ||
1051            isa<FunctionParmPackExpr>(CapturingVarExpr));
1052     return NonODRUsedCapturingExprs.count(CapturingVarExpr);
1053   }
1054   void removePotentialCapture(Expr *E) {
1055     llvm::erase(PotentiallyCapturingExprs, E);
1056   }
1057   void clearPotentialCaptures() {
1058     PotentiallyCapturingExprs.clear();
1059     PotentialThisCaptureLocation = SourceLocation();
1060   }
1061   unsigned getNumPotentialVariableCaptures() const {
1062     return PotentiallyCapturingExprs.size();
1063   }
1064 
1065   bool hasPotentialCaptures() const {
1066     return getNumPotentialVariableCaptures() ||
1067                                   PotentialThisCaptureLocation.isValid();
1068   }
1069 
1070   void visitPotentialCaptures(
1071       llvm::function_ref<void(ValueDecl *, Expr *)> Callback) const;
1072 
1073   bool lambdaCaptureShouldBeConst() const;
1074 };
1075 
1076 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
1077     : Base(nullptr, false) {}
1078 
1079 FunctionScopeInfo::WeakObjectProfileTy
1080 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
1081   FunctionScopeInfo::WeakObjectProfileTy Result;
1082   Result.Base.setInt(true);
1083   return Result;
1084 }
1085 
1086 template <typename ExprT>
1087 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
1088   assert(E);
1089   WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
1090   Uses.push_back(WeakUseTy(E, IsRead));
1091 }
1092 
1093 inline void CapturingScopeInfo::addThisCapture(bool isNested,
1094                                                SourceLocation Loc,
1095                                                QualType CaptureType,
1096                                                bool ByCopy) {
1097   Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
1098                              ByCopy, /*Invalid*/ false));
1099   CXXThisCaptureIndex = Captures.size();
1100 }
1101 
1102 } // namespace sema
1103 
1104 } // namespace clang
1105 
1106 #endif // LLVM_CLANG_SEMA_SCOPEINFO_H