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"
193a2f91280a49f4747063f983dc6a3296bd9359d2Ben Langmuir#include "clang/Basic/CapturedStmt.h"
20351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Basic/PartialDiagnostic.h"
21c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali#include "clang/Sema/Ownership.h"
22781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/DenseMap.h"
23c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali#include "llvm/ADT/SmallSet.h"
24781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/SmallVector.h"
25c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali#include <algorithm>
26781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
27781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace clang {
28781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
2958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass Decl;
30781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass BlockDecl;
316afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Sirajclass CapturedDecl;
32f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass CXXMethodDecl;
330d8e9646bc000bab521ce52ed294209a92298cefRichard Smithclass FieldDecl;
347fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Roseclass ObjCPropertyDecl;
35781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass IdentifierInfo;
368c045ace381972f41d385b0a661ccf172834f459Ben Langmuirclass ImplicitParamDecl;
37ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnerclass LabelDecl;
38781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass ReturnStmt;
39781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass Scope;
40781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass SwitchStmt;
41fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Valiclass TemplateTypeParmDecl;
42fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Valiclass TemplateParameterList;
43f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass VarDecl;
447a2704800943fbb69207e125d28186278712af36Jordan Roseclass DeclRefExpr;
45c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Valiclass MemberExpr;
467a2704800943fbb69207e125d28186278712af36Jordan Roseclass ObjCIvarRefExpr;
4758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass ObjCPropertyRefExpr;
487fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Roseclass ObjCMessageExpr;
49781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
50781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace sema {
51781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
52625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// \brief Contains information about the compound statement currently being
53625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// parsed.
54625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkoclass CompoundScopeInfo {
55625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkopublic:
56625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  CompoundScopeInfo()
57625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    : HasEmptyLoopBodies(false) { }
58625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
59625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief Whether this compound stamement contains `for' or `while' loops
60625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// with empty bodies.
61625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  bool HasEmptyLoopBodies;
62625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
63625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  void setHasEmptyLoopBodies() {
64625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    HasEmptyLoopBodies = true;
65625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
66625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko};
67625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
68351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekclass PossiblyUnreachableDiag {
69351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekpublic:
70351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  PartialDiagnostic PD;
71351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  SourceLocation Loc;
72351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  const Stmt *stmt;
73351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
74351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
75351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek                          const Stmt *stmt)
76351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    : PD(PD), Loc(Loc), stmt(stmt) {}
77351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek};
78351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
79781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a function, method, or block that is
80781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// currently being parsed.
81781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass FunctionScopeInfo {
82ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanprotected:
83ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  enum ScopeKind {
84ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Function,
85ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Block,
866afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    SK_Lambda,
876afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    SK_CapturedRegion
88ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  };
89ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
90781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
91ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief What kind of scope we are describing.
92ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  ///
93ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  ScopeKind Kind;
94781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
95809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// \brief Whether this function contains a VLA, \@try, try, C++
96781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// initializer, or anything else that can't be jumped past.
97781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasBranchProtectedScope;
98781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
99781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Whether this function contains any switches or direct gotos.
100781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasBranchIntoScope;
101781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
102781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Whether this function contains any indirect gotos.
103781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasIndirectGoto;
104781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
105820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis  /// \brief Whether a statement was dropped because it was invalid.
106820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis  bool HasDroppedStmt;
107820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis
108535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose  /// A flag that is set when parsing a method that must call super's
109535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose  /// implementation, such as \c -dealloc, \c -finalize, or any method marked
110535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose  /// with \c __attribute__((objc_requires_super)).
111535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose  bool ObjCShouldCallSuper;
11295aac15936e8362aeb4813f95bc255dee6473592Eli Friedman
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// True when this is a method marked as a designated initializer.
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool ObjCIsDesignatedInit;
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// This starts true for a method marked as designated initializer and will
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// be set to false if there is an invocation to a designated initializer of
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// the super class.
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool ObjCWarnForNoDesignatedInitChain;
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// True when this is an initializer method not marked as a designated
121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// initializer within a class that has at least one initializer marked as a
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// designated initializer.
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool ObjCIsSecondaryInit;
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// This starts true for a secondary initializer method and will be set to
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// false if there is an invocation of an initializer on 'self'.
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool ObjCWarnForNoInitDelegation;
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1288fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  /// \brief Used to determine if errors occurred in this function or block.
1298fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  DiagnosticErrorTrap ErrorTrap;
130781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
131781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// SwitchStack - This is the current set of active switch statements in the
132781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block.
133686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<SwitchStmt*, 8> SwitchStack;
134781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
135781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief The list of return statements that occur within the function or
136781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block, if there is any chance of applying the named return value
1377dd900ed308506f9cf1cb72c70db1652f94cab37Jordan Rose  /// optimization, or if we need to infer a return type.
138686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<ReturnStmt*, 4> Returns;
139625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
140625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief The stack of currently active compound stamement scopes in the
141625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// function.
142625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
143625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
144351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// \brief A list of PartialDiagnostics created but delayed within the
145351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// current function scope.  These diagnostics are vetted for reachability
146351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// prior to being emitted.
147686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
148781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
14958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic:
15058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Represents a simple identification of a weak object.
15158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
15258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
15358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
15458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// This is used to determine if two weak accesses refer to the same object.
15558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Here are some examples of how various accesses are "profiled":
15658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
15758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Access Expression |     "Base" Decl     |          "Property" Decl
15858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// :---------------: | :-----------------: | :------------------------------:
15958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
16058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
16158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
16258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
16358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
16458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
16558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
1667a2704800943fbb69207e125d28186278712af36Jordan Rose  /// weakVar           | 0 (known)           | weakVar (VarDecl)
1677a2704800943fbb69207e125d28186278712af36Jordan Rose  /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
16858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
16958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Objects are identified with only two Decls to make it reasonably fast to
17058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// compare them.
17158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  class WeakObjectProfileTy {
17258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The base object decl, as described in the class documentation.
17358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
17458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The extra flag is "true" if the Base and Property are enough to uniquely
17558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// identify the object in memory.
17658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
17758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// \sa isExactProfile()
17858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
17958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    BaseInfoTy Base;
18058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
18158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// The "property" decl, as described in the class documentation.
18258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
18358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
18458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// case of "implicit" properties (regular methods accessed via dot syntax).
18558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const NamedDecl *Property;
18658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
1877a2704800943fbb69207e125d28186278712af36Jordan Rose    /// Used to find the proper base profile for a given base expression.
1887a2704800943fbb69207e125d28186278712af36Jordan Rose    static BaseInfoTy getBaseInfo(const Expr *BaseE);
1897a2704800943fbb69207e125d28186278712af36Jordan Rose
19058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    // For use in DenseMap.
191b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    friend class DenseMapInfo;
19258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    inline WeakObjectProfileTy();
19358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    static inline WeakObjectProfileTy getSentinel();
19458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
19558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  public:
19658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
1977fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
1987a2704800943fbb69207e125d28186278712af36Jordan Rose    WeakObjectProfileTy(const DeclRefExpr *RE);
1997a2704800943fbb69207e125d28186278712af36Jordan Rose    WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
20058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
201c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose    const NamedDecl *getBase() const { return Base.getPointer(); }
20258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const NamedDecl *getProperty() const { return Property; }
20358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
20458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Returns true if the object base specifies a known object in memory,
20558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// rather than, say, an instance variable or property of another object.
20658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
20758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
20858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// considered an exact profile if \c foo is a local variable, even if
20958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// another variable \c foo2 refers to the same object as \c foo.
21058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    ///
21158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// For increased precision, accesses with base variables that are
21258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
21358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// be exact, though this is not true for arbitrary variables
21458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    /// (foo.prop1.prop2).
21558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool isExactProfile() const {
21658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Base.getInt();
21758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
21858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
21958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool operator==(const WeakObjectProfileTy &Other) const {
22058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Base == Other.Base && Property == Other.Property;
22158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
222b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose
223b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    // For use in DenseMap.
224b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    // We can't specialize the usual llvm::DenseMapInfo at the end of the file
225b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    // because by that point the DenseMap in FunctionScopeInfo has already been
226b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    // instantiated.
227b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    class DenseMapInfo {
228b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    public:
229b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      static inline WeakObjectProfileTy getEmptyKey() {
230b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        return WeakObjectProfileTy();
231b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      }
232b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      static inline WeakObjectProfileTy getTombstoneKey() {
233b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        return WeakObjectProfileTy::getSentinel();
234b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      }
235b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose
236b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      static unsigned getHashValue(const WeakObjectProfileTy &Val) {
237b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
238b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
239b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose                                                           Val.Property));
240b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      }
241b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose
242b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      static bool isEqual(const WeakObjectProfileTy &LHS,
243b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose                          const WeakObjectProfileTy &RHS) {
244b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose        return LHS == RHS;
245b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose      }
246b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose    };
24758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  };
24858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
24958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Represents a single use of a weak object.
25058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
25158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Stores both the expression and whether the access is potentially unsafe
25258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// (i.e. it could potentially be warned about).
25358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
25458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
25558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  class WeakUseTy {
25658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    llvm::PointerIntPair<const Expr *, 1, bool> Rep;
25758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  public:
25858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
25958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
26058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    const Expr *getUseExpr() const { return Rep.getPointer(); }
26158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool isUnsafe() const { return Rep.getInt(); }
26258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    void markSafe() { Rep.setInt(false); }
26358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
26458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    bool operator==(const WeakUseTy &Other) const {
26558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose      return Rep == Other.Rep;
26658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    }
26758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  };
26858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
26958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect uses of a particular weak object in a function body.
27058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
27158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
27258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  typedef SmallVector<WeakUseTy, 4> WeakUseVector;
27358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
27458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect all uses of weak objects in a function body.
27558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
27658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
277b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose  typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
278b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose                              WeakObjectProfileTy::DenseMapInfo>
27958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose          WeakObjectUseMap;
28058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
28158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseprivate:
28258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Used to collect all uses of weak objects in this function body.
28358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
28458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
28558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  WeakObjectUseMap WeakObjectUses;
28658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
28758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic:
2887a2704800943fbb69207e125d28186278712af36Jordan Rose  /// Record that a weak object was accessed.
28958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
29058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
2917a2704800943fbb69207e125d28186278712af36Jordan Rose  template <typename ExprT>
2927a2704800943fbb69207e125d28186278712af36Jordan Rose  inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
29358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
2947fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose  void recordUseOfWeak(const ObjCMessageExpr *Msg,
2957fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose                       const ObjCPropertyDecl *Prop);
2967fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose
29758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Record that a given expression is a "safe" access of a weak object (e.g.
29858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// assigning it to a strong variable.)
29958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  ///
30058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  /// Part of the implementation of -Wrepeated-use-of-weak.
30158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  void markSafeWeakUse(const Expr *E);
30258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
30358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  const WeakObjectUseMap &getWeakObjectUses() const {
30458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose    return WeakObjectUses;
30558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  }
30658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
307781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchIntoScope() {
308781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchIntoScope = true;
309781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
310781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
311781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchProtectedScope() {
312781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchProtectedScope = true;
313781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
314781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
315781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasIndirectGoto() {
316781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasIndirectGoto = true;
317781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
318781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
319820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis  void setHasDroppedStmt() {
320820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis    HasDroppedStmt = true;
321820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis  }
322820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis
323781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool NeedsScopeChecking() const {
324820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis    return !HasDroppedStmt &&
325820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis        (HasIndirectGoto ||
326820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis          (HasBranchProtectedScope && HasBranchIntoScope));
327781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
328781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
329d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  FunctionScopeInfo(DiagnosticsEngine &Diag)
330ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    : Kind(SK_Function),
331781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchProtectedScope(false),
332781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchIntoScope(false),
333781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasIndirectGoto(false),
334820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis      HasDroppedStmt(false),
335535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose      ObjCShouldCallSuper(false),
336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ObjCIsDesignatedInit(false),
337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ObjCWarnForNoDesignatedInitChain(false),
338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ObjCIsSecondaryInit(false),
339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ObjCWarnForNoInitDelegation(false),
3408fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis      ErrorTrap(Diag) { }
341781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
342781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~FunctionScopeInfo();
343781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
344781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Clear out the information in this function scope, making it
345781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// suitable for reuse.
3468fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  void Clear();
347781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
348781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
349b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo {
350b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic:
351b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  enum ImplicitCaptureStyle {
3526afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
3536afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    ImpCap_CapturedRegion
354b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
355b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
356b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  ImplicitCaptureStyle ImpCaptureStyle;
357b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
358b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  class Capture {
3590d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // There are three categories of capture: capturing 'this', capturing
3600d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // local variables, and C++1y initialized captures (which can have an
3610d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // arbitrary initializer, and don't really capture in the traditional
3620d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // sense at all).
3630d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    //
3640d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // There are three ways to capture a local variable:
3650d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    //  - capture by copy in the C++11 sense,
3660d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    //  - capture by reference in the C++11 sense, and
3670d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    //  - __block capture.
3680d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // Lambdas explicitly specify capture by copy or capture by reference.
3690d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // For blocks, __block capture applies to variables with that annotation,
3700d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // variables of reference type are captured by reference, and other
3710d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // variables are captured by copy.
372b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum CaptureKind {
37304fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith      Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This
374b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    };
375b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
37604fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith    /// The variable being captured (if we are not capturing 'this') and whether
37704fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith    /// this is a nested capture.
37804fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith    llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested;
379b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
38004fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith    /// Expression to initialize a field of the given type, and the kind of
38104fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith    /// capture (if this is a capture and not an init-capture). The expression
38204fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith    /// is only required if we are capturing ByVal and the variable's type has
38304fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith    /// a non-trivial copy constructor.
3840d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind;
3850d8e9646bc000bab521ce52ed294209a92298cefRichard Smith
3860d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    /// \brief The source location at which the first capture occurred.
38793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation Loc;
3880d8e9646bc000bab521ce52ed294209a92298cefRichard Smith
389a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief The location of the ellipsis that expands a parameter pack.
390a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation EllipsisLoc;
3910d8e9646bc000bab521ce52ed294209a92298cefRichard Smith
392999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief The type as it was captured, which is in effect the type of the
393999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// non-static data member that would hold the capture.
394999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType CaptureType;
3950d8e9646bc000bab521ce52ed294209a92298cefRichard Smith
396b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  public:
3970d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
3980d8e9646bc000bab521ce52ed294209a92298cefRichard Smith            SourceLocation Loc, SourceLocation EllipsisLoc,
399999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
40004fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith        : VarAndNested(Var, IsNested),
4010d8e9646bc000bab521ce52ed294209a92298cefRichard Smith          InitExprAndCaptureKind(Cpy, Block ? Cap_Block :
4020d8e9646bc000bab521ce52ed294209a92298cefRichard Smith                                      ByRef ? Cap_ByRef : Cap_ByCopy),
4030d8e9646bc000bab521ce52ed294209a92298cefRichard Smith          Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
404b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
405b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum IsThisCapture { ThisCapture };
4060d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
407999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
4086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        : VarAndNested(nullptr, IsNested),
40904fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith          InitExprAndCaptureKind(Cpy, Cap_This),
4100d8e9646bc000bab521ce52ed294209a92298cefRichard Smith          Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
411b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
4120d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    bool isThisCapture() const {
41304fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith      return InitExprAndCaptureKind.getInt() == Cap_This;
4140d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    }
4150d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    bool isVariableCapture() const {
41604fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith      return InitExprAndCaptureKind.getInt() != Cap_This;
4170d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    }
4180d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    bool isCopyCapture() const {
4190d8e9646bc000bab521ce52ed294209a92298cefRichard Smith      return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
4200d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    }
4210d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    bool isReferenceCapture() const {
4220d8e9646bc000bab521ce52ed294209a92298cefRichard Smith      return InitExprAndCaptureKind.getInt() == Cap_ByRef;
4230d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    }
4240d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    bool isBlockCapture() const {
4250d8e9646bc000bab521ce52ed294209a92298cefRichard Smith      return InitExprAndCaptureKind.getInt() == Cap_Block;
4260d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    }
42704fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith    bool isNested() { return VarAndNested.getInt(); }
428b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
429b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    VarDecl *getVariable() const {
43004fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith      return VarAndNested.getPointer();
431b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
43293962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
43393962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief Retrieve the location at which this variable was captured.
43493962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation getLocation() const { return Loc; }
43593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
436a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief Retrieve the source location of the ellipsis, whose presence
437a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// indicates that the capture is a pack expansion.
438a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
439a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
440999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief Retrieve the capture type for this capture, which is effectively
441999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// the type of the non-static data member in the lambda/block structure
442999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// that would store this capture.
443999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType getCaptureType() const { return CaptureType; }
444999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
4450d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    Expr *getInitExpr() const {
4460d8e9646bc000bab521ce52ed294209a92298cefRichard Smith      return InitExprAndCaptureKind.getPointer();
447b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
448b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
449b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
450b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
45184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
45284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman      HasImplicitReturnType(false)
453b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman     {}
454b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
455b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CaptureMap - A map of captured variables to (index+1) into Captures.
456b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
457b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
458b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
459b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// zero if 'this' is not captured.
460b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  unsigned CXXThisCaptureIndex;
461b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
462b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// Captures - The captures.
463b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  SmallVector<Capture, 4> Captures;
464b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
46584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// \brief - Whether the target type of return statements in this context
46684b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// is deduced (e.g. a lambda or block with omitted return type).
46784b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  bool HasImplicitReturnType;
46884b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
46984b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// ReturnType - The target type of return statements in this context,
47084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// or null if unknown.
47184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  QualType ReturnType;
47284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
473999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
474999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  SourceLocation Loc, SourceLocation EllipsisLoc,
475999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  QualType CaptureType, Expr *Cpy) {
476a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
477999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                               EllipsisLoc, CaptureType, Cpy));
478b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    CaptureMap[Var] = Captures.size();
479b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
480b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
481999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
482c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor                      Expr *Cpy);
483b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
484a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the C++ 'this' is captured.
485a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
486a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
487a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
488a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCXXThisCapture() {
489a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCXXThisCaptured() && "this has not been captured");
490a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CXXThisCaptureIndex - 1];
491a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
492a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
493a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the given variable has been captured.
494a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCaptured(VarDecl *Var) const {
495b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman    return CaptureMap.count(Var);
496a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
497a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
498a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of the given variable, if it has been
499a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// captured already.
500a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCapture(VarDecl *Var) {
501a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCaptured(Var) && "Variable has not been captured");
502a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CaptureMap[Var] - 1];
503a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
504a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
505a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  const Capture &getCapture(VarDecl *Var) const {
506a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
507a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor      = CaptureMap.find(Var);
508a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(Known != CaptureMap.end() && "Variable has not been captured");
509a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[Known->second - 1];
510a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
511a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
512b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
5136afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
5146afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj                                 || FSI->Kind == SK_CapturedRegion;
515b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
516b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman};
517b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
518781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed.
519b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo {
520781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
521781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  BlockDecl *TheDecl;
522781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
523781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// TheScope - This is the scope for the block itself, which contains
524781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// arguments etc.
525781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  Scope *TheScope;
526781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
527781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// BlockType - The function type of the block, if one was given.
528781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// Its return type may be BuiltinType::Dependent.
529781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  QualType FunctionType;
530781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
531d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
532b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
533b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      TheScope(BlockScope)
534781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  {
535ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Block;
536781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
537781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
538781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~BlockScopeInfo();
539781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
540ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
541ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Block;
542ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
543781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
544781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
5456afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj/// \brief Retains information about a captured region.
5466afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Sirajclass CapturedRegionScopeInfo: public CapturingScopeInfo {
5476afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Sirajpublic:
5486afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  /// \brief The CapturedDecl for this statement.
5496afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  CapturedDecl *TheCapturedDecl;
5506afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  /// \brief The captured record type.
5516afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  RecordDecl *TheRecordDecl;
5526afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  /// \brief This is the enclosing scope of the captured region.
5536afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  Scope *TheScope;
5548c045ace381972f41d385b0a661ccf172834f459Ben Langmuir  /// \brief The implicit parameter for the captured variables.
5558c045ace381972f41d385b0a661ccf172834f459Ben Langmuir  ImplicitParamDecl *ContextParam;
5566afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  /// \brief The kind of captured region.
5576afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  CapturedRegionKind CapRegionKind;
5586afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj
5596afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
5608c045ace381972f41d385b0a661ccf172834f459Ben Langmuir                          RecordDecl *RD, ImplicitParamDecl *Context,
5618c045ace381972f41d385b0a661ccf172834f459Ben Langmuir                          CapturedRegionKind K)
5626afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
5638c045ace381972f41d385b0a661ccf172834f459Ben Langmuir      TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
5648c045ace381972f41d385b0a661ccf172834f459Ben Langmuir      ContextParam(Context), CapRegionKind(K)
5656afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  {
5666afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    Kind = SK_CapturedRegion;
5676afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  }
5686afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj
5696afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  virtual ~CapturedRegionScopeInfo();
5706afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj
5716afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  /// \brief A descriptive name for the kind of captured region this is.
5726afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  StringRef getRegionName() const {
5736afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    switch (CapRegionKind) {
5746afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    case CR_Default:
5756afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj      return "default captured statement";
5760c018357b8bbb1f96bbf622a5807421e626b4228Alexey Bataev    case CR_OpenMP:
5770c018357b8bbb1f96bbf622a5807421e626b4228Alexey Bataev      return "OpenMP region";
5786afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    }
5790579c165aa54840898956703ebd63bdd1f4dd907Benjamin Kramer    llvm_unreachable("Invalid captured region kind!");
5806afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  }
5816afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj
5826afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  static bool classof(const FunctionScopeInfo *FSI) {
5836afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj    return FSI->Kind == SK_CapturedRegion;
5846afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj  }
5856afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj};
5866afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj
587b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo {
588ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic:
589ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The class that describes the lambda.
590ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  CXXRecordDecl *Lambda;
59101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
592f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett  /// \brief The lambda's compiler-generated \c operator().
59376e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  CXXMethodDecl *CallOperator;
59476e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor
59501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Source range covering the lambda introducer [...].
59601d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  SourceRange IntroducerRange;
59701d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
598f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett  /// \brief Source location of the '&' or '=' specifying the default capture
599f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett  /// type, if any.
600f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett  SourceLocation CaptureDefaultLoc;
601f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett
602f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett  /// \brief The number of captures in the \c Captures list that are
603ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// explicit captures.
604ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  unsigned NumExplicitCaptures;
60572899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman
606503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether this is a mutable lambda.
607d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman  bool Mutable;
608f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett
60901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Whether the (empty) parameter list is explicit.
61001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  bool ExplicitParams;
611d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman
612503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether any of the capture expressions requires cleanups.
613503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  bool ExprNeedsCleanups;
614503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
615612409ece080e814f79e06772c690d603f45fbd6Richard Smith  /// \brief Whether the lambda contains an unexpanded parameter pack.
616612409ece080e814f79e06772c690d603f45fbd6Richard Smith  bool ContainsUnexpandedParameterPack;
617612409ece080e814f79e06772c690d603f45fbd6Richard Smith
6189daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Variables used to index into by-copy array captures.
619cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  SmallVector<VarDecl *, 4> ArrayIndexVars;
6209daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
6219daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
6229daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// its list of array index variables.
623cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  SmallVector<unsigned, 4> ArrayIndexStarts;
624fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali
625fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// \brief If this is a generic lambda, use this as the depth of
626fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// each 'auto' parameter, during initial AST construction.
627fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  unsigned AutoTemplateParameterDepth;
628fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali
629fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// \brief Store the list of the auto parameters for a generic lambda.
630fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// If this is a generic lambda, store the list of the auto
631fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// parameters converted into TemplateTypeParmDecls into a vector
632fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// that can be used to construct the generic lambda's template
633fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// parameter list, during initial AST construction.
634fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams;
635fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali
636fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// If this is a generic lambda, and the template parameter
637fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// list has been created (from the AutoTemplateParams) then
638fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  /// store a reference to it (cache it to avoid reconstructing it).
639fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  TemplateParameterList *GLTemplateParameterList;
640c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali
641c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs
642c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  or MemberExprs) that refer to local variables in a generic lambda
643c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  or a lambda in a potentially-evaluated-if-used context.
644c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///
645c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  Potentially capturable variables of a nested lambda that might need
646c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///   to be captured by the lambda are housed here.
647c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  This is specifically useful for generic lambdas or
648c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  lambdas within a a potentially evaluated-if-used context.
649c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  If an enclosing variable is named in an expression of a lambda nested
650c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  within a generic lambda, we don't always know know whether the variable
651c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  will truly be odr-used (i.e. need to be captured) by that nested lambda,
652c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  until its instantiation. But we still need to capture it in the
653c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  enclosing lambda if all intervening lambdas can capture the variable.
654c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali
655c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
656c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali
657c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// \brief Contains all variable-referring-expressions that refer
658c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  to local variables that are usable as constant expressions and
659c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  do not involve an odr-use (they may still need to be captured
660c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  if the enclosing full-expression is instantiation dependent).
661c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  llvm::SmallSet<Expr*, 8> NonODRUsedCapturingExprs;
662c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali
663c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  SourceLocation PotentialThisCaptureLocation;
664fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali
665fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali  LambdaScopeInfo(DiagnosticsEngine &Diag)
6666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
6676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
668fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false),
6696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr)
670ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  {
671ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Lambda;
672ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
673b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
674ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  virtual ~LambdaScopeInfo();
675b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
676f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett  /// \brief Note when all explicit captures have been added.
677a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  void finishedExplicitCaptures() {
678a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    NumExplicitCaptures = Captures.size();
679a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
680c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
681c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  static bool classof(const FunctionScopeInfo *FSI) {
682152b4e4652baedfceba1cd8115515629225e713fManuel Klimek    return FSI->Kind == SK_Lambda;
683ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
684c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali
685c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///
686c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// \brief Add a variable that might potentially be captured by the
687c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// lambda and therefore the enclosing lambdas.
688c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///
689c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// This is also used by enclosing lambda's to speculatively capture
690c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// variables that nested lambda's - depending on their enclosing
691c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// specialization - might need to capture.
692c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// Consider:
693c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// void f(int, int); <-- don't capture
694c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// void f(const int&, double); <-- capture
695c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// void foo() {
696c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///   const int x = 10;
697c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///   auto L = [=](auto a) { // capture 'x'
698c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///      return [=](auto b) {
699c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///        f(x, a);  // we may or may not need to capture 'x'
700c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///      };
701c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///   };
702c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// }
703c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  void addPotentialCapture(Expr *VarExpr) {
704c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr));
705c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    PotentiallyCapturingExprs.push_back(VarExpr);
706c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
707c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali
708c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  void addPotentialThisCapture(SourceLocation Loc) {
709c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    PotentialThisCaptureLocation = Loc;
710c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
711c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  bool hasPotentialThisCapture() const {
712c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    return PotentialThisCaptureLocation.isValid();
713c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
714c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali
715c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// \brief Mark a variable's reference in a lambda as non-odr using.
716c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///
717c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// For generic lambdas, if a variable is named in a potentially evaluated
718c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// expression, where the enclosing full expression is dependent then we
719c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// must capture the variable (given a default capture).
720c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// This is accomplished by recording all references to variables
721c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of
722c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// PotentialCaptures. All such variables have to be captured by that lambda,
723c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// except for as described below.
724c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// If that variable is usable as a constant expression and is named in a
725c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// manner that does not involve its odr-use (e.g. undergoes
726c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
727c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
728c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// if we can determine that the full expression is not instantiation-
729c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// dependent, then we can entirely avoid its capture.
730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///   const int n = 0;
732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///   [&] (auto x) {
733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///     (void)+n + x;
734c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///   };
735c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// Interestingly, this strategy would involve a capture of n, even though
736c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// it's obviously not odr-used here, because the full-expression is
737c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// instantiation-dependent.  It could be useful to avoid capturing such
738c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// variables, even when they are referred to in an instantiation-dependent
739c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// expression, if we can unambiguously determine that they shall never be
740c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// odr-used.  This would involve removal of the variable-referring-expression
741c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// from the array of PotentialCaptures during the lvalue-to-rvalue
742c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// conversions.  But per the working draft N3797, (post-chicago 2013) we must
743c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// capture such variables.
744c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// Before anyone is tempted to implement a strategy for not-capturing 'n',
745c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  /// consider the insightful warning in:
746c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///    /cfe-commits/Week-of-Mon-20131104/092596.html
747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// "The problem is that the set of captures for a lambda is part of the ABI
748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///  (since lambda layout can be made visible through inline functions and the
749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///  like), and there are no guarantees as to which cases we'll manage to build
750651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///  an lvalue-to-rvalue conversion in, when parsing a template -- some
751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///  seemingly harmless change elsewhere in Sema could cause us to start or stop
752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///  building such a node. So we need a rule that anyone can implement and get
753c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///  exactly the same result".
754c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  ///
755c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
756c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    assert(isa<DeclRefExpr>(CapturingVarExpr)
757c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali        || isa<MemberExpr>(CapturingVarExpr));
758c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    NonODRUsedCapturingExprs.insert(CapturingVarExpr);
759c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
761c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    assert(isa<DeclRefExpr>(CapturingVarExpr)
762c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali      || isa<MemberExpr>(CapturingVarExpr));
763c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    return NonODRUsedCapturingExprs.count(CapturingVarExpr);
764c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
765c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  void removePotentialCapture(Expr *E) {
766c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    PotentiallyCapturingExprs.erase(
767c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali        std::remove(PotentiallyCapturingExprs.begin(),
768c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali            PotentiallyCapturingExprs.end(), E),
769c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali        PotentiallyCapturingExprs.end());
770c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
771c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  void clearPotentialCaptures() {
772c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    PotentiallyCapturingExprs.clear();
773c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    PotentialThisCaptureLocation = SourceLocation();
774c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
775c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  unsigned getNumPotentialVariableCaptures() const {
776c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    return PotentiallyCapturingExprs.size();
777c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
778c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali
779c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  bool hasPotentialCaptures() const {
780c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali    return getNumPotentialVariableCaptures() ||
781c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali                                  PotentialThisCaptureLocation.isValid();
782c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  }
783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // When passed the index, returns the VarDecl and Expr associated
785c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali  // with the index.
786651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const;
787ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman};
788ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
78958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
7906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  : Base(nullptr, false), Property(nullptr) {}
79158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
79258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy
79358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
79458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  FunctionScopeInfo::WeakObjectProfileTy Result;
79558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  Result.Base.setInt(true);
79658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose  return Result;
79758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose}
79858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose
7997a2704800943fbb69207e125d28186278712af36Jordan Rosetemplate <typename ExprT>
8007a2704800943fbb69207e125d28186278712af36Jordan Rosevoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
8017a2704800943fbb69207e125d28186278712af36Jordan Rose  assert(E);
8027a2704800943fbb69207e125d28186278712af36Jordan Rose  WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
8037a2704800943fbb69207e125d28186278712af36Jordan Rose  Uses.push_back(WeakUseTy(E, IsRead));
804781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}
8057a2704800943fbb69207e125d28186278712af36Jordan Rose
806c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregorinline void
807c3f1742bdd1ae0091d51168e111cd63861587b13Douglas GregorCapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
808c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor                                   QualType CaptureType, Expr *Cpy) {
809c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
810c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor                             Cpy));
811c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  CXXThisCaptureIndex = Captures.size();
812c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
813c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor  if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
814c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor    LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
815c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor}
816c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor
8177a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace sema
8187a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace clang
819781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
820781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif
821