ScopeInfo.h revision c0e44454bd78b8b4f3d70f08cf1edd5466b0c798
1781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
2781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//
3781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//                     The LLVM Compiler Infrastructure
4781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//
5781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// This file is distributed under the University of Illinois Open Source
6781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// License. See LICENSE.TXT for details.
7781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//
8781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//===----------------------------------------------------------------------===//
9781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//
10a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// This file defines FunctionScopeInfo and its subclasses, which contain
11a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// information about a single function, block, lambda, or method body.
12781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//
13781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//===----------------------------------------------------------------------===//
14781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
15781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
16781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#define LLVM_CLANG_SEMA_SCOPE_INFO_H
17781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
18781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "clang/AST/Type.h"
19351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Basic/PartialDiagnostic.h"
20781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/DenseMap.h"
21781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/SmallVector.h"
22781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
23781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace clang {
24781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
2558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass Decl;
26781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass BlockDecl;
27f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass CXXMethodDecl;
287fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Roseclass ObjCPropertyDecl;
29781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass IdentifierInfo;
30ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnerclass LabelDecl;
31781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass ReturnStmt;
32781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass Scope;
33781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass SwitchStmt;
34f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass VarDecl;
357a2704800943fbb69207e125d28186278712af36Jordan Roseclass DeclRefExpr;
367a2704800943fbb69207e125d28186278712af36Jordan Roseclass ObjCIvarRefExpr;
3758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass ObjCPropertyRefExpr;
387fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Roseclass ObjCMessageExpr;
39781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
40781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace sema {
41781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
42625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// \brief Contains information about the compound statement currently being
43625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// parsed.
44625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkoclass CompoundScopeInfo {
45625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkopublic:
46625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  CompoundScopeInfo()
47625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    : HasEmptyLoopBodies(false) { }
48625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
49625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief Whether this compound stamement contains `for' or `while' loops
50625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// with empty bodies.
51625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  bool HasEmptyLoopBodies;
52625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
53625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  void setHasEmptyLoopBodies() {
54625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    HasEmptyLoopBodies = true;
55625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
56625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko};
57625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
58351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekclass PossiblyUnreachableDiag {
59351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekpublic:
60351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  PartialDiagnostic PD;
61351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  SourceLocation Loc;
62351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  const Stmt *stmt;
63351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
64351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
65351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek                          const Stmt *stmt)
66351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    : PD(PD), Loc(Loc), stmt(stmt) {}
67351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek};
68351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
69781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a function, method, or block that is
70781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// currently being parsed.
71781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass FunctionScopeInfo {
72ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanprotected:
73ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  enum ScopeKind {
74ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Function,
75ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Block,
76ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Lambda
77ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  };
78ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
79781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
80ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief What kind of scope we are describing.
81ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  ///
82ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  ScopeKind Kind;
83781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
84809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// \brief Whether this function contains a VLA, \@try, try, C++
85781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// initializer, or anything else that can't be jumped past.
86781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasBranchProtectedScope;
87781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
88781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Whether this function contains any switches or direct gotos.
89781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasBranchIntoScope;
90781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
91781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Whether this function contains any indirect gotos.
92781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasIndirectGoto;
93781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
94535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose  /// A flag that is set when parsing a method that must call super's
95535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose  /// implementation, such as \c -dealloc, \c -finalize, or any method marked
96535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose  /// with \c __attribute__((objc_requires_super)).
97535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose  bool ObjCShouldCallSuper;
9895aac15936e8362aeb4813f95bc255dee6473592Eli Friedman
998fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  /// \brief Used to determine if errors occurred in this function or block.
1008fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  DiagnosticErrorTrap ErrorTrap;
101781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
102781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// SwitchStack - This is the current set of active switch statements in the
103781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block.
104686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<SwitchStmt*, 8> SwitchStack;
105781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
106781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief The list of return statements that occur within the function or
107781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block, if there is any chance of applying the named return value
1087dd900ed308506f9cf1cb72c70db1652f94cab37Jordan Rose  /// optimization, or if we need to infer a return type.
109686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<ReturnStmt*, 4> Returns;
110625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
111625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief The stack of currently active compound stamement scopes in the
112625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// function.
113625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
114625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
115351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// \brief A list of PartialDiagnostics created but delayed within the
116351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// current function scope.  These diagnostics are vetted for reachability
117351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// prior to being emitted.
118686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
119781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
12058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic:
12158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Represents a simple identification of a weak object.
12258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
12358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
12458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
12558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// This is used to determine if two weak accesses refer to the same object.
12658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Here are some examples of how various accesses are "profiled":
12758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
12858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Access Expression |     "Base" Decl     |          "Property" Decl
12958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// :---------------: | :-----------------: | :------------------------------:
13058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
13158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
13258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
13358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
13458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
13558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
13658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
1377a2704800943fbb69207e125d28186278712af36Jordan Rose  /// weakVar           | 0 (known)           | weakVar (VarDecl)
1387a2704800943fbb69207e125d28186278712af36Jordan Rose  /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
13958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
14058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Objects are identified with only two Decls to make it reasonably fast to
14158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// compare them.
14258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  class WeakObjectProfileTy {
14358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The base object decl, as described in the class documentation.
14458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
14558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The extra flag is "true" if the Base and Property are enough to uniquely
14658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// identify the object in memory.
14758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
14858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// \sa isExactProfile()
14958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
15058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    BaseInfoTy Base;
15158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
15258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The "property" decl, as described in the class documentation.
15358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
15458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
15558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// case of "implicit" properties (regular methods accessed via dot syntax).
15658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const NamedDecl *Property;
15758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
1587a2704800943fbb69207e125d28186278712af36Jordan Rose    /// Used to find the proper base profile for a given base expression.
1597a2704800943fbb69207e125d28186278712af36Jordan Rose    static BaseInfoTy getBaseInfo(const Expr *BaseE);
1607a2704800943fbb69207e125d28186278712af36Jordan Rose
16158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // For use in DenseMap.
162b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    friend class DenseMapInfo;
16358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    inline WeakObjectProfileTy();
16458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    static inline WeakObjectProfileTy getSentinel();
16558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
16658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  public:
16758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
1687fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
1697a2704800943fbb69207e125d28186278712af36Jordan Rose    WeakObjectProfileTy(const DeclRefExpr *RE);
1707a2704800943fbb69207e125d28186278712af36Jordan Rose    WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
17158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
172c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    const NamedDecl *getBase() const { return Base.getPointer(); }
17358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const NamedDecl *getProperty() const { return Property; }
17458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
17558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Returns true if the object base specifies a known object in memory,
17658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// rather than, say, an instance variable or property of another object.
17758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
17858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
17958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// considered an exact profile if \c foo is a local variable, even if
18058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// another variable \c foo2 refers to the same object as \c foo.
18158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
18258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// For increased precision, accesses with base variables that are
18358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
18458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// be exact, though this is not true for arbitrary variables
18558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// (foo.prop1.prop2).
18658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool isExactProfile() const {
18758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Base.getInt();
18858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
18958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
19058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool operator==(const WeakObjectProfileTy &Other) const {
19158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Base == Other.Base && Property == Other.Property;
19258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
193b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose
194b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    // For use in DenseMap.
195b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    // We can't specialize the usual llvm::DenseMapInfo at the end of the file
196b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    // because by that point the DenseMap in FunctionScopeInfo has already been
197b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    // instantiated.
198b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    class DenseMapInfo {
199b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    public:
200b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      static inline WeakObjectProfileTy getEmptyKey() {
201b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        return WeakObjectProfileTy();
202b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      }
203b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      static inline WeakObjectProfileTy getTombstoneKey() {
204b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        return WeakObjectProfileTy::getSentinel();
205b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      }
206b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose
207b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      static unsigned getHashValue(const WeakObjectProfileTy &Val) {
208b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
209b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
210b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose                                                           Val.Property));
211b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      }
212b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose
213b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      static bool isEqual(const WeakObjectProfileTy &LHS,
214b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose                          const WeakObjectProfileTy &RHS) {
215b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        return LHS == RHS;
216b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      }
217b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    };
21858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  };
21958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
22058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Represents a single use of a weak object.
22158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
22258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Stores both the expression and whether the access is potentially unsafe
22358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// (i.e. it could potentially be warned about).
22458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
22558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
22658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  class WeakUseTy {
22758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    llvm::PointerIntPair<const Expr *, 1, bool> Rep;
22858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  public:
22958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
23058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
23158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const Expr *getUseExpr() const { return Rep.getPointer(); }
23258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool isUnsafe() const { return Rep.getInt(); }
23358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    void markSafe() { Rep.setInt(false); }
23458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
23558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool operator==(const WeakUseTy &Other) const {
23658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Rep == Other.Rep;
23758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
23858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  };
23958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
24058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect uses of a particular weak object in a function body.
24158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
24258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
24358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef SmallVector<WeakUseTy, 4> WeakUseVector;
24458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
24558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect all uses of weak objects in a function body.
24658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
24758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
248b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose  typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
249b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose                              WeakObjectProfileTy::DenseMapInfo>
25058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose          WeakObjectUseMap;
25158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
25258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseprivate:
25358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect all uses of weak objects in this function body.
25458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
25558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
25658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  WeakObjectUseMap WeakObjectUses;
25758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
25858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic:
2597a2704800943fbb69207e125d28186278712af36Jordan Rose  /// Record that a weak object was accessed.
26058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
26158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
2627a2704800943fbb69207e125d28186278712af36Jordan Rose  template <typename ExprT>
2637a2704800943fbb69207e125d28186278712af36Jordan Rose  inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
26458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
2657fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose  void recordUseOfWeak(const ObjCMessageExpr *Msg,
2667fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose                       const ObjCPropertyDecl *Prop);
2677fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose
26858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Record that a given expression is a "safe" access of a weak object (e.g.
26958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// assigning it to a strong variable.)
27058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
27158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
27258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  void markSafeWeakUse(const Expr *E);
27358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
27458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  const WeakObjectUseMap &getWeakObjectUses() const {
27558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    return WeakObjectUses;
27658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  }
27758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
278781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchIntoScope() {
279781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchIntoScope = true;
280781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
281781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
282781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchProtectedScope() {
283781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchProtectedScope = true;
284781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
285781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
286781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasIndirectGoto() {
287781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasIndirectGoto = true;
288781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
289781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
290781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool NeedsScopeChecking() const {
291781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    return HasIndirectGoto ||
292781472fe99a120098c631b0cbe33c89f8cef5e70John McCall          (HasBranchProtectedScope && HasBranchIntoScope);
293781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
294781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
295d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  FunctionScopeInfo(DiagnosticsEngine &Diag)
296ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    : Kind(SK_Function),
297781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchProtectedScope(false),
298781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchIntoScope(false),
299781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasIndirectGoto(false),
300535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose      ObjCShouldCallSuper(false),
3018fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis      ErrorTrap(Diag) { }
302781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
303781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~FunctionScopeInfo();
304781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
305781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Clear out the information in this function scope, making it
306781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// suitable for reuse.
3078fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  void Clear();
308781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
309781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
310b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo {
311b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic:
312b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  enum ImplicitCaptureStyle {
313b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
314b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
315b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
316b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  ImplicitCaptureStyle ImpCaptureStyle;
317b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
318b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  class Capture {
319b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // There are two categories of capture: capturing 'this', and capturing
320b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // local variables.  There are three ways to capture a local variable:
321b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // capture by copy in the C++11 sense, capture by reference
322b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // in the C++11 sense, and __block capture.  Lambdas explicitly specify
323b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // capture by copy or capture by reference.  For blocks, __block capture
324b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // applies to variables with that annotation, variables of reference type
325b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // are captured by reference, and other variables are captured by copy.
326b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum CaptureKind {
327b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman      Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
328b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    };
329b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
330b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // The variable being captured (if we are not capturing 'this'),
331b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // and misc bits descibing the capture.
332b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
333b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
334b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // Expression to initialize a field of the given type, and whether this
335b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // is a nested capture; the expression is only required if we are
336b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // capturing ByVal and the variable's type has a non-trivial
337b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // copy constructor.
338b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
339b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
34093962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief The source location at which the first capture occurred..
34193962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation Loc;
34293962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
343a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief The location of the ellipsis that expands a parameter pack.
344a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation EllipsisLoc;
345a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
346999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief The type as it was captured, which is in effect the type of the
347999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// non-static data member that would hold the capture.
348999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType CaptureType;
349999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
350b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  public:
351b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
352999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            SourceLocation Loc, SourceLocation EllipsisLoc,
353999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
354b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman      : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
355999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
356999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        CaptureType(CaptureType){}
357b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
358b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum IsThisCapture { ThisCapture };
359999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    Capture(IsThisCapture, bool isNested, SourceLocation Loc,
360999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
361a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
362999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        EllipsisLoc(), CaptureType(CaptureType) { }
363b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
364b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
365b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isVariableCapture() const { return !isThisCapture(); }
366b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
367b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
368b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
369b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isNested() { return CopyExprAndNested.getInt(); }
370b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
371b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    VarDecl *getVariable() const {
372b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      return VarAndKind.getPointer();
373b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
37493962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
37593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief Retrieve the location at which this variable was captured.
37693962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation getLocation() const { return Loc; }
37793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
378a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief Retrieve the source location of the ellipsis, whose presence
379a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// indicates that the capture is a pack expansion.
380a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
381a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
382999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief Retrieve the capture type for this capture, which is effectively
383999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// the type of the non-static data member in the lambda/block structure
384999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// that would store this capture.
385999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType getCaptureType() const { return CaptureType; }
386999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
387b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    Expr *getCopyExpr() const {
388b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      return CopyExprAndNested.getPointer();
389b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
390b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
391b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
392b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
39384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
39484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman      HasImplicitReturnType(false)
395b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman     {}
396b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
397b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CaptureMap - A map of captured variables to (index+1) into Captures.
398b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
399b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
400b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
401b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// zero if 'this' is not captured.
402b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  unsigned CXXThisCaptureIndex;
403b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
404b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// Captures - The captures.
405b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  SmallVector<Capture, 4> Captures;
406b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
40784b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// \brief - Whether the target type of return statements in this context
40884b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// is deduced (e.g. a lambda or block with omitted return type).
40984b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  bool HasImplicitReturnType;
41084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
41184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// ReturnType - The target type of return statements in this context,
41284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// or null if unknown.
41384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  QualType ReturnType;
41484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
415999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
416999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  SourceLocation Loc, SourceLocation EllipsisLoc,
417999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  QualType CaptureType, Expr *Cpy) {
418a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
419999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                               EllipsisLoc, CaptureType, Cpy));
420b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    CaptureMap[Var] = Captures.size();
421b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
422b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
423999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
424c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor                      Expr *Cpy);
425b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
426a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the C++ 'this' is captured.
427a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
428a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
429a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
430a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCXXThisCapture() {
431a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCXXThisCaptured() && "this has not been captured");
432a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CXXThisCaptureIndex - 1];
433a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
434a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
435a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the given variable has been captured.
436a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCaptured(VarDecl *Var) const {
437b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman    return CaptureMap.count(Var);
438a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
439a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
440a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of the given variable, if it has been
441a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// captured already.
442a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCapture(VarDecl *Var) {
443a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCaptured(Var) && "Variable has not been captured");
444a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CaptureMap[Var] - 1];
445a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
446a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
447a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  const Capture &getCapture(VarDecl *Var) const {
448a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
449a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor      = CaptureMap.find(Var);
450a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(Known != CaptureMap.end() && "Variable has not been captured");
451a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[Known->second - 1];
452a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
453a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
454b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
455b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
456b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
457b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman};
458b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
459781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed.
460b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo {
461781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
462781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  BlockDecl *TheDecl;
463781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
464781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// TheScope - This is the scope for the block itself, which contains
465781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// arguments etc.
466781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  Scope *TheScope;
467781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
468781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// BlockType - The function type of the block, if one was given.
469781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// Its return type may be BuiltinType::Dependent.
470781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  QualType FunctionType;
471781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
472d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
473b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
474b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      TheScope(BlockScope)
475781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  {
476ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Block;
477781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
478781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
479781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~BlockScopeInfo();
480781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
481ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
482ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Block;
483ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
484781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
485781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
486b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo {
487ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic:
488ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The class that describes the lambda.
489ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  CXXRecordDecl *Lambda;
49001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
49176e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  /// \brief The class that describes the lambda.
49276e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  CXXMethodDecl *CallOperator;
49376e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor
49401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Source range covering the lambda introducer [...].
49501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  SourceRange IntroducerRange;
49601d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
497ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The number of captures in the \c Captures list that are
498ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// explicit captures.
499ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  unsigned NumExplicitCaptures;
50072899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman
501503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether this is a mutable lambda.
502d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman  bool Mutable;
50301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
50401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Whether the (empty) parameter list is explicit.
50501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  bool ExplicitParams;
506d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman
507503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether any of the capture expressions requires cleanups.
508503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  bool ExprNeedsCleanups;
509503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
510612409ece080e814f79e06772c690d603f45fbd6Richard Smith  /// \brief Whether the lambda contains an unexpanded parameter pack.
511612409ece080e814f79e06772c690d603f45fbd6Richard Smith  bool ContainsUnexpandedParameterPack;
512612409ece080e814f79e06772c690d603f45fbd6Richard Smith
5139daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Variables used to index into by-copy array captures.
5149daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
5159daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
5169daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
5179daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// its list of array index variables.
5189daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
5199daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
52076e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
52176e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor                  CXXMethodDecl *CallOperator)
522b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
523503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
524612409ece080e814f79e06772c690d603f45fbd6Richard Smith      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
525ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  {
526ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Lambda;
527ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
528b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
529ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  virtual ~LambdaScopeInfo();
530b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
531a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Note when
532a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  void finishedExplicitCaptures() {
533a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    NumExplicitCaptures = Captures.size();
534a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
535c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
536c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  static bool classof(const FunctionScopeInfo *FSI) {
537ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Lambda;
538ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
539ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman};
540ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
541c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
54258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
54358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  : Base(0, false), Property(0) {}
54458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
54558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy
54658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
54758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  FunctionScopeInfo::WeakObjectProfileTy Result;
54858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  Result.Base.setInt(true);
54958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  return Result;
55058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose}
55158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
5527a2704800943fbb69207e125d28186278712af36Jordan Rosetemplate <typename ExprT>
5537a2704800943fbb69207e125d28186278712af36Jordan Rosevoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
5547a2704800943fbb69207e125d28186278712af36Jordan Rose  assert(E);
5557a2704800943fbb69207e125d28186278712af36Jordan Rose  WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
5567a2704800943fbb69207e125d28186278712af36Jordan Rose  Uses.push_back(WeakUseTy(E, IsRead));
557781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}
5587a2704800943fbb69207e125d28186278712af36Jordan Rose
559c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregorinline void
560c3f1742bdd1ae0091d51168e111cd63861587b13Douglas GregorCapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
561c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor                                   QualType CaptureType, Expr *Cpy) {
562c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
563c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor                             Cpy));
564c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  CXXThisCaptureIndex = Captures.size();
565c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
566c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
567c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor    LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
568c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor}
569c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
5707a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace sema
5717a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace clang
572781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
573781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif
574