1212795Sdim//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
2212795Sdim//
3212795Sdim//                     The LLVM Compiler Infrastructure
4212795Sdim//
5212795Sdim// This file is distributed under the University of Illinois Open Source
6212795Sdim// License. See LICENSE.TXT for details.
7212795Sdim//
8212795Sdim//===----------------------------------------------------------------------===//
9212795Sdim//
10243830Sdim// This file defines FunctionScopeInfo and its subclasses, which contain
11243830Sdim// information about a single function, block, lambda, or method body.
12212795Sdim//
13212795Sdim//===----------------------------------------------------------------------===//
14212795Sdim
15212795Sdim#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
16212795Sdim#define LLVM_CLANG_SEMA_SCOPE_INFO_H
17212795Sdim
18212795Sdim#include "clang/AST/Type.h"
19251662Sdim#include "clang/Basic/CapturedStmt.h"
20219077Sdim#include "clang/Basic/PartialDiagnostic.h"
21212795Sdim#include "llvm/ADT/DenseMap.h"
22212795Sdim#include "llvm/ADT/SmallVector.h"
23212795Sdim
24212795Sdimnamespace clang {
25212795Sdim
26243830Sdimclass Decl;
27212795Sdimclass BlockDecl;
28251662Sdimclass CapturedDecl;
29234353Sdimclass CXXMethodDecl;
30243830Sdimclass ObjCPropertyDecl;
31212795Sdimclass IdentifierInfo;
32251662Sdimclass ImplicitParamDecl;
33218893Sdimclass LabelDecl;
34212795Sdimclass ReturnStmt;
35212795Sdimclass Scope;
36212795Sdimclass SwitchStmt;
37234353Sdimclass VarDecl;
38243830Sdimclass DeclRefExpr;
39243830Sdimclass ObjCIvarRefExpr;
40243830Sdimclass ObjCPropertyRefExpr;
41243830Sdimclass ObjCMessageExpr;
42212795Sdim
43212795Sdimnamespace sema {
44212795Sdim
45234353Sdim/// \brief Contains information about the compound statement currently being
46234353Sdim/// parsed.
47234353Sdimclass CompoundScopeInfo {
48234353Sdimpublic:
49234353Sdim  CompoundScopeInfo()
50234353Sdim    : HasEmptyLoopBodies(false) { }
51234353Sdim
52234353Sdim  /// \brief Whether this compound stamement contains `for' or `while' loops
53234353Sdim  /// with empty bodies.
54234353Sdim  bool HasEmptyLoopBodies;
55234353Sdim
56234353Sdim  void setHasEmptyLoopBodies() {
57234353Sdim    HasEmptyLoopBodies = true;
58234353Sdim  }
59234353Sdim};
60234353Sdim
61219077Sdimclass PossiblyUnreachableDiag {
62219077Sdimpublic:
63219077Sdim  PartialDiagnostic PD;
64219077Sdim  SourceLocation Loc;
65219077Sdim  const Stmt *stmt;
66219077Sdim
67219077Sdim  PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
68219077Sdim                          const Stmt *stmt)
69219077Sdim    : PD(PD), Loc(Loc), stmt(stmt) {}
70219077Sdim};
71219077Sdim
72212795Sdim/// \brief Retains information about a function, method, or block that is
73212795Sdim/// currently being parsed.
74212795Sdimclass FunctionScopeInfo {
75234353Sdimprotected:
76234353Sdim  enum ScopeKind {
77234353Sdim    SK_Function,
78234353Sdim    SK_Block,
79251662Sdim    SK_Lambda,
80251662Sdim    SK_CapturedRegion
81234353Sdim  };
82234353Sdim
83212795Sdimpublic:
84234353Sdim  /// \brief What kind of scope we are describing.
85234353Sdim  ///
86234353Sdim  ScopeKind Kind;
87212795Sdim
88239462Sdim  /// \brief Whether this function contains a VLA, \@try, try, C++
89212795Sdim  /// initializer, or anything else that can't be jumped past.
90212795Sdim  bool HasBranchProtectedScope;
91212795Sdim
92212795Sdim  /// \brief Whether this function contains any switches or direct gotos.
93212795Sdim  bool HasBranchIntoScope;
94212795Sdim
95212795Sdim  /// \brief Whether this function contains any indirect gotos.
96212795Sdim  bool HasIndirectGoto;
97212795Sdim
98249423Sdim  /// \brief Whether a statement was dropped because it was invalid.
99249423Sdim  bool HasDroppedStmt;
100249423Sdim
101243830Sdim  /// A flag that is set when parsing a method that must call super's
102243830Sdim  /// implementation, such as \c -dealloc, \c -finalize, or any method marked
103243830Sdim  /// with \c __attribute__((objc_requires_super)).
104243830Sdim  bool ObjCShouldCallSuper;
105239462Sdim
106218893Sdim  /// \brief Used to determine if errors occurred in this function or block.
107218893Sdim  DiagnosticErrorTrap ErrorTrap;
108212795Sdim
109212795Sdim  /// SwitchStack - This is the current set of active switch statements in the
110212795Sdim  /// block.
111226633Sdim  SmallVector<SwitchStmt*, 8> SwitchStack;
112212795Sdim
113212795Sdim  /// \brief The list of return statements that occur within the function or
114212795Sdim  /// block, if there is any chance of applying the named return value
115239462Sdim  /// optimization, or if we need to infer a return type.
116226633Sdim  SmallVector<ReturnStmt*, 4> Returns;
117234353Sdim
118234353Sdim  /// \brief The stack of currently active compound stamement scopes in the
119234353Sdim  /// function.
120234353Sdim  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
121234353Sdim
122219077Sdim  /// \brief A list of PartialDiagnostics created but delayed within the
123219077Sdim  /// current function scope.  These diagnostics are vetted for reachability
124219077Sdim  /// prior to being emitted.
125226633Sdim  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
126212795Sdim
127243830Sdimpublic:
128243830Sdim  /// Represents a simple identification of a weak object.
129243830Sdim  ///
130243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
131243830Sdim  ///
132243830Sdim  /// This is used to determine if two weak accesses refer to the same object.
133243830Sdim  /// Here are some examples of how various accesses are "profiled":
134243830Sdim  ///
135243830Sdim  /// Access Expression |     "Base" Decl     |          "Property" Decl
136243830Sdim  /// :---------------: | :-----------------: | :------------------------------:
137243830Sdim  /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
138243830Sdim  /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
139243830Sdim  /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
140243830Sdim  /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
141243830Sdim  /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
142243830Sdim  /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
143243830Sdim  /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
144243830Sdim  /// weakVar           | 0 (known)           | weakVar (VarDecl)
145243830Sdim  /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
146243830Sdim  ///
147243830Sdim  /// Objects are identified with only two Decls to make it reasonably fast to
148243830Sdim  /// compare them.
149243830Sdim  class WeakObjectProfileTy {
150243830Sdim    /// The base object decl, as described in the class documentation.
151243830Sdim    ///
152243830Sdim    /// The extra flag is "true" if the Base and Property are enough to uniquely
153243830Sdim    /// identify the object in memory.
154243830Sdim    ///
155243830Sdim    /// \sa isExactProfile()
156243830Sdim    typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
157243830Sdim    BaseInfoTy Base;
158243830Sdim
159243830Sdim    /// The "property" decl, as described in the class documentation.
160243830Sdim    ///
161243830Sdim    /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
162243830Sdim    /// case of "implicit" properties (regular methods accessed via dot syntax).
163243830Sdim    const NamedDecl *Property;
164243830Sdim
165243830Sdim    /// Used to find the proper base profile for a given base expression.
166243830Sdim    static BaseInfoTy getBaseInfo(const Expr *BaseE);
167243830Sdim
168243830Sdim    // For use in DenseMap.
169243830Sdim    friend class DenseMapInfo;
170243830Sdim    inline WeakObjectProfileTy();
171243830Sdim    static inline WeakObjectProfileTy getSentinel();
172243830Sdim
173243830Sdim  public:
174243830Sdim    WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
175243830Sdim    WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
176243830Sdim    WeakObjectProfileTy(const DeclRefExpr *RE);
177243830Sdim    WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
178243830Sdim
179243830Sdim    const NamedDecl *getBase() const { return Base.getPointer(); }
180243830Sdim    const NamedDecl *getProperty() const { return Property; }
181243830Sdim
182243830Sdim    /// Returns true if the object base specifies a known object in memory,
183243830Sdim    /// rather than, say, an instance variable or property of another object.
184243830Sdim    ///
185243830Sdim    /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
186243830Sdim    /// considered an exact profile if \c foo is a local variable, even if
187243830Sdim    /// another variable \c foo2 refers to the same object as \c foo.
188243830Sdim    ///
189243830Sdim    /// For increased precision, accesses with base variables that are
190243830Sdim    /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
191243830Sdim    /// be exact, though this is not true for arbitrary variables
192243830Sdim    /// (foo.prop1.prop2).
193243830Sdim    bool isExactProfile() const {
194243830Sdim      return Base.getInt();
195243830Sdim    }
196243830Sdim
197243830Sdim    bool operator==(const WeakObjectProfileTy &Other) const {
198243830Sdim      return Base == Other.Base && Property == Other.Property;
199243830Sdim    }
200243830Sdim
201243830Sdim    // For use in DenseMap.
202243830Sdim    // We can't specialize the usual llvm::DenseMapInfo at the end of the file
203243830Sdim    // because by that point the DenseMap in FunctionScopeInfo has already been
204243830Sdim    // instantiated.
205243830Sdim    class DenseMapInfo {
206243830Sdim    public:
207243830Sdim      static inline WeakObjectProfileTy getEmptyKey() {
208243830Sdim        return WeakObjectProfileTy();
209243830Sdim      }
210243830Sdim      static inline WeakObjectProfileTy getTombstoneKey() {
211243830Sdim        return WeakObjectProfileTy::getSentinel();
212243830Sdim      }
213243830Sdim
214243830Sdim      static unsigned getHashValue(const WeakObjectProfileTy &Val) {
215243830Sdim        typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
216243830Sdim        return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
217243830Sdim                                                           Val.Property));
218243830Sdim      }
219243830Sdim
220243830Sdim      static bool isEqual(const WeakObjectProfileTy &LHS,
221243830Sdim                          const WeakObjectProfileTy &RHS) {
222243830Sdim        return LHS == RHS;
223243830Sdim      }
224243830Sdim    };
225243830Sdim  };
226243830Sdim
227243830Sdim  /// Represents a single use of a weak object.
228243830Sdim  ///
229243830Sdim  /// Stores both the expression and whether the access is potentially unsafe
230243830Sdim  /// (i.e. it could potentially be warned about).
231243830Sdim  ///
232243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
233243830Sdim  class WeakUseTy {
234243830Sdim    llvm::PointerIntPair<const Expr *, 1, bool> Rep;
235243830Sdim  public:
236243830Sdim    WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
237243830Sdim
238243830Sdim    const Expr *getUseExpr() const { return Rep.getPointer(); }
239243830Sdim    bool isUnsafe() const { return Rep.getInt(); }
240243830Sdim    void markSafe() { Rep.setInt(false); }
241243830Sdim
242243830Sdim    bool operator==(const WeakUseTy &Other) const {
243243830Sdim      return Rep == Other.Rep;
244243830Sdim    }
245243830Sdim  };
246243830Sdim
247243830Sdim  /// Used to collect uses of a particular weak object in a function body.
248243830Sdim  ///
249243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
250243830Sdim  typedef SmallVector<WeakUseTy, 4> WeakUseVector;
251243830Sdim
252243830Sdim  /// Used to collect all uses of weak objects in a function body.
253243830Sdim  ///
254243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
255243830Sdim  typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
256243830Sdim                              WeakObjectProfileTy::DenseMapInfo>
257243830Sdim          WeakObjectUseMap;
258243830Sdim
259243830Sdimprivate:
260243830Sdim  /// Used to collect all uses of weak objects in this function body.
261243830Sdim  ///
262243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
263243830Sdim  WeakObjectUseMap WeakObjectUses;
264243830Sdim
265243830Sdimpublic:
266243830Sdim  /// Record that a weak object was accessed.
267243830Sdim  ///
268243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
269243830Sdim  template <typename ExprT>
270243830Sdim  inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
271243830Sdim
272243830Sdim  void recordUseOfWeak(const ObjCMessageExpr *Msg,
273243830Sdim                       const ObjCPropertyDecl *Prop);
274243830Sdim
275243830Sdim  /// Record that a given expression is a "safe" access of a weak object (e.g.
276243830Sdim  /// assigning it to a strong variable.)
277243830Sdim  ///
278243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
279243830Sdim  void markSafeWeakUse(const Expr *E);
280243830Sdim
281243830Sdim  const WeakObjectUseMap &getWeakObjectUses() const {
282243830Sdim    return WeakObjectUses;
283243830Sdim  }
284243830Sdim
285212795Sdim  void setHasBranchIntoScope() {
286212795Sdim    HasBranchIntoScope = true;
287212795Sdim  }
288212795Sdim
289212795Sdim  void setHasBranchProtectedScope() {
290212795Sdim    HasBranchProtectedScope = true;
291212795Sdim  }
292212795Sdim
293212795Sdim  void setHasIndirectGoto() {
294212795Sdim    HasIndirectGoto = true;
295212795Sdim  }
296212795Sdim
297249423Sdim  void setHasDroppedStmt() {
298249423Sdim    HasDroppedStmt = true;
299249423Sdim  }
300249423Sdim
301212795Sdim  bool NeedsScopeChecking() const {
302249423Sdim    return !HasDroppedStmt &&
303249423Sdim        (HasIndirectGoto ||
304249423Sdim          (HasBranchProtectedScope && HasBranchIntoScope));
305212795Sdim  }
306212795Sdim
307226633Sdim  FunctionScopeInfo(DiagnosticsEngine &Diag)
308234353Sdim    : Kind(SK_Function),
309212795Sdim      HasBranchProtectedScope(false),
310212795Sdim      HasBranchIntoScope(false),
311212795Sdim      HasIndirectGoto(false),
312249423Sdim      HasDroppedStmt(false),
313243830Sdim      ObjCShouldCallSuper(false),
314218893Sdim      ErrorTrap(Diag) { }
315212795Sdim
316212795Sdim  virtual ~FunctionScopeInfo();
317212795Sdim
318212795Sdim  /// \brief Clear out the information in this function scope, making it
319212795Sdim  /// suitable for reuse.
320218893Sdim  void Clear();
321212795Sdim};
322212795Sdim
323234353Sdimclass CapturingScopeInfo : public FunctionScopeInfo {
324234353Sdimpublic:
325234353Sdim  enum ImplicitCaptureStyle {
326251662Sdim    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
327251662Sdim    ImpCap_CapturedRegion
328234353Sdim  };
329234353Sdim
330234353Sdim  ImplicitCaptureStyle ImpCaptureStyle;
331234353Sdim
332234353Sdim  class Capture {
333234353Sdim    // There are two categories of capture: capturing 'this', and capturing
334234353Sdim    // local variables.  There are three ways to capture a local variable:
335234353Sdim    // capture by copy in the C++11 sense, capture by reference
336234353Sdim    // in the C++11 sense, and __block capture.  Lambdas explicitly specify
337234353Sdim    // capture by copy or capture by reference.  For blocks, __block capture
338234353Sdim    // applies to variables with that annotation, variables of reference type
339234353Sdim    // are captured by reference, and other variables are captured by copy.
340234353Sdim    enum CaptureKind {
341234353Sdim      Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
342234353Sdim    };
343234353Sdim
344234353Sdim    // The variable being captured (if we are not capturing 'this'),
345234353Sdim    // and misc bits descibing the capture.
346234353Sdim    llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
347234353Sdim
348234353Sdim    // Expression to initialize a field of the given type, and whether this
349234353Sdim    // is a nested capture; the expression is only required if we are
350234353Sdim    // capturing ByVal and the variable's type has a non-trivial
351234353Sdim    // copy constructor.
352234353Sdim    llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
353234353Sdim
354234353Sdim    /// \brief The source location at which the first capture occurred..
355234353Sdim    SourceLocation Loc;
356234353Sdim
357234353Sdim    /// \brief The location of the ellipsis that expands a parameter pack.
358234353Sdim    SourceLocation EllipsisLoc;
359234353Sdim
360234353Sdim    /// \brief The type as it was captured, which is in effect the type of the
361234353Sdim    /// non-static data member that would hold the capture.
362234353Sdim    QualType CaptureType;
363234353Sdim
364234353Sdim  public:
365234353Sdim    Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
366234353Sdim            SourceLocation Loc, SourceLocation EllipsisLoc,
367234353Sdim            QualType CaptureType, Expr *Cpy)
368234353Sdim      : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
369234353Sdim        CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
370234353Sdim        CaptureType(CaptureType){}
371234353Sdim
372234353Sdim    enum IsThisCapture { ThisCapture };
373234353Sdim    Capture(IsThisCapture, bool isNested, SourceLocation Loc,
374234353Sdim            QualType CaptureType, Expr *Cpy)
375234353Sdim      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
376234353Sdim        EllipsisLoc(), CaptureType(CaptureType) { }
377234353Sdim
378234353Sdim    bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
379234353Sdim    bool isVariableCapture() const { return !isThisCapture(); }
380234353Sdim    bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
381234353Sdim    bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
382234353Sdim    bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
383234353Sdim    bool isNested() { return CopyExprAndNested.getInt(); }
384234353Sdim
385234353Sdim    VarDecl *getVariable() const {
386234353Sdim      return VarAndKind.getPointer();
387234353Sdim    }
388234353Sdim
389234353Sdim    /// \brief Retrieve the location at which this variable was captured.
390234353Sdim    SourceLocation getLocation() const { return Loc; }
391234353Sdim
392234353Sdim    /// \brief Retrieve the source location of the ellipsis, whose presence
393234353Sdim    /// indicates that the capture is a pack expansion.
394234353Sdim    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
395234353Sdim
396234353Sdim    /// \brief Retrieve the capture type for this capture, which is effectively
397234353Sdim    /// the type of the non-static data member in the lambda/block structure
398234353Sdim    /// that would store this capture.
399234353Sdim    QualType getCaptureType() const { return CaptureType; }
400234353Sdim
401234353Sdim    Expr *getCopyExpr() const {
402234353Sdim      return CopyExprAndNested.getPointer();
403234353Sdim    }
404234353Sdim  };
405234353Sdim
406234353Sdim  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
407234353Sdim    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
408234353Sdim      HasImplicitReturnType(false)
409234353Sdim     {}
410234353Sdim
411234353Sdim  /// CaptureMap - A map of captured variables to (index+1) into Captures.
412234353Sdim  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
413234353Sdim
414234353Sdim  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
415234353Sdim  /// zero if 'this' is not captured.
416234353Sdim  unsigned CXXThisCaptureIndex;
417234353Sdim
418234353Sdim  /// Captures - The captures.
419234353Sdim  SmallVector<Capture, 4> Captures;
420234353Sdim
421234353Sdim  /// \brief - Whether the target type of return statements in this context
422234353Sdim  /// is deduced (e.g. a lambda or block with omitted return type).
423234353Sdim  bool HasImplicitReturnType;
424234353Sdim
425234353Sdim  /// ReturnType - The target type of return statements in this context,
426234353Sdim  /// or null if unknown.
427234353Sdim  QualType ReturnType;
428234353Sdim
429234353Sdim  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
430234353Sdim                  SourceLocation Loc, SourceLocation EllipsisLoc,
431234353Sdim                  QualType CaptureType, Expr *Cpy) {
432234353Sdim    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
433234353Sdim                               EllipsisLoc, CaptureType, Cpy));
434234353Sdim    CaptureMap[Var] = Captures.size();
435234353Sdim  }
436234353Sdim
437234353Sdim  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
438243830Sdim                      Expr *Cpy);
439234353Sdim
440234353Sdim  /// \brief Determine whether the C++ 'this' is captured.
441234353Sdim  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
442234353Sdim
443234353Sdim  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
444234353Sdim  Capture &getCXXThisCapture() {
445234353Sdim    assert(isCXXThisCaptured() && "this has not been captured");
446234353Sdim    return Captures[CXXThisCaptureIndex - 1];
447234353Sdim  }
448234353Sdim
449234353Sdim  /// \brief Determine whether the given variable has been captured.
450234353Sdim  bool isCaptured(VarDecl *Var) const {
451234353Sdim    return CaptureMap.count(Var);
452234353Sdim  }
453234353Sdim
454234353Sdim  /// \brief Retrieve the capture of the given variable, if it has been
455234353Sdim  /// captured already.
456234353Sdim  Capture &getCapture(VarDecl *Var) {
457234353Sdim    assert(isCaptured(Var) && "Variable has not been captured");
458234353Sdim    return Captures[CaptureMap[Var] - 1];
459234353Sdim  }
460234353Sdim
461234353Sdim  const Capture &getCapture(VarDecl *Var) const {
462234353Sdim    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
463234353Sdim      = CaptureMap.find(Var);
464234353Sdim    assert(Known != CaptureMap.end() && "Variable has not been captured");
465234353Sdim    return Captures[Known->second - 1];
466234353Sdim  }
467234353Sdim
468234353Sdim  static bool classof(const FunctionScopeInfo *FSI) {
469251662Sdim    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
470251662Sdim                                 || FSI->Kind == SK_CapturedRegion;
471234353Sdim  }
472234353Sdim};
473234353Sdim
474212795Sdim/// \brief Retains information about a block that is currently being parsed.
475234353Sdimclass BlockScopeInfo : public CapturingScopeInfo {
476212795Sdimpublic:
477212795Sdim  BlockDecl *TheDecl;
478212795Sdim
479212795Sdim  /// TheScope - This is the scope for the block itself, which contains
480212795Sdim  /// arguments etc.
481212795Sdim  Scope *TheScope;
482212795Sdim
483212795Sdim  /// BlockType - The function type of the block, if one was given.
484212795Sdim  /// Its return type may be BuiltinType::Dependent.
485212795Sdim  QualType FunctionType;
486212795Sdim
487226633Sdim  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
488234353Sdim    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
489234353Sdim      TheScope(BlockScope)
490212795Sdim  {
491234353Sdim    Kind = SK_Block;
492212795Sdim  }
493212795Sdim
494212795Sdim  virtual ~BlockScopeInfo();
495212795Sdim
496234353Sdim  static bool classof(const FunctionScopeInfo *FSI) {
497234353Sdim    return FSI->Kind == SK_Block;
498234353Sdim  }
499212795Sdim};
500212795Sdim
501251662Sdim/// \brief Retains information about a captured region.
502251662Sdimclass CapturedRegionScopeInfo: public CapturingScopeInfo {
503251662Sdimpublic:
504251662Sdim  /// \brief The CapturedDecl for this statement.
505251662Sdim  CapturedDecl *TheCapturedDecl;
506251662Sdim  /// \brief The captured record type.
507251662Sdim  RecordDecl *TheRecordDecl;
508251662Sdim  /// \brief This is the enclosing scope of the captured region.
509251662Sdim  Scope *TheScope;
510251662Sdim  /// \brief The implicit parameter for the captured variables.
511251662Sdim  ImplicitParamDecl *ContextParam;
512251662Sdim  /// \brief The kind of captured region.
513251662Sdim  CapturedRegionKind CapRegionKind;
514251662Sdim
515251662Sdim  CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
516251662Sdim                          RecordDecl *RD, ImplicitParamDecl *Context,
517251662Sdim                          CapturedRegionKind K)
518251662Sdim    : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
519251662Sdim      TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
520251662Sdim      ContextParam(Context), CapRegionKind(K)
521251662Sdim  {
522251662Sdim    Kind = SK_CapturedRegion;
523251662Sdim  }
524251662Sdim
525251662Sdim  virtual ~CapturedRegionScopeInfo();
526251662Sdim
527251662Sdim  /// \brief A descriptive name for the kind of captured region this is.
528251662Sdim  StringRef getRegionName() const {
529251662Sdim    switch (CapRegionKind) {
530251662Sdim    case CR_Default:
531251662Sdim      return "default captured statement";
532251662Sdim    }
533251662Sdim    llvm_unreachable("Invalid captured region kind!");
534251662Sdim  }
535251662Sdim
536251662Sdim  static bool classof(const FunctionScopeInfo *FSI) {
537251662Sdim    return FSI->Kind == SK_CapturedRegion;
538251662Sdim  }
539251662Sdim};
540251662Sdim
541234353Sdimclass LambdaScopeInfo : public CapturingScopeInfo {
542234353Sdimpublic:
543234353Sdim  /// \brief The class that describes the lambda.
544234353Sdim  CXXRecordDecl *Lambda;
545234353Sdim
546234353Sdim  /// \brief The class that describes the lambda.
547234353Sdim  CXXMethodDecl *CallOperator;
548234353Sdim
549234353Sdim  /// \brief Source range covering the lambda introducer [...].
550234353Sdim  SourceRange IntroducerRange;
551234353Sdim
552234353Sdim  /// \brief The number of captures in the \c Captures list that are
553234353Sdim  /// explicit captures.
554234353Sdim  unsigned NumExplicitCaptures;
555234353Sdim
556234353Sdim  /// \brief Whether this is a mutable lambda.
557234353Sdim  bool Mutable;
558234353Sdim
559234353Sdim  /// \brief Whether the (empty) parameter list is explicit.
560234353Sdim  bool ExplicitParams;
561234353Sdim
562234353Sdim  /// \brief Whether any of the capture expressions requires cleanups.
563234353Sdim  bool ExprNeedsCleanups;
564234353Sdim
565239462Sdim  /// \brief Whether the lambda contains an unexpanded parameter pack.
566239462Sdim  bool ContainsUnexpandedParameterPack;
567239462Sdim
568234353Sdim  /// \brief Variables used to index into by-copy array captures.
569249423Sdim  SmallVector<VarDecl *, 4> ArrayIndexVars;
570234353Sdim
571234353Sdim  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
572234353Sdim  /// its list of array index variables.
573249423Sdim  SmallVector<unsigned, 4> ArrayIndexStarts;
574234353Sdim
575234353Sdim  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
576234353Sdim                  CXXMethodDecl *CallOperator)
577234353Sdim    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
578234353Sdim      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
579239462Sdim      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
580234353Sdim  {
581234353Sdim    Kind = SK_Lambda;
582234353Sdim  }
583234353Sdim
584234353Sdim  virtual ~LambdaScopeInfo();
585234353Sdim
586234353Sdim  /// \brief Note when
587234353Sdim  void finishedExplicitCaptures() {
588234353Sdim    NumExplicitCaptures = Captures.size();
589234353Sdim  }
590243830Sdim
591243830Sdim  static bool classof(const FunctionScopeInfo *FSI) {
592234353Sdim    return FSI->Kind == SK_Lambda;
593234353Sdim  }
594234353Sdim};
595234353Sdim
596243830Sdim
597243830SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
598243830Sdim  : Base(0, false), Property(0) {}
599243830Sdim
600243830SdimFunctionScopeInfo::WeakObjectProfileTy
601243830SdimFunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
602243830Sdim  FunctionScopeInfo::WeakObjectProfileTy Result;
603243830Sdim  Result.Base.setInt(true);
604243830Sdim  return Result;
605212795Sdim}
606243830Sdim
607243830Sdimtemplate <typename ExprT>
608243830Sdimvoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
609243830Sdim  assert(E);
610243830Sdim  WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
611243830Sdim  Uses.push_back(WeakUseTy(E, IsRead));
612212795Sdim}
613212795Sdim
614243830Sdiminline void
615243830SdimCapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
616243830Sdim                                   QualType CaptureType, Expr *Cpy) {
617243830Sdim  Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
618243830Sdim                             Cpy));
619243830Sdim  CXXThisCaptureIndex = Captures.size();
620243830Sdim
621243830Sdim  if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
622243830Sdim    LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
623243830Sdim}
624243830Sdim
625243830Sdim} // end namespace sema
626243830Sdim} // end namespace clang
627243830Sdim
628212795Sdim#endif
629