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"
21263508Sdim#include "clang/Sema/Ownership.h"
22212795Sdim#include "llvm/ADT/DenseMap.h"
23263508Sdim#include "llvm/ADT/SmallSet.h"
24212795Sdim#include "llvm/ADT/SmallVector.h"
25263508Sdim#include <algorithm>
26212795Sdim
27212795Sdimnamespace clang {
28212795Sdim
29243830Sdimclass Decl;
30212795Sdimclass BlockDecl;
31251662Sdimclass CapturedDecl;
32234353Sdimclass CXXMethodDecl;
33263508Sdimclass FieldDecl;
34243830Sdimclass ObjCPropertyDecl;
35212795Sdimclass IdentifierInfo;
36251662Sdimclass ImplicitParamDecl;
37218893Sdimclass LabelDecl;
38212795Sdimclass ReturnStmt;
39212795Sdimclass Scope;
40212795Sdimclass SwitchStmt;
41263508Sdimclass TemplateTypeParmDecl;
42263508Sdimclass TemplateParameterList;
43234353Sdimclass VarDecl;
44243830Sdimclass DeclRefExpr;
45263508Sdimclass MemberExpr;
46243830Sdimclass ObjCIvarRefExpr;
47243830Sdimclass ObjCPropertyRefExpr;
48243830Sdimclass ObjCMessageExpr;
49212795Sdim
50212795Sdimnamespace sema {
51212795Sdim
52234353Sdim/// \brief Contains information about the compound statement currently being
53234353Sdim/// parsed.
54234353Sdimclass CompoundScopeInfo {
55234353Sdimpublic:
56234353Sdim  CompoundScopeInfo()
57234353Sdim    : HasEmptyLoopBodies(false) { }
58234353Sdim
59234353Sdim  /// \brief Whether this compound stamement contains `for' or `while' loops
60234353Sdim  /// with empty bodies.
61234353Sdim  bool HasEmptyLoopBodies;
62234353Sdim
63234353Sdim  void setHasEmptyLoopBodies() {
64234353Sdim    HasEmptyLoopBodies = true;
65234353Sdim  }
66234353Sdim};
67234353Sdim
68219077Sdimclass PossiblyUnreachableDiag {
69219077Sdimpublic:
70219077Sdim  PartialDiagnostic PD;
71219077Sdim  SourceLocation Loc;
72219077Sdim  const Stmt *stmt;
73219077Sdim
74219077Sdim  PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
75219077Sdim                          const Stmt *stmt)
76219077Sdim    : PD(PD), Loc(Loc), stmt(stmt) {}
77219077Sdim};
78219077Sdim
79212795Sdim/// \brief Retains information about a function, method, or block that is
80212795Sdim/// currently being parsed.
81212795Sdimclass FunctionScopeInfo {
82234353Sdimprotected:
83234353Sdim  enum ScopeKind {
84234353Sdim    SK_Function,
85234353Sdim    SK_Block,
86251662Sdim    SK_Lambda,
87251662Sdim    SK_CapturedRegion
88234353Sdim  };
89234353Sdim
90212795Sdimpublic:
91234353Sdim  /// \brief What kind of scope we are describing.
92234353Sdim  ///
93234353Sdim  ScopeKind Kind;
94212795Sdim
95239462Sdim  /// \brief Whether this function contains a VLA, \@try, try, C++
96212795Sdim  /// initializer, or anything else that can't be jumped past.
97212795Sdim  bool HasBranchProtectedScope;
98212795Sdim
99212795Sdim  /// \brief Whether this function contains any switches or direct gotos.
100212795Sdim  bool HasBranchIntoScope;
101212795Sdim
102212795Sdim  /// \brief Whether this function contains any indirect gotos.
103212795Sdim  bool HasIndirectGoto;
104212795Sdim
105249423Sdim  /// \brief Whether a statement was dropped because it was invalid.
106249423Sdim  bool HasDroppedStmt;
107249423Sdim
108243830Sdim  /// A flag that is set when parsing a method that must call super's
109243830Sdim  /// implementation, such as \c -dealloc, \c -finalize, or any method marked
110243830Sdim  /// with \c __attribute__((objc_requires_super)).
111243830Sdim  bool ObjCShouldCallSuper;
112239462Sdim
113218893Sdim  /// \brief Used to determine if errors occurred in this function or block.
114218893Sdim  DiagnosticErrorTrap ErrorTrap;
115212795Sdim
116212795Sdim  /// SwitchStack - This is the current set of active switch statements in the
117212795Sdim  /// block.
118226633Sdim  SmallVector<SwitchStmt*, 8> SwitchStack;
119212795Sdim
120212795Sdim  /// \brief The list of return statements that occur within the function or
121212795Sdim  /// block, if there is any chance of applying the named return value
122239462Sdim  /// optimization, or if we need to infer a return type.
123226633Sdim  SmallVector<ReturnStmt*, 4> Returns;
124234353Sdim
125234353Sdim  /// \brief The stack of currently active compound stamement scopes in the
126234353Sdim  /// function.
127234353Sdim  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
128234353Sdim
129219077Sdim  /// \brief A list of PartialDiagnostics created but delayed within the
130219077Sdim  /// current function scope.  These diagnostics are vetted for reachability
131219077Sdim  /// prior to being emitted.
132226633Sdim  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
133212795Sdim
134243830Sdimpublic:
135243830Sdim  /// Represents a simple identification of a weak object.
136243830Sdim  ///
137243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
138243830Sdim  ///
139243830Sdim  /// This is used to determine if two weak accesses refer to the same object.
140243830Sdim  /// Here are some examples of how various accesses are "profiled":
141243830Sdim  ///
142243830Sdim  /// Access Expression |     "Base" Decl     |          "Property" Decl
143243830Sdim  /// :---------------: | :-----------------: | :------------------------------:
144243830Sdim  /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
145243830Sdim  /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
146243830Sdim  /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
147243830Sdim  /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
148243830Sdim  /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
149243830Sdim  /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
150243830Sdim  /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
151243830Sdim  /// weakVar           | 0 (known)           | weakVar (VarDecl)
152243830Sdim  /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
153243830Sdim  ///
154243830Sdim  /// Objects are identified with only two Decls to make it reasonably fast to
155243830Sdim  /// compare them.
156243830Sdim  class WeakObjectProfileTy {
157243830Sdim    /// The base object decl, as described in the class documentation.
158243830Sdim    ///
159243830Sdim    /// The extra flag is "true" if the Base and Property are enough to uniquely
160243830Sdim    /// identify the object in memory.
161243830Sdim    ///
162243830Sdim    /// \sa isExactProfile()
163243830Sdim    typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
164243830Sdim    BaseInfoTy Base;
165243830Sdim
166243830Sdim    /// The "property" decl, as described in the class documentation.
167243830Sdim    ///
168243830Sdim    /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
169243830Sdim    /// case of "implicit" properties (regular methods accessed via dot syntax).
170243830Sdim    const NamedDecl *Property;
171243830Sdim
172243830Sdim    /// Used to find the proper base profile for a given base expression.
173243830Sdim    static BaseInfoTy getBaseInfo(const Expr *BaseE);
174243830Sdim
175243830Sdim    // For use in DenseMap.
176243830Sdim    friend class DenseMapInfo;
177243830Sdim    inline WeakObjectProfileTy();
178243830Sdim    static inline WeakObjectProfileTy getSentinel();
179243830Sdim
180243830Sdim  public:
181243830Sdim    WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
182243830Sdim    WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
183243830Sdim    WeakObjectProfileTy(const DeclRefExpr *RE);
184243830Sdim    WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
185243830Sdim
186243830Sdim    const NamedDecl *getBase() const { return Base.getPointer(); }
187243830Sdim    const NamedDecl *getProperty() const { return Property; }
188243830Sdim
189243830Sdim    /// Returns true if the object base specifies a known object in memory,
190243830Sdim    /// rather than, say, an instance variable or property of another object.
191243830Sdim    ///
192243830Sdim    /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
193243830Sdim    /// considered an exact profile if \c foo is a local variable, even if
194243830Sdim    /// another variable \c foo2 refers to the same object as \c foo.
195243830Sdim    ///
196243830Sdim    /// For increased precision, accesses with base variables that are
197243830Sdim    /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
198243830Sdim    /// be exact, though this is not true for arbitrary variables
199243830Sdim    /// (foo.prop1.prop2).
200243830Sdim    bool isExactProfile() const {
201243830Sdim      return Base.getInt();
202243830Sdim    }
203243830Sdim
204243830Sdim    bool operator==(const WeakObjectProfileTy &Other) const {
205243830Sdim      return Base == Other.Base && Property == Other.Property;
206243830Sdim    }
207243830Sdim
208243830Sdim    // For use in DenseMap.
209243830Sdim    // We can't specialize the usual llvm::DenseMapInfo at the end of the file
210243830Sdim    // because by that point the DenseMap in FunctionScopeInfo has already been
211243830Sdim    // instantiated.
212243830Sdim    class DenseMapInfo {
213243830Sdim    public:
214243830Sdim      static inline WeakObjectProfileTy getEmptyKey() {
215243830Sdim        return WeakObjectProfileTy();
216243830Sdim      }
217243830Sdim      static inline WeakObjectProfileTy getTombstoneKey() {
218243830Sdim        return WeakObjectProfileTy::getSentinel();
219243830Sdim      }
220243830Sdim
221243830Sdim      static unsigned getHashValue(const WeakObjectProfileTy &Val) {
222243830Sdim        typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
223243830Sdim        return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
224243830Sdim                                                           Val.Property));
225243830Sdim      }
226243830Sdim
227243830Sdim      static bool isEqual(const WeakObjectProfileTy &LHS,
228243830Sdim                          const WeakObjectProfileTy &RHS) {
229243830Sdim        return LHS == RHS;
230243830Sdim      }
231243830Sdim    };
232243830Sdim  };
233243830Sdim
234243830Sdim  /// Represents a single use of a weak object.
235243830Sdim  ///
236243830Sdim  /// Stores both the expression and whether the access is potentially unsafe
237243830Sdim  /// (i.e. it could potentially be warned about).
238243830Sdim  ///
239243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
240243830Sdim  class WeakUseTy {
241243830Sdim    llvm::PointerIntPair<const Expr *, 1, bool> Rep;
242243830Sdim  public:
243243830Sdim    WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
244243830Sdim
245243830Sdim    const Expr *getUseExpr() const { return Rep.getPointer(); }
246243830Sdim    bool isUnsafe() const { return Rep.getInt(); }
247243830Sdim    void markSafe() { Rep.setInt(false); }
248243830Sdim
249243830Sdim    bool operator==(const WeakUseTy &Other) const {
250243830Sdim      return Rep == Other.Rep;
251243830Sdim    }
252243830Sdim  };
253243830Sdim
254243830Sdim  /// Used to collect uses of a particular weak object in a function body.
255243830Sdim  ///
256243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
257243830Sdim  typedef SmallVector<WeakUseTy, 4> WeakUseVector;
258243830Sdim
259243830Sdim  /// Used to collect all uses of weak objects in a function body.
260243830Sdim  ///
261243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
262243830Sdim  typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
263243830Sdim                              WeakObjectProfileTy::DenseMapInfo>
264243830Sdim          WeakObjectUseMap;
265243830Sdim
266243830Sdimprivate:
267243830Sdim  /// Used to collect all uses of weak objects in this function body.
268243830Sdim  ///
269243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
270243830Sdim  WeakObjectUseMap WeakObjectUses;
271243830Sdim
272243830Sdimpublic:
273243830Sdim  /// Record that a weak object was accessed.
274243830Sdim  ///
275243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
276243830Sdim  template <typename ExprT>
277243830Sdim  inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
278243830Sdim
279243830Sdim  void recordUseOfWeak(const ObjCMessageExpr *Msg,
280243830Sdim                       const ObjCPropertyDecl *Prop);
281243830Sdim
282243830Sdim  /// Record that a given expression is a "safe" access of a weak object (e.g.
283243830Sdim  /// assigning it to a strong variable.)
284243830Sdim  ///
285243830Sdim  /// Part of the implementation of -Wrepeated-use-of-weak.
286243830Sdim  void markSafeWeakUse(const Expr *E);
287243830Sdim
288243830Sdim  const WeakObjectUseMap &getWeakObjectUses() const {
289243830Sdim    return WeakObjectUses;
290243830Sdim  }
291243830Sdim
292212795Sdim  void setHasBranchIntoScope() {
293212795Sdim    HasBranchIntoScope = true;
294212795Sdim  }
295212795Sdim
296212795Sdim  void setHasBranchProtectedScope() {
297212795Sdim    HasBranchProtectedScope = true;
298212795Sdim  }
299212795Sdim
300212795Sdim  void setHasIndirectGoto() {
301212795Sdim    HasIndirectGoto = true;
302212795Sdim  }
303212795Sdim
304249423Sdim  void setHasDroppedStmt() {
305249423Sdim    HasDroppedStmt = true;
306249423Sdim  }
307249423Sdim
308212795Sdim  bool NeedsScopeChecking() const {
309249423Sdim    return !HasDroppedStmt &&
310249423Sdim        (HasIndirectGoto ||
311249423Sdim          (HasBranchProtectedScope && HasBranchIntoScope));
312212795Sdim  }
313212795Sdim
314226633Sdim  FunctionScopeInfo(DiagnosticsEngine &Diag)
315234353Sdim    : Kind(SK_Function),
316212795Sdim      HasBranchProtectedScope(false),
317212795Sdim      HasBranchIntoScope(false),
318212795Sdim      HasIndirectGoto(false),
319249423Sdim      HasDroppedStmt(false),
320243830Sdim      ObjCShouldCallSuper(false),
321218893Sdim      ErrorTrap(Diag) { }
322212795Sdim
323212795Sdim  virtual ~FunctionScopeInfo();
324212795Sdim
325212795Sdim  /// \brief Clear out the information in this function scope, making it
326212795Sdim  /// suitable for reuse.
327218893Sdim  void Clear();
328212795Sdim};
329212795Sdim
330234353Sdimclass CapturingScopeInfo : public FunctionScopeInfo {
331234353Sdimpublic:
332234353Sdim  enum ImplicitCaptureStyle {
333251662Sdim    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
334251662Sdim    ImpCap_CapturedRegion
335234353Sdim  };
336234353Sdim
337234353Sdim  ImplicitCaptureStyle ImpCaptureStyle;
338234353Sdim
339234353Sdim  class Capture {
340263508Sdim    // There are three categories of capture: capturing 'this', capturing
341263508Sdim    // local variables, and C++1y initialized captures (which can have an
342263508Sdim    // arbitrary initializer, and don't really capture in the traditional
343263508Sdim    // sense at all).
344263508Sdim    //
345263508Sdim    // There are three ways to capture a local variable:
346263508Sdim    //  - capture by copy in the C++11 sense,
347263508Sdim    //  - capture by reference in the C++11 sense, and
348263508Sdim    //  - __block capture.
349263508Sdim    // Lambdas explicitly specify capture by copy or capture by reference.
350263508Sdim    // For blocks, __block capture applies to variables with that annotation,
351263508Sdim    // variables of reference type are captured by reference, and other
352263508Sdim    // variables are captured by copy.
353234353Sdim    enum CaptureKind {
354263508Sdim      Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This
355234353Sdim    };
356234353Sdim
357263508Sdim    /// The variable being captured (if we are not capturing 'this') and whether
358263508Sdim    /// this is a nested capture.
359263508Sdim    llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested;
360234353Sdim
361263508Sdim    /// Expression to initialize a field of the given type, and the kind of
362263508Sdim    /// capture (if this is a capture and not an init-capture). The expression
363263508Sdim    /// is only required if we are capturing ByVal and the variable's type has
364263508Sdim    /// a non-trivial copy constructor.
365263508Sdim    llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind;
366234353Sdim
367263508Sdim    /// \brief The source location at which the first capture occurred.
368234353Sdim    SourceLocation Loc;
369263508Sdim
370234353Sdim    /// \brief The location of the ellipsis that expands a parameter pack.
371234353Sdim    SourceLocation EllipsisLoc;
372263508Sdim
373234353Sdim    /// \brief The type as it was captured, which is in effect the type of the
374234353Sdim    /// non-static data member that would hold the capture.
375234353Sdim    QualType CaptureType;
376263508Sdim
377234353Sdim  public:
378263508Sdim    Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
379263508Sdim            SourceLocation Loc, SourceLocation EllipsisLoc,
380234353Sdim            QualType CaptureType, Expr *Cpy)
381263508Sdim        : VarAndNested(Var, IsNested),
382263508Sdim          InitExprAndCaptureKind(Cpy, Block ? Cap_Block :
383263508Sdim                                      ByRef ? Cap_ByRef : Cap_ByCopy),
384263508Sdim          Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
385234353Sdim
386234353Sdim    enum IsThisCapture { ThisCapture };
387263508Sdim    Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
388234353Sdim            QualType CaptureType, Expr *Cpy)
389263508Sdim        : VarAndNested(0, IsNested),
390263508Sdim          InitExprAndCaptureKind(Cpy, Cap_This),
391263508Sdim          Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
392234353Sdim
393263508Sdim    bool isThisCapture() const {
394263508Sdim      return InitExprAndCaptureKind.getInt() == Cap_This;
395263508Sdim    }
396263508Sdim    bool isVariableCapture() const {
397263508Sdim      return InitExprAndCaptureKind.getInt() != Cap_This;
398263508Sdim    }
399263508Sdim    bool isCopyCapture() const {
400263508Sdim      return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
401263508Sdim    }
402263508Sdim    bool isReferenceCapture() const {
403263508Sdim      return InitExprAndCaptureKind.getInt() == Cap_ByRef;
404263508Sdim    }
405263508Sdim    bool isBlockCapture() const {
406263508Sdim      return InitExprAndCaptureKind.getInt() == Cap_Block;
407263508Sdim    }
408263508Sdim    bool isNested() { return VarAndNested.getInt(); }
409234353Sdim
410234353Sdim    VarDecl *getVariable() const {
411263508Sdim      return VarAndNested.getPointer();
412234353Sdim    }
413234353Sdim
414234353Sdim    /// \brief Retrieve the location at which this variable was captured.
415234353Sdim    SourceLocation getLocation() const { return Loc; }
416234353Sdim
417234353Sdim    /// \brief Retrieve the source location of the ellipsis, whose presence
418234353Sdim    /// indicates that the capture is a pack expansion.
419234353Sdim    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
420234353Sdim
421234353Sdim    /// \brief Retrieve the capture type for this capture, which is effectively
422234353Sdim    /// the type of the non-static data member in the lambda/block structure
423234353Sdim    /// that would store this capture.
424234353Sdim    QualType getCaptureType() const { return CaptureType; }
425234353Sdim
426263508Sdim    Expr *getInitExpr() const {
427263508Sdim      return InitExprAndCaptureKind.getPointer();
428234353Sdim    }
429234353Sdim  };
430234353Sdim
431234353Sdim  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
432234353Sdim    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
433234353Sdim      HasImplicitReturnType(false)
434234353Sdim     {}
435234353Sdim
436234353Sdim  /// CaptureMap - A map of captured variables to (index+1) into Captures.
437234353Sdim  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
438234353Sdim
439234353Sdim  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
440234353Sdim  /// zero if 'this' is not captured.
441234353Sdim  unsigned CXXThisCaptureIndex;
442234353Sdim
443234353Sdim  /// Captures - The captures.
444234353Sdim  SmallVector<Capture, 4> Captures;
445234353Sdim
446234353Sdim  /// \brief - Whether the target type of return statements in this context
447234353Sdim  /// is deduced (e.g. a lambda or block with omitted return type).
448234353Sdim  bool HasImplicitReturnType;
449234353Sdim
450234353Sdim  /// ReturnType - The target type of return statements in this context,
451234353Sdim  /// or null if unknown.
452234353Sdim  QualType ReturnType;
453234353Sdim
454234353Sdim  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
455234353Sdim                  SourceLocation Loc, SourceLocation EllipsisLoc,
456234353Sdim                  QualType CaptureType, Expr *Cpy) {
457234353Sdim    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
458234353Sdim                               EllipsisLoc, CaptureType, Cpy));
459234353Sdim    CaptureMap[Var] = Captures.size();
460234353Sdim  }
461234353Sdim
462234353Sdim  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
463243830Sdim                      Expr *Cpy);
464234353Sdim
465234353Sdim  /// \brief Determine whether the C++ 'this' is captured.
466234353Sdim  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
467234353Sdim
468234353Sdim  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
469234353Sdim  Capture &getCXXThisCapture() {
470234353Sdim    assert(isCXXThisCaptured() && "this has not been captured");
471234353Sdim    return Captures[CXXThisCaptureIndex - 1];
472234353Sdim  }
473234353Sdim
474234353Sdim  /// \brief Determine whether the given variable has been captured.
475234353Sdim  bool isCaptured(VarDecl *Var) const {
476234353Sdim    return CaptureMap.count(Var);
477234353Sdim  }
478234353Sdim
479234353Sdim  /// \brief Retrieve the capture of the given variable, if it has been
480234353Sdim  /// captured already.
481234353Sdim  Capture &getCapture(VarDecl *Var) {
482234353Sdim    assert(isCaptured(Var) && "Variable has not been captured");
483234353Sdim    return Captures[CaptureMap[Var] - 1];
484234353Sdim  }
485234353Sdim
486234353Sdim  const Capture &getCapture(VarDecl *Var) const {
487234353Sdim    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
488234353Sdim      = CaptureMap.find(Var);
489234353Sdim    assert(Known != CaptureMap.end() && "Variable has not been captured");
490234353Sdim    return Captures[Known->second - 1];
491234353Sdim  }
492234353Sdim
493234353Sdim  static bool classof(const FunctionScopeInfo *FSI) {
494251662Sdim    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
495251662Sdim                                 || FSI->Kind == SK_CapturedRegion;
496234353Sdim  }
497234353Sdim};
498234353Sdim
499212795Sdim/// \brief Retains information about a block that is currently being parsed.
500234353Sdimclass BlockScopeInfo : public CapturingScopeInfo {
501212795Sdimpublic:
502212795Sdim  BlockDecl *TheDecl;
503212795Sdim
504212795Sdim  /// TheScope - This is the scope for the block itself, which contains
505212795Sdim  /// arguments etc.
506212795Sdim  Scope *TheScope;
507212795Sdim
508212795Sdim  /// BlockType - The function type of the block, if one was given.
509212795Sdim  /// Its return type may be BuiltinType::Dependent.
510212795Sdim  QualType FunctionType;
511212795Sdim
512226633Sdim  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
513234353Sdim    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
514234353Sdim      TheScope(BlockScope)
515212795Sdim  {
516234353Sdim    Kind = SK_Block;
517212795Sdim  }
518212795Sdim
519212795Sdim  virtual ~BlockScopeInfo();
520212795Sdim
521234353Sdim  static bool classof(const FunctionScopeInfo *FSI) {
522234353Sdim    return FSI->Kind == SK_Block;
523234353Sdim  }
524212795Sdim};
525212795Sdim
526251662Sdim/// \brief Retains information about a captured region.
527251662Sdimclass CapturedRegionScopeInfo: public CapturingScopeInfo {
528251662Sdimpublic:
529251662Sdim  /// \brief The CapturedDecl for this statement.
530251662Sdim  CapturedDecl *TheCapturedDecl;
531251662Sdim  /// \brief The captured record type.
532251662Sdim  RecordDecl *TheRecordDecl;
533251662Sdim  /// \brief This is the enclosing scope of the captured region.
534251662Sdim  Scope *TheScope;
535251662Sdim  /// \brief The implicit parameter for the captured variables.
536251662Sdim  ImplicitParamDecl *ContextParam;
537251662Sdim  /// \brief The kind of captured region.
538251662Sdim  CapturedRegionKind CapRegionKind;
539251662Sdim
540251662Sdim  CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
541251662Sdim                          RecordDecl *RD, ImplicitParamDecl *Context,
542251662Sdim                          CapturedRegionKind K)
543251662Sdim    : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
544251662Sdim      TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
545251662Sdim      ContextParam(Context), CapRegionKind(K)
546251662Sdim  {
547251662Sdim    Kind = SK_CapturedRegion;
548251662Sdim  }
549251662Sdim
550251662Sdim  virtual ~CapturedRegionScopeInfo();
551251662Sdim
552251662Sdim  /// \brief A descriptive name for the kind of captured region this is.
553251662Sdim  StringRef getRegionName() const {
554251662Sdim    switch (CapRegionKind) {
555251662Sdim    case CR_Default:
556251662Sdim      return "default captured statement";
557263508Sdim    case CR_OpenMP:
558263508Sdim      return "OpenMP region";
559251662Sdim    }
560251662Sdim    llvm_unreachable("Invalid captured region kind!");
561251662Sdim  }
562251662Sdim
563251662Sdim  static bool classof(const FunctionScopeInfo *FSI) {
564251662Sdim    return FSI->Kind == SK_CapturedRegion;
565251662Sdim  }
566251662Sdim};
567251662Sdim
568234353Sdimclass LambdaScopeInfo : public CapturingScopeInfo {
569234353Sdimpublic:
570234353Sdim  /// \brief The class that describes the lambda.
571234353Sdim  CXXRecordDecl *Lambda;
572234353Sdim
573263508Sdim  /// \brief The lambda's compiler-generated \c operator().
574234353Sdim  CXXMethodDecl *CallOperator;
575234353Sdim
576234353Sdim  /// \brief Source range covering the lambda introducer [...].
577234353Sdim  SourceRange IntroducerRange;
578234353Sdim
579263508Sdim  /// \brief Source location of the '&' or '=' specifying the default capture
580263508Sdim  /// type, if any.
581263508Sdim  SourceLocation CaptureDefaultLoc;
582263508Sdim
583263508Sdim  /// \brief The number of captures in the \c Captures list that are
584234353Sdim  /// explicit captures.
585234353Sdim  unsigned NumExplicitCaptures;
586234353Sdim
587234353Sdim  /// \brief Whether this is a mutable lambda.
588234353Sdim  bool Mutable;
589263508Sdim
590234353Sdim  /// \brief Whether the (empty) parameter list is explicit.
591234353Sdim  bool ExplicitParams;
592234353Sdim
593234353Sdim  /// \brief Whether any of the capture expressions requires cleanups.
594234353Sdim  bool ExprNeedsCleanups;
595234353Sdim
596239462Sdim  /// \brief Whether the lambda contains an unexpanded parameter pack.
597239462Sdim  bool ContainsUnexpandedParameterPack;
598239462Sdim
599234353Sdim  /// \brief Variables used to index into by-copy array captures.
600249423Sdim  SmallVector<VarDecl *, 4> ArrayIndexVars;
601234353Sdim
602234353Sdim  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
603234353Sdim  /// its list of array index variables.
604249423Sdim  SmallVector<unsigned, 4> ArrayIndexStarts;
605234353Sdim
606263508Sdim  /// \brief If this is a generic lambda, use this as the depth of
607263508Sdim  /// each 'auto' parameter, during initial AST construction.
608263508Sdim  unsigned AutoTemplateParameterDepth;
609263508Sdim
610263508Sdim  /// \brief Store the list of the auto parameters for a generic lambda.
611263508Sdim  /// If this is a generic lambda, store the list of the auto
612263508Sdim  /// parameters converted into TemplateTypeParmDecls into a vector
613263508Sdim  /// that can be used to construct the generic lambda's template
614263508Sdim  /// parameter list, during initial AST construction.
615263508Sdim  SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams;
616263508Sdim
617263508Sdim  /// If this is a generic lambda, and the template parameter
618263508Sdim  /// list has been created (from the AutoTemplateParams) then
619263508Sdim  /// store a reference to it (cache it to avoid reconstructing it).
620263508Sdim  TemplateParameterList *GLTemplateParameterList;
621263508Sdim
622263508Sdim  /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs
623263508Sdim  ///  or MemberExprs) that refer to local variables in a generic lambda
624263508Sdim  ///  or a lambda in a potentially-evaluated-if-used context.
625263508Sdim  ///
626263508Sdim  ///  Potentially capturable variables of a nested lambda that might need
627263508Sdim  ///   to be captured by the lambda are housed here.
628263508Sdim  ///  This is specifically useful for generic lambdas or
629263508Sdim  ///  lambdas within a a potentially evaluated-if-used context.
630263508Sdim  ///  If an enclosing variable is named in an expression of a lambda nested
631263508Sdim  ///  within a generic lambda, we don't always know know whether the variable
632263508Sdim  ///  will truly be odr-used (i.e. need to be captured) by that nested lambda,
633263508Sdim  ///  until its instantiation. But we still need to capture it in the
634263508Sdim  ///  enclosing lambda if all intervening lambdas can capture the variable.
635263508Sdim
636263508Sdim  llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
637263508Sdim
638263508Sdim  /// \brief Contains all variable-referring-expressions that refer
639263508Sdim  ///  to local variables that are usable as constant expressions and
640263508Sdim  ///  do not involve an odr-use (they may still need to be captured
641263508Sdim  ///  if the enclosing full-expression is instantiation dependent).
642263508Sdim  llvm::SmallSet<Expr*, 8> NonODRUsedCapturingExprs;
643263508Sdim
644263508Sdim  SourceLocation PotentialThisCaptureLocation;
645263508Sdim
646263508Sdim  LambdaScopeInfo(DiagnosticsEngine &Diag)
647263508Sdim    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(0),
648263508Sdim      CallOperator(0), NumExplicitCaptures(0), Mutable(false),
649263508Sdim      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false),
650263508Sdim      AutoTemplateParameterDepth(0), GLTemplateParameterList(0)
651234353Sdim  {
652234353Sdim    Kind = SK_Lambda;
653234353Sdim  }
654234353Sdim
655234353Sdim  virtual ~LambdaScopeInfo();
656234353Sdim
657263508Sdim  /// \brief Note when all explicit captures have been added.
658234353Sdim  void finishedExplicitCaptures() {
659234353Sdim    NumExplicitCaptures = Captures.size();
660234353Sdim  }
661243830Sdim
662243830Sdim  static bool classof(const FunctionScopeInfo *FSI) {
663263508Sdim    return FSI->Kind == SK_Lambda;
664234353Sdim  }
665263508Sdim
666263508Sdim  ///
667263508Sdim  /// \brief Add a variable that might potentially be captured by the
668263508Sdim  /// lambda and therefore the enclosing lambdas.
669263508Sdim  ///
670263508Sdim  /// This is also used by enclosing lambda's to speculatively capture
671263508Sdim  /// variables that nested lambda's - depending on their enclosing
672263508Sdim  /// specialization - might need to capture.
673263508Sdim  /// Consider:
674263508Sdim  /// void f(int, int); <-- don't capture
675263508Sdim  /// void f(const int&, double); <-- capture
676263508Sdim  /// void foo() {
677263508Sdim  ///   const int x = 10;
678263508Sdim  ///   auto L = [=](auto a) { // capture 'x'
679263508Sdim  ///      return [=](auto b) {
680263508Sdim  ///        f(x, a);  // we may or may not need to capture 'x'
681263508Sdim  ///      };
682263508Sdim  ///   };
683263508Sdim  /// }
684263508Sdim  void addPotentialCapture(Expr *VarExpr) {
685263508Sdim    assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr));
686263508Sdim    PotentiallyCapturingExprs.push_back(VarExpr);
687263508Sdim  }
688263508Sdim
689263508Sdim  void addPotentialThisCapture(SourceLocation Loc) {
690263508Sdim    PotentialThisCaptureLocation = Loc;
691263508Sdim  }
692263508Sdim  bool hasPotentialThisCapture() const {
693263508Sdim    return PotentialThisCaptureLocation.isValid();
694263508Sdim  }
695263508Sdim
696263508Sdim  /// \brief Mark a variable's reference in a lambda as non-odr using.
697263508Sdim  ///
698263508Sdim  /// For generic lambdas, if a variable is named in a potentially evaluated
699263508Sdim  /// expression, where the enclosing full expression is dependent then we
700263508Sdim  /// must capture the variable (given a default capture).
701263508Sdim  /// This is accomplished by recording all references to variables
702263508Sdim  /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of
703263508Sdim  /// PotentialCaptures. All such variables have to be captured by that lambda,
704263508Sdim  /// except for as described below.
705263508Sdim  /// If that variable is usable as a constant expression and is named in a
706263508Sdim  /// manner that does not involve its odr-use (e.g. undergoes
707263508Sdim  /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
708263508Sdim  /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
709263508Sdim  /// if we can determine that the full expression is not instantiation-
710263508Sdim  /// dependent, then we can entirely avoid its capture.
711263508Sdim  ///
712263508Sdim  ///   const int n = 0;
713263508Sdim  ///   [&] (auto x) {
714263508Sdim  ///     (void)+n + x;
715263508Sdim  ///   };
716263508Sdim  /// Interestingly, this strategy would involve a capture of n, even though
717263508Sdim  /// it's obviously not odr-used here, because the full-expression is
718263508Sdim  /// instantiation-dependent.  It could be useful to avoid capturing such
719263508Sdim  /// variables, even when they are referred to in an instantiation-dependent
720263508Sdim  /// expression, if we can unambiguously determine that they shall never be
721263508Sdim  /// odr-used.  This would involve removal of the variable-referring-expression
722263508Sdim  /// from the array of PotentialCaptures during the lvalue-to-rvalue
723263508Sdim  /// conversions.  But per the working draft N3797, (post-chicago 2013) we must
724263508Sdim  /// capture such variables.
725263508Sdim  /// Before anyone is tempted to implement a strategy for not-capturing 'n',
726263508Sdim  /// consider the insightful warning in:
727263508Sdim  ///    /cfe-commits/Week-of-Mon-20131104/092596.html
728263508Sdim  /// "The problem is that the set of captures for a lambda is part of the ABI
729263508Sdim  ///  (since lambda layout can be made visible through inline functions and the
730263508Sdim  ///  like), and there are no guarantees as to which cases we'll manage to build
731263508Sdim  ///  an lvalue-to-rvalue conversion in, when parsing a template -- some
732263508Sdim  ///  seemingly harmless change elsewhere in Sema could cause us to start or stop
733263508Sdim  ///  building such a node. So we need a rule that anyone can implement and get
734263508Sdim  ///  exactly the same result".
735263508Sdim  ///
736263508Sdim  void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
737263508Sdim    assert(isa<DeclRefExpr>(CapturingVarExpr)
738263508Sdim        || isa<MemberExpr>(CapturingVarExpr));
739263508Sdim    NonODRUsedCapturingExprs.insert(CapturingVarExpr);
740263508Sdim  }
741263508Sdim  bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) {
742263508Sdim    assert(isa<DeclRefExpr>(CapturingVarExpr)
743263508Sdim      || isa<MemberExpr>(CapturingVarExpr));
744263508Sdim    return NonODRUsedCapturingExprs.count(CapturingVarExpr);
745263508Sdim  }
746263508Sdim  void removePotentialCapture(Expr *E) {
747263508Sdim    PotentiallyCapturingExprs.erase(
748263508Sdim        std::remove(PotentiallyCapturingExprs.begin(),
749263508Sdim            PotentiallyCapturingExprs.end(), E),
750263508Sdim        PotentiallyCapturingExprs.end());
751263508Sdim  }
752263508Sdim  void clearPotentialCaptures() {
753263508Sdim    PotentiallyCapturingExprs.clear();
754263508Sdim    PotentialThisCaptureLocation = SourceLocation();
755263508Sdim  }
756263508Sdim  unsigned getNumPotentialVariableCaptures() const {
757263508Sdim    return PotentiallyCapturingExprs.size();
758263508Sdim  }
759263508Sdim
760263508Sdim  bool hasPotentialCaptures() const {
761263508Sdim    return getNumPotentialVariableCaptures() ||
762263508Sdim                                  PotentialThisCaptureLocation.isValid();
763263508Sdim  }
764263508Sdim
765263508Sdim  // When passed the index, returns the VarDecl and Expr associated
766263508Sdim  // with the index.
767263508Sdim  void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E);
768263508Sdim
769234353Sdim};
770234353Sdim
771243830Sdim
772243830SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
773243830Sdim  : Base(0, false), Property(0) {}
774243830Sdim
775243830SdimFunctionScopeInfo::WeakObjectProfileTy
776243830SdimFunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
777243830Sdim  FunctionScopeInfo::WeakObjectProfileTy Result;
778243830Sdim  Result.Base.setInt(true);
779243830Sdim  return Result;
780212795Sdim}
781243830Sdim
782243830Sdimtemplate <typename ExprT>
783243830Sdimvoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
784243830Sdim  assert(E);
785243830Sdim  WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
786243830Sdim  Uses.push_back(WeakUseTy(E, IsRead));
787212795Sdim}
788212795Sdim
789243830Sdiminline void
790243830SdimCapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
791243830Sdim                                   QualType CaptureType, Expr *Cpy) {
792243830Sdim  Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
793243830Sdim                             Cpy));
794243830Sdim  CXXThisCaptureIndex = Captures.size();
795243830Sdim
796243830Sdim  if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
797243830Sdim    LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
798243830Sdim}
799243830Sdim
800243830Sdim} // end namespace sema
801243830Sdim} // end namespace clang
802243830Sdim
803212795Sdim#endif
804