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
8795aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  /// A flag that is set when parsing a -dealloc method and no [super dealloc]
8895aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  /// call was found yet.
8995aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  bool ObjCShouldCallSuperDealloc;
9095aac15936e8362aeb4813f95bc255dee6473592Eli Friedman
9195aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  /// A flag that is set when parsing a -finalize method and no [super finalize]
9295aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  /// call was found yet.
9395aac15936e8362aeb4813f95bc255dee6473592Eli Friedman  bool ObjCShouldCallSuperFinalize;
9495aac15936e8362aeb4813f95bc255dee6473592Eli Friedman
958fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  /// \brief Used to determine if errors occurred in this function or block.
968fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  DiagnosticErrorTrap ErrorTrap;
97781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
98781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// SwitchStack - This is the current set of active switch statements in the
99781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block.
100686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<SwitchStmt*, 8> SwitchStack;
101781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
102781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief The list of return statements that occur within the function or
103781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// block, if there is any chance of applying the named return value
1047dd900ed308506f9cf1cb72c70db1652f94cab37Jordan Rose  /// optimization, or if we need to infer a return type.
105686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<ReturnStmt*, 4> Returns;
106625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
107625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// \brief The stack of currently active compound stamement scopes in the
108625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  /// function.
109625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
110625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko
111351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// \brief A list of PartialDiagnostics created but delayed within the
112351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// current function scope.  These diagnostics are vetted for reachability
113351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek  /// prior to being emitted.
114686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
115781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
116781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchIntoScope() {
117781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchIntoScope = true;
118781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
119781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
120781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasBranchProtectedScope() {
121781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasBranchProtectedScope = true;
122781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
123781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
124781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  void setHasIndirectGoto() {
125781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    HasIndirectGoto = true;
126781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
127781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
128781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  bool NeedsScopeChecking() const {
129781472fe99a120098c631b0cbe33c89f8cef5e70John McCall    return HasIndirectGoto ||
130781472fe99a120098c631b0cbe33c89f8cef5e70John McCall          (HasBranchProtectedScope && HasBranchIntoScope);
131781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
132781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
133d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  FunctionScopeInfo(DiagnosticsEngine &Diag)
134ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    : Kind(SK_Function),
135781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchProtectedScope(false),
136781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasBranchIntoScope(false),
137781472fe99a120098c631b0cbe33c89f8cef5e70John McCall      HasIndirectGoto(false),
13895aac15936e8362aeb4813f95bc255dee6473592Eli Friedman      ObjCShouldCallSuperDealloc(false),
13995aac15936e8362aeb4813f95bc255dee6473592Eli Friedman      ObjCShouldCallSuperFinalize(false),
1408fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis      ErrorTrap(Diag) { }
141781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
142781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~FunctionScopeInfo();
143781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
144781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// \brief Clear out the information in this function scope, making it
145781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// suitable for reuse.
1468fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis  void Clear();
147781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
148781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  static bool classof(const FunctionScopeInfo *FSI) { return true; }
149781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
150781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
151b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo {
152b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic:
153b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  enum ImplicitCaptureStyle {
154b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
155b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
156b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
157b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  ImplicitCaptureStyle ImpCaptureStyle;
158b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
159b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  class Capture {
160b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // There are two categories of capture: capturing 'this', and capturing
161b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // local variables.  There are three ways to capture a local variable:
162b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // capture by copy in the C++11 sense, capture by reference
163b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // in the C++11 sense, and __block capture.  Lambdas explicitly specify
164b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // capture by copy or capture by reference.  For blocks, __block capture
165b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // applies to variables with that annotation, variables of reference type
166b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    // are captured by reference, and other variables are captured by copy.
167b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum CaptureKind {
168b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman      Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
169b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    };
170b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
171b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // The variable being captured (if we are not capturing 'this'),
172b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // and misc bits descibing the capture.
173b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
174b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
175b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // Expression to initialize a field of the given type, and whether this
176b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // is a nested capture; the expression is only required if we are
177b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // capturing ByVal and the variable's type has a non-trivial
178b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    // copy constructor.
179b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
180b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
18193962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief The source location at which the first capture occurred..
18293962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation Loc;
18393962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
184a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief The location of the ellipsis that expands a parameter pack.
185a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation EllipsisLoc;
186a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
187999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief The type as it was captured, which is in effect the type of the
188999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// non-static data member that would hold the capture.
189999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType CaptureType;
190999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
191b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  public:
192b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
193999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            SourceLocation Loc, SourceLocation EllipsisLoc,
194999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
195b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman      : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
196999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
197999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        CaptureType(CaptureType){}
198b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
199b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    enum IsThisCapture { ThisCapture };
200999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    Capture(IsThisCapture, bool isNested, SourceLocation Loc,
201999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor            QualType CaptureType, Expr *Cpy)
202a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
203999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor        EllipsisLoc(), CaptureType(CaptureType) { }
204b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
205b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
206b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isVariableCapture() const { return !isThisCapture(); }
207b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
208b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
209b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman    bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
210b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    bool isNested() { return CopyExprAndNested.getInt(); }
211b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
212b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    VarDecl *getVariable() const {
213b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      return VarAndKind.getPointer();
214b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
21593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
21693962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    /// \brief Retrieve the location at which this variable was captured.
21793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor    SourceLocation getLocation() const { return Loc; }
21893962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor
219a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// \brief Retrieve the source location of the ellipsis, whose presence
220a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    /// indicates that the capture is a pack expansion.
221a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
222a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor
223999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// \brief Retrieve the capture type for this capture, which is effectively
224999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// the type of the non-static data member in the lambda/block structure
225999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    /// that would store this capture.
226999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    QualType getCaptureType() const { return CaptureType; }
227999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor
228b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    Expr *getCopyExpr() const {
229b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      return CopyExprAndNested.getPointer();
230b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    }
231b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  };
232b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
233b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
23484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
23584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman      HasImplicitReturnType(false)
236b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman     {}
237b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
238b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CaptureMap - A map of captured variables to (index+1) into Captures.
239b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
240b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
241b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
242b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// zero if 'this' is not captured.
243b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  unsigned CXXThisCaptureIndex;
244b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
245b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  /// Captures - The captures.
246b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  SmallVector<Capture, 4> Captures;
247b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
24884b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// \brief - Whether the target type of return statements in this context
24984b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// is deduced (e.g. a lambda or block with omitted return type).
25084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  bool HasImplicitReturnType;
25184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
25284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// ReturnType - The target type of return statements in this context,
25384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  /// or null if unknown.
25484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman  QualType ReturnType;
25584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman
256999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
257999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  SourceLocation Loc, SourceLocation EllipsisLoc,
258999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                  QualType CaptureType, Expr *Cpy) {
259a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
260999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                               EllipsisLoc, CaptureType, Cpy));
261b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    CaptureMap[Var] = Captures.size();
262b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
263b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
264999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
265999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                      Expr *Cpy) {
266999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor    Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
267999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor                               Cpy));
268b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    CXXThisCaptureIndex = Captures.size();
269b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
270b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
271a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the C++ 'this' is captured.
272a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
273a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
274a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
275a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCXXThisCapture() {
276a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCXXThisCaptured() && "this has not been captured");
277a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CXXThisCaptureIndex - 1];
278a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
279a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
280a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Determine whether the given variable has been captured.
281a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  bool isCaptured(VarDecl *Var) const {
282b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman    return CaptureMap.count(Var);
283a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
284a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
285a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Retrieve the capture of the given variable, if it has been
286a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// captured already.
287a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  Capture &getCapture(VarDecl *Var) {
288a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(isCaptured(Var) && "Variable has not been captured");
289a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[CaptureMap[Var] - 1];
290a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
291a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
292a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  const Capture &getCapture(VarDecl *Var) const {
293a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
294a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor      = CaptureMap.find(Var);
295a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    assert(Known != CaptureMap.end() && "Variable has not been captured");
296a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    return Captures[Known->second - 1];
297a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
298a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
299b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
300b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
301b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  }
302b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman  static bool classof(const CapturingScopeInfo *BSI) { return true; }
303b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman};
304b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
305781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed.
306b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo {
307781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic:
308781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  BlockDecl *TheDecl;
309781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
310781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// TheScope - This is the scope for the block itself, which contains
311781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// arguments etc.
312781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  Scope *TheScope;
313781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
314781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// BlockType - The function type of the block, if one was given.
315781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  /// Its return type may be BuiltinType::Dependent.
316781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  QualType FunctionType;
317781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
318d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
319b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
320b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman      TheScope(BlockScope)
321781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  {
322ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Block;
323781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  }
324781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
325781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  virtual ~BlockScopeInfo();
326781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
327ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
328ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Block;
329ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
330781472fe99a120098c631b0cbe33c89f8cef5e70John McCall  static bool classof(const BlockScopeInfo *BSI) { return true; }
331781472fe99a120098c631b0cbe33c89f8cef5e70John McCall};
332781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
333b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo {
334ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic:
335ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The class that describes the lambda.
336ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  CXXRecordDecl *Lambda;
33701d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
33876e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  /// \brief The class that describes the lambda.
33976e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  CXXMethodDecl *CallOperator;
34076e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor
34101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Source range covering the lambda introducer [...].
34201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  SourceRange IntroducerRange;
34301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
344ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// \brief The number of captures in the \c Captures list that are
345ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  /// explicit captures.
346ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  unsigned NumExplicitCaptures;
34772899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman
348503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether this is a mutable lambda.
349d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman  bool Mutable;
35001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
35101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  /// \brief Whether the (empty) parameter list is explicit.
35201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  bool ExplicitParams;
353d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman
354503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  /// \brief Whether any of the capture expressions requires cleanups.
355503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor  bool ExprNeedsCleanups;
356503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor
357612409ece080e814f79e06772c690d603f45fbd6Richard Smith  /// \brief Whether the lambda contains an unexpanded parameter pack.
358612409ece080e814f79e06772c690d603f45fbd6Richard Smith  bool ContainsUnexpandedParameterPack;
359612409ece080e814f79e06772c690d603f45fbd6Richard Smith
3609daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Variables used to index into by-copy array captures.
3619daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
3629daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
3639daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
3649daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  /// its list of array index variables.
3659daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor  llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
3669daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor
36776e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
36876e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor                  CXXMethodDecl *CallOperator)
369b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
370503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
371612409ece080e814f79e06772c690d603f45fbd6Richard Smith      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
372ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  {
373ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    Kind = SK_Lambda;
374ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
375b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
376ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  virtual ~LambdaScopeInfo();
377b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman
378a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  /// \brief Note when
379a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  void finishedExplicitCaptures() {
380a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor    NumExplicitCaptures = Captures.size();
381a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor  }
382a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor
383ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const FunctionScopeInfo *FSI) {
384ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman    return FSI->Kind == SK_Lambda;
385ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  }
386ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman  static bool classof(const LambdaScopeInfo *BSI) { return true; }
387ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
388ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman};
389ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman
390781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}
391781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}
392781472fe99a120098c631b0cbe33c89f8cef5e70John McCall
393781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif
394