ScopeInfo.h revision a55d32d1b8f799bf58c02540983976368c42d895
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;
28781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass IdentifierInfo;
29ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnerclass LabelDecl;
30781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass ReturnStmt;
31781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass Scope;
32781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass SwitchStmt;
33f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass VarDecl;
347a2704800943fbb69207e125d28186278712af36Jordan Roseclass DeclRefExpr;
357a2704800943fbb69207e125d28186278712af36Jordan Roseclass ObjCIvarRefExpr;
3658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass ObjCPropertyRefExpr;
37781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
38781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace sema {
39781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
40625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// \brief Contains information about the compound statement currently being
41625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// parsed.
42625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkoclass CompoundScopeInfo {
43625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkopublic:
44625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  CompoundScopeInfo()
45625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    : HasEmptyLoopBodies(false) { }
46625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
47625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief Whether this compound stamement contains `for' or `while' loops
48625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// with empty bodies.
49625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  bool HasEmptyLoopBodies;
50625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
51625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  void setHasEmptyLoopBodies() {
52625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    HasEmptyLoopBodies = true;
53625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
54625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko};
55625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
56351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekclass PossiblyUnreachableDiag {
57351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekpublic:
58351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  PartialDiagnostic PD;
59351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  SourceLocation Loc;
60351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  const Stmt *stmt;
61351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
62351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
63351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek                          const Stmt *stmt)
64351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    : PD(PD), Loc(Loc), stmt(stmt) {}
65351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek};
66351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
67781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a function, method, or block that is
68781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// currently being parsed.
69781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass FunctionScopeInfo {
70ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanprotected:
71ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  enum ScopeKind {
72ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Function,
73ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Block,
74ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Lambda
75ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  };
76ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
77781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
78ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief What kind of scope we are describing.
79ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  ///
80ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  ScopeKind Kind;
81781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
82809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// \brief Whether this function contains a VLA, \@try, try, C++
83781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// initializer, or anything else that can't be jumped past.
84781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasBranchProtectedScope;
85781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
86781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Whether this function contains any switches or direct gotos.
87781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasBranchIntoScope;
88781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
89781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Whether this function contains any indirect gotos.
90781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasIndirectGoto;
91781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
9295aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  /// A flag that is set when parsing a -dealloc method and no [super dealloc]
9395aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  /// call was found yet.
9495aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  bool ObjCShouldCallSuperDealloc;
9595aac15936e8362aeb4813f95bc255dee6473592Eli Friedman
9695aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  /// A flag that is set when parsing a -finalize method and no [super finalize]
9795aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  /// call was found yet.
9895aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  bool ObjCShouldCallSuperFinalize;
9995aac15936e8362aeb4813f95bc255dee6473592Eli Friedman
1008fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  /// \brief Used to determine if errors occurred in this function or block.
1018fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  DiagnosticErrorTrap ErrorTrap;
102781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
103781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// SwitchStack - This is the current set of active switch statements in the
104781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block.
105686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<SwitchStmt*, 8> SwitchStack;
106781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
107781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief The list of return statements that occur within the function or
108781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block, if there is any chance of applying the named return value
1097dd900ed308506f9cf1cb72c70db1652f94cab37Jordan Rose  /// optimization, or if we need to infer a return type.
110686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<ReturnStmt*, 4> Returns;
111625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
112625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief The stack of currently active compound stamement scopes in the
113625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// function.
114625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
115625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
116351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// \brief A list of PartialDiagnostics created but delayed within the
117351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// current function scope.  These diagnostics are vetted for reachability
118351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// prior to being emitted.
119686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
120781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
12158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic:
12258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Represents a simple identification of a weak object.
12358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
12458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
12558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
12658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// This is used to determine if two weak accesses refer to the same object.
12758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Here are some examples of how various accesses are "profiled":
12858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
12958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Access Expression |     "Base" Decl     |          "Property" Decl
13058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// :---------------: | :-----------------: | :------------------------------:
13158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
13258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
13358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
13458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
13558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
13658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
13758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
1387a2704800943fbb69207e125d28186278712af36Jordan Rose  /// weakVar           | 0 (known)           | weakVar (VarDecl)
1397a2704800943fbb69207e125d28186278712af36Jordan Rose  /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
14058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
14158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Objects are identified with only two Decls to make it reasonably fast to
14258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// compare them.
14358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  class WeakObjectProfileTy {
14458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The base object decl, as described in the class documentation.
14558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
14658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The extra flag is "true" if the Base and Property are enough to uniquely
14758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// identify the object in memory.
14858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
14958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// \sa isExactProfile()
15058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
15158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    BaseInfoTy Base;
15258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
15358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The "property" decl, as described in the class documentation.
15458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
15558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
15658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// case of "implicit" properties (regular methods accessed via dot syntax).
15758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const NamedDecl *Property;
15858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
1597a2704800943fbb69207e125d28186278712af36Jordan Rose    /// Used to find the proper base profile for a given base expression.
1607a2704800943fbb69207e125d28186278712af36Jordan Rose    static BaseInfoTy getBaseInfo(const Expr *BaseE);
1617a2704800943fbb69207e125d28186278712af36Jordan Rose
16258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // For use in DenseMap.
16358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    friend struct llvm::DenseMapInfo<WeakObjectProfileTy>;
16458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    inline WeakObjectProfileTy();
16558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    static inline WeakObjectProfileTy getSentinel();
16658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
16758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  public:
16858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
1697a2704800943fbb69207e125d28186278712af36Jordan Rose    WeakObjectProfileTy(const DeclRefExpr *RE);
1707a2704800943fbb69207e125d28186278712af36Jordan Rose    WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
17158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
17258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const NamedDecl *getProperty() const { return Property; }
17358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
17458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Returns true if the object base specifies a known object in memory,
17558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// rather than, say, an instance variable or property of another object.
17658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
17758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
17858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// considered an exact profile if \c foo is a local variable, even if
17958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// another variable \c foo2 refers to the same object as \c foo.
18058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
18158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// For increased precision, accesses with base variables that are
18258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
18358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// be exact, though this is not true for arbitrary variables
18458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// (foo.prop1.prop2).
18558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool isExactProfile() const {
18658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Base.getInt();
18758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
18858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
18958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool operator==(const WeakObjectProfileTy &Other) const {
19058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Base == Other.Base && Property == Other.Property;
19158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
19258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  };
19358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
19458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Represents a single use of a weak object.
19558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
19658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Stores both the expression and whether the access is potentially unsafe
19758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// (i.e. it could potentially be warned about).
19858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
19958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
20058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  class WeakUseTy {
20158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    llvm::PointerIntPair<const Expr *, 1, bool> Rep;
20258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  public:
20358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
20458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
20558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const Expr *getUseExpr() const { return Rep.getPointer(); }
20658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool isUnsafe() const { return Rep.getInt(); }
20758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    void markSafe() { Rep.setInt(false); }
20858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
20958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool operator==(const WeakUseTy &Other) const {
21058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Rep == Other.Rep;
21158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
21258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  };
21358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
21458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect uses of a particular weak object in a function body.
21558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
21658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
21758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef SmallVector<WeakUseTy, 4> WeakUseVector;
21858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
21958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect all uses of weak objects in a function body.
22058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
22158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
22258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8>
22358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose          WeakObjectUseMap;
22458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
22558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseprivate:
22658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect all uses of weak objects in this function body.
22758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
22858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
22958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  WeakObjectUseMap WeakObjectUses;
23058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
23158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic:
2327a2704800943fbb69207e125d28186278712af36Jordan Rose  /// Record that a weak object was accessed.
23358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
23458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
2357a2704800943fbb69207e125d28186278712af36Jordan Rose  template <typename ExprT>
2367a2704800943fbb69207e125d28186278712af36Jordan Rose  inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
23758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
23858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Record that a given expression is a "safe" access of a weak object (e.g.
23958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// assigning it to a strong variable.)
24058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
24158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
24258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  void markSafeWeakUse(const Expr *E);
24358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
24458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  const WeakObjectUseMap &getWeakObjectUses() const {
24558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    return WeakObjectUses;
24658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  }
24758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
248781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchIntoScope() {
249781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchIntoScope = true;
250781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
251781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
252781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchProtectedScope() {
253781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchProtectedScope = true;
254781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
255781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
256781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasIndirectGoto() {
257781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasIndirectGoto = true;
258781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
259781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
260781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool NeedsScopeChecking() const {
261781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    return HasIndirectGoto ||
262781472fe99a120098c631b0cbe33c89f8cef5e70John McCall          (HasBranchProtectedScope && HasBranchIntoScope);
263781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
264781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
265d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  FunctionScopeInfo(DiagnosticsEngine &Diag)
266ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    : Kind(SK_Function),
267781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchProtectedScope(false),
268781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchIntoScope(false),
269781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasIndirectGoto(false),
27095aac15936e8362aeb4813f95bc255dee6473592Eli Friedman      ObjCShouldCallSuperDealloc(false),
27195aac15936e8362aeb4813f95bc255dee6473592Eli Friedman      ObjCShouldCallSuperFinalize(false),
2728fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis      ErrorTrap(Diag) { }
273781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
274781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~FunctionScopeInfo();
275781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
276781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Clear out the information in this function scope, making it
277781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// suitable for reuse.
2788fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  void Clear();
279781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
280781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  static bool classof(const FunctionScopeInfo *FSI) { return true; }
281781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
282781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
283b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo {
284b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic:
285b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  enum ImplicitCaptureStyle {
286b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
287b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
288b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
289b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  ImplicitCaptureStyle ImpCaptureStyle;
290b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
291b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  class Capture {
292b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // There are two categories of capture: capturing 'this', and capturing
293b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // local variables.  There are three ways to capture a local variable:
294b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // capture by copy in the C++11 sense, capture by reference
295b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // in the C++11 sense, and __block capture.  Lambdas explicitly specify
296b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // capture by copy or capture by reference.  For blocks, __block capture
297b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // applies to variables with that annotation, variables of reference type
298b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // are captured by reference, and other variables are captured by copy.
299b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum CaptureKind {
300b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman      Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
301b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    };
302b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
303b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // The variable being captured (if we are not capturing 'this'),
304b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // and misc bits descibing the capture.
305b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
306b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
307b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // Expression to initialize a field of the given type, and whether this
308b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // is a nested capture; the expression is only required if we are
309b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // capturing ByVal and the variable's type has a non-trivial
310b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // copy constructor.
311b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
312b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
31393962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief The source location at which the first capture occurred..
31493962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation Loc;
31593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
316a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief The location of the ellipsis that expands a parameter pack.
317a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation EllipsisLoc;
318a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
319999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief The type as it was captured, which is in effect the type of the
320999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// non-static data member that would hold the capture.
321999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType CaptureType;
322999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
323b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  public:
324b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
325999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            SourceLocation Loc, SourceLocation EllipsisLoc,
326999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
327b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman      : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
328999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
329999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        CaptureType(CaptureType){}
330b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
331b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum IsThisCapture { ThisCapture };
332999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    Capture(IsThisCapture, bool isNested, SourceLocation Loc,
333999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
334a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
335999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        EllipsisLoc(), CaptureType(CaptureType) { }
336b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
337b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
338b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isVariableCapture() const { return !isThisCapture(); }
339b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
340b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
341b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
342b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isNested() { return CopyExprAndNested.getInt(); }
343b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
344b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    VarDecl *getVariable() const {
345b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      return VarAndKind.getPointer();
346b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
34793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
34893962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief Retrieve the location at which this variable was captured.
34993962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation getLocation() const { return Loc; }
35093962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
351a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief Retrieve the source location of the ellipsis, whose presence
352a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// indicates that the capture is a pack expansion.
353a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
354a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
355999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief Retrieve the capture type for this capture, which is effectively
356999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// the type of the non-static data member in the lambda/block structure
357999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// that would store this capture.
358999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType getCaptureType() const { return CaptureType; }
359999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
360b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    Expr *getCopyExpr() const {
361b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      return CopyExprAndNested.getPointer();
362b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
363b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
364b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
365b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
36684b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
36784b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman      HasImplicitReturnType(false)
368b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman     {}
369b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
370b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CaptureMap - A map of captured variables to (index+1) into Captures.
371b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
372b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
373b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
374b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// zero if 'this' is not captured.
375b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  unsigned CXXThisCaptureIndex;
376b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
377b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// Captures - The captures.
378b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  SmallVector<Capture, 4> Captures;
379b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
38084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// \brief - Whether the target type of return statements in this context
38184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// is deduced (e.g. a lambda or block with omitted return type).
38284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  bool HasImplicitReturnType;
38384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
38484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// ReturnType - The target type of return statements in this context,
38584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// or null if unknown.
38684b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  QualType ReturnType;
38784b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
388999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
389999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  SourceLocation Loc, SourceLocation EllipsisLoc,
390999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  QualType CaptureType, Expr *Cpy) {
391a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
392999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                               EllipsisLoc, CaptureType, Cpy));
393b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    CaptureMap[Var] = Captures.size();
394b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
395b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
396999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
397999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                      Expr *Cpy) {
398999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
399999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                               Cpy));
400b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    CXXThisCaptureIndex = Captures.size();
401b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
402b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
403a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the C++ 'this' is captured.
404a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
405a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
406a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
407a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCXXThisCapture() {
408a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCXXThisCaptured() && "this has not been captured");
409a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CXXThisCaptureIndex - 1];
410a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
411a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
412a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the given variable has been captured.
413a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCaptured(VarDecl *Var) const {
414b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman    return CaptureMap.count(Var);
415a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
416a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
417a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of the given variable, if it has been
418a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// captured already.
419a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCapture(VarDecl *Var) {
420a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCaptured(Var) && "Variable has not been captured");
421a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CaptureMap[Var] - 1];
422a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
423a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
424a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  const Capture &getCapture(VarDecl *Var) const {
425a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
426a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor      = CaptureMap.find(Var);
427a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(Known != CaptureMap.end() && "Variable has not been captured");
428a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[Known->second - 1];
429a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
430a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
431b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
432b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
433b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
434b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  static bool classof(const CapturingScopeInfo *BSI) { return true; }
435b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman};
436b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
437781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed.
438b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo {
439781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
440781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  BlockDecl *TheDecl;
441781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
442781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// TheScope - This is the scope for the block itself, which contains
443781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// arguments etc.
444781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  Scope *TheScope;
445781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
446781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// BlockType - The function type of the block, if one was given.
447781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// Its return type may be BuiltinType::Dependent.
448781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  QualType FunctionType;
449781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
450d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
451b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
452b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      TheScope(BlockScope)
453781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  {
454ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Block;
455781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
456781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
457781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~BlockScopeInfo();
458781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
459ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
460ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Block;
461ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
462781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  static bool classof(const BlockScopeInfo *BSI) { return true; }
463781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
464781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
465b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo {
466ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic:
467ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The class that describes the lambda.
468ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  CXXRecordDecl *Lambda;
46901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
47076e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  /// \brief The class that describes the lambda.
47176e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  CXXMethodDecl *CallOperator;
47276e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor
47301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Source range covering the lambda introducer [...].
47401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  SourceRange IntroducerRange;
47501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
476ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The number of captures in the \c Captures list that are
477ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// explicit captures.
478ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  unsigned NumExplicitCaptures;
47972899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman
480503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether this is a mutable lambda.
481d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman  bool Mutable;
48201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
48301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Whether the (empty) parameter list is explicit.
48401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  bool ExplicitParams;
485d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman
486503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether any of the capture expressions requires cleanups.
487503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  bool ExprNeedsCleanups;
488503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
489612409ece080e814f79e06772c690d603f45fbd6Richard Smith  /// \brief Whether the lambda contains an unexpanded parameter pack.
490612409ece080e814f79e06772c690d603f45fbd6Richard Smith  bool ContainsUnexpandedParameterPack;
491612409ece080e814f79e06772c690d603f45fbd6Richard Smith
4929daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Variables used to index into by-copy array captures.
4939daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
4949daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
4959daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
4969daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// its list of array index variables.
4979daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
4989daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
49976e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
50076e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor                  CXXMethodDecl *CallOperator)
501b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
502503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
503612409ece080e814f79e06772c690d603f45fbd6Richard Smith      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
504ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  {
505ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Lambda;
506ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
507b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
508ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  virtual ~LambdaScopeInfo();
509b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
510a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Note when
511a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  void finishedExplicitCaptures() {
512a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    NumExplicitCaptures = Captures.size();
513a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
514a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
515ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
516ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Lambda;
517ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
518ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const LambdaScopeInfo *BSI) { return true; }
519ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
520ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman};
521ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
52258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
52358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  : Base(0, false), Property(0) {}
52458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
52558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy
52658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
52758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  FunctionScopeInfo::WeakObjectProfileTy Result;
52858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  Result.Base.setInt(true);
52958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  return Result;
53058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose}
53158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
5327a2704800943fbb69207e125d28186278712af36Jordan Rosetemplate <typename ExprT>
5337a2704800943fbb69207e125d28186278712af36Jordan Rosevoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
5347a2704800943fbb69207e125d28186278712af36Jordan Rose  assert(E);
5357a2704800943fbb69207e125d28186278712af36Jordan Rose  WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
5367a2704800943fbb69207e125d28186278712af36Jordan Rose  Uses.push_back(WeakUseTy(E, IsRead));
537781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}
5387a2704800943fbb69207e125d28186278712af36Jordan Rose
5397a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace sema
5407a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace clang
541781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
54258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosenamespace llvm {
54358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  template <>
54458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  struct DenseMapInfo<clang::sema::FunctionScopeInfo::WeakObjectProfileTy> {
54558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    typedef clang::sema::FunctionScopeInfo::WeakObjectProfileTy ProfileTy;
54658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    static inline ProfileTy getEmptyKey() {
54758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return ProfileTy();
54858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
54958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    static inline ProfileTy getTombstoneKey() {
55058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return ProfileTy::getSentinel();
55158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
55258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
55358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    static unsigned getHashValue(const ProfileTy &Val) {
55458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      typedef std::pair<ProfileTy::BaseInfoTy, const clang::NamedDecl *> Pair;
55558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, Val.Property));
55658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
55758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
55858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    static bool isEqual(const ProfileTy &LHS, const ProfileTy &RHS) {
55958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return LHS == RHS;
56058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
56158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  };
56258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose} // end namespace llvm
56358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
564781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif
565