ScopeInfo.h revision 809d1be9820039b4cf6efa48246a0d70ffa13394
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//
10781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//  This file defines FunctionScopeInfo and BlockScopeInfo.
11781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//
12781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//===----------------------------------------------------------------------===//
13781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
14781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
15781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#define LLVM_CLANG_SEMA_SCOPE_INFO_H
16781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
17781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "clang/AST/Type.h"
18351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Basic/PartialDiagnostic.h"
19781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/DenseMap.h"
20781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/SmallVector.h"
21781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
22781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace clang {
23781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
24781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass BlockDecl;
25f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass CXXMethodDecl;
26781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass IdentifierInfo;
27ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnerclass LabelDecl;
28781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass ReturnStmt;
29781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass Scope;
30781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass SwitchStmt;
31f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass VarDecl;
32781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
33781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace sema {
34781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
35625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// \brief Contains information about the compound statement currently being
36625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// parsed.
37625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkoclass CompoundScopeInfo {
38625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkopublic:
39625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  CompoundScopeInfo()
40625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    : HasEmptyLoopBodies(false) { }
41625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
42625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief Whether this compound stamement contains `for' or `while' loops
43625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// with empty bodies.
44625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  bool HasEmptyLoopBodies;
45625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
46625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  void setHasEmptyLoopBodies() {
47625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko    HasEmptyLoopBodies = true;
48625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  }
49625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko};
50625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
51351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekclass PossiblyUnreachableDiag {
52351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekpublic:
53351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  PartialDiagnostic PD;
54351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  SourceLocation Loc;
55351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  const Stmt *stmt;
56351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
57351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
58351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek                          const Stmt *stmt)
59351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek    : PD(PD), Loc(Loc), stmt(stmt) {}
60351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek};
61351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek
62781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a function, method, or block that is
63781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// currently being parsed.
64781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass FunctionScopeInfo {
65ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanprotected:
66ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  enum ScopeKind {
67ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Function,
68ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Block,
69ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    SK_Lambda
70ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  };
71ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
72781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
73ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief What kind of scope we are describing.
74ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  ///
75ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  ScopeKind Kind;
76781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
77809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett  /// \brief Whether this function contains a VLA, \@try, try, C++
78781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// initializer, or anything else that can't be jumped past.
79781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasBranchProtectedScope;
80781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
81781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Whether this function contains any switches or direct gotos.
82781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasBranchIntoScope;
83781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
84781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Whether this function contains any indirect gotos.
85781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool HasIndirectGoto;
86781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
878fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  /// \brief Used to determine if errors occurred in this function or block.
888fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  DiagnosticErrorTrap ErrorTrap;
89781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
90781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// SwitchStack - This is the current set of active switch statements in the
91781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block.
92686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<SwitchStmt*, 8> SwitchStack;
93781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
94781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief The list of return statements that occur within the function or
95781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block, if there is any chance of applying the named return value
96781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// optimization.
97686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<ReturnStmt*, 4> Returns;
98625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
99625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief The stack of currently active compound stamement scopes in the
100625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// function.
101625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
102625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
103351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// \brief A list of PartialDiagnostics created but delayed within the
104351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// current function scope.  These diagnostics are vetted for reachability
105351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// prior to being emitted.
106686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
107781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
108781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchIntoScope() {
109781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchIntoScope = true;
110781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
111781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
112781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchProtectedScope() {
113781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchProtectedScope = true;
114781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
115781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
116781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasIndirectGoto() {
117781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasIndirectGoto = true;
118781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
119781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
120781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool NeedsScopeChecking() const {
121781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    return HasIndirectGoto ||
122781472fe99a120098c631b0cbe33c89f8cef5e70John McCall          (HasBranchProtectedScope && HasBranchIntoScope);
123781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
124781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
125d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  FunctionScopeInfo(DiagnosticsEngine &Diag)
126ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    : Kind(SK_Function),
127781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchProtectedScope(false),
128781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchIntoScope(false),
129781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasIndirectGoto(false),
1308fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis      ErrorTrap(Diag) { }
131781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
132781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~FunctionScopeInfo();
133781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
134781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Clear out the information in this function scope, making it
135781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// suitable for reuse.
1368fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  void Clear();
137781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
138781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  static bool classof(const FunctionScopeInfo *FSI) { return true; }
139781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
140781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
141b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo {
142b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic:
143b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  enum ImplicitCaptureStyle {
144b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
145b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
146b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
147b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  ImplicitCaptureStyle ImpCaptureStyle;
148b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
149b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  class Capture {
150b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // There are two categories of capture: capturing 'this', and capturing
151b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // local variables.  There are three ways to capture a local variable:
152b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // capture by copy in the C++11 sense, capture by reference
153b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // in the C++11 sense, and __block capture.  Lambdas explicitly specify
154b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // capture by copy or capture by reference.  For blocks, __block capture
155b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // applies to variables with that annotation, variables of reference type
156b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // are captured by reference, and other variables are captured by copy.
157b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum CaptureKind {
158b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman      Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
159b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    };
160b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
161b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // The variable being captured (if we are not capturing 'this'),
162b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // and misc bits descibing the capture.
163b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
164b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
165b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // Expression to initialize a field of the given type, and whether this
166b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // is a nested capture; the expression is only required if we are
167b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // capturing ByVal and the variable's type has a non-trivial
168b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // copy constructor.
169b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
170b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
17193962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief The source location at which the first capture occurred..
17293962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation Loc;
17393962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
174a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief The location of the ellipsis that expands a parameter pack.
175a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation EllipsisLoc;
176a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
177999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief The type as it was captured, which is in effect the type of the
178999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// non-static data member that would hold the capture.
179999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType CaptureType;
180999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
181b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  public:
182b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
183999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            SourceLocation Loc, SourceLocation EllipsisLoc,
184999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
185b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman      : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
186999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
187999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        CaptureType(CaptureType){}
188b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
189b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum IsThisCapture { ThisCapture };
190999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    Capture(IsThisCapture, bool isNested, SourceLocation Loc,
191999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
192a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
193999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        EllipsisLoc(), CaptureType(CaptureType) { }
194b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
195b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
196b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isVariableCapture() const { return !isThisCapture(); }
197b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
198b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
199b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
200b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isNested() { return CopyExprAndNested.getInt(); }
201b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
202b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    VarDecl *getVariable() const {
203b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      return VarAndKind.getPointer();
204b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
20593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
20693962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief Retrieve the location at which this variable was captured.
20793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation getLocation() const { return Loc; }
20893962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
209a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief Retrieve the source location of the ellipsis, whose presence
210a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// indicates that the capture is a pack expansion.
211a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
212a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
213999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief Retrieve the capture type for this capture, which is effectively
214999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// the type of the non-static data member in the lambda/block structure
215999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// that would store this capture.
216999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType getCaptureType() const { return CaptureType; }
217999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
218b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    Expr *getCopyExpr() const {
219b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      return CopyExprAndNested.getPointer();
220b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
221b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
222b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
223b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
22484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
22584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman      HasImplicitReturnType(false)
226b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman     {}
227b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
228b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CaptureMap - A map of captured variables to (index+1) into Captures.
229b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
230b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
231b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
232b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// zero if 'this' is not captured.
233b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  unsigned CXXThisCaptureIndex;
234b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
235b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// Captures - The captures.
236b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  SmallVector<Capture, 4> Captures;
237b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
23884b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// \brief - Whether the target type of return statements in this context
23984b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// is deduced (e.g. a lambda or block with omitted return type).
24084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  bool HasImplicitReturnType;
24184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
24284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// ReturnType - The target type of return statements in this context,
24384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// or null if unknown.
24484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  QualType ReturnType;
24584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
246999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
247999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  SourceLocation Loc, SourceLocation EllipsisLoc,
248999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  QualType CaptureType, Expr *Cpy) {
249a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
250999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                               EllipsisLoc, CaptureType, Cpy));
251b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    CaptureMap[Var] = Captures.size();
252b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
253b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
254999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
255999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                      Expr *Cpy) {
256999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
257999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                               Cpy));
258b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    CXXThisCaptureIndex = Captures.size();
259b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
260b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
261a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the C++ 'this' is captured.
262a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
263a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
264a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
265a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCXXThisCapture() {
266a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCXXThisCaptured() && "this has not been captured");
267a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CXXThisCaptureIndex - 1];
268a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
269a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
270a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the given variable has been captured.
271a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCaptured(VarDecl *Var) const {
272b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman    return CaptureMap.count(Var);
273a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
274a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
275a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of the given variable, if it has been
276a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// captured already.
277a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCapture(VarDecl *Var) {
278a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCaptured(Var) && "Variable has not been captured");
279a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CaptureMap[Var] - 1];
280a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
281a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
282a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  const Capture &getCapture(VarDecl *Var) const {
283a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
284a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor      = CaptureMap.find(Var);
285a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(Known != CaptureMap.end() && "Variable has not been captured");
286a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[Known->second - 1];
287a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
288a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
289b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
290b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
291b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
292b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  static bool classof(const CapturingScopeInfo *BSI) { return true; }
293b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman};
294b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
295781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed.
296b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo {
297781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
298781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  BlockDecl *TheDecl;
299781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
300781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// TheScope - This is the scope for the block itself, which contains
301781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// arguments etc.
302781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  Scope *TheScope;
303781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
304781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// BlockType - The function type of the block, if one was given.
305781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// Its return type may be BuiltinType::Dependent.
306781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  QualType FunctionType;
307781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
308d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
309b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
310b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      TheScope(BlockScope)
311781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  {
312ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Block;
313781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
314781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
315781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~BlockScopeInfo();
316781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
317ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
318ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Block;
319ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
320781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  static bool classof(const BlockScopeInfo *BSI) { return true; }
321781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
322781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
323b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo {
324ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic:
325ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The class that describes the lambda.
326ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  CXXRecordDecl *Lambda;
32701d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
32876e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  /// \brief The class that describes the lambda.
32976e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  CXXMethodDecl *CallOperator;
33076e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor
33101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Source range covering the lambda introducer [...].
33201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  SourceRange IntroducerRange;
33301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
334ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The number of captures in the \c Captures list that are
335ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// explicit captures.
336ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  unsigned NumExplicitCaptures;
33772899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman
338503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether this is a mutable lambda.
339d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman  bool Mutable;
34001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
34101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Whether the (empty) parameter list is explicit.
34201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  bool ExplicitParams;
343d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman
344503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether any of the capture expressions requires cleanups.
345503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  bool ExprNeedsCleanups;
346503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
3479daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Variables used to index into by-copy array captures.
3489daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
3499daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
3509daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
3519daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// its list of array index variables.
3529daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
3539daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
35476e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
35576e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor                  CXXMethodDecl *CallOperator)
356b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
357503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
358503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor      ExprNeedsCleanups(false)
359ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  {
360ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Lambda;
361ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
362b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
363ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  virtual ~LambdaScopeInfo();
364b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
365a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Note when
366a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  void finishedExplicitCaptures() {
367a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    NumExplicitCaptures = Captures.size();
368a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
369a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
370ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
371ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Lambda;
372ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
373ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const LambdaScopeInfo *BSI) { return true; }
374ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
375ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman};
376ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
377781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}
378781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}
379781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
380781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif
381