1//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Defines the LambdaCapture class.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H
16#define LLVM_CLANG_AST_LAMBDACAPTURE_H
17
18#include "clang/AST/Decl.h"
19#include "clang/Basic/Lambda.h"
20#include "llvm/ADT/PointerIntPair.h"
21
22namespace clang {
23
24/// \brief Describes the capture of a variable or of \c this, or of a
25/// C++1y init-capture.
26class LambdaCapture {
27  enum {
28    /// \brief Flag used by the Capture class to indicate that the given
29    /// capture was implicit.
30    Capture_Implicit = 0x01,
31
32    /// \brief Flag used by the Capture class to indicate that the
33    /// given capture was by-copy.
34    ///
35    /// This includes the case of a non-reference init-capture.
36    Capture_ByCopy = 0x02,
37
38    /// \brief Flag used by the Capture class to distinguish between a capture
39    /// of '*this' and a capture of a VLA type.
40    Capture_This = 0x04
41  };
42
43  // Decl could represent:
44  // - a VarDecl* that represents the variable that was captured or the
45  //   init-capture.
46  // - or, is a nullptr and Capture_This is set in Bits if this represents a
47  //   capture of '*this' by value or reference.
48  // - or, is a nullptr and Capture_This is not set in Bits if this represents
49  //   a capture of a VLA type.
50  llvm::PointerIntPair<Decl*, 3> DeclAndBits;
51
52  SourceLocation Loc;
53  SourceLocation EllipsisLoc;
54
55  friend class ASTStmtReader;
56  friend class ASTStmtWriter;
57
58public:
59  /// \brief Create a new capture of a variable or of \c this.
60  ///
61  /// \param Loc The source location associated with this capture.
62  ///
63  /// \param Kind The kind of capture (this, byref, bycopy), which must
64  /// not be init-capture.
65  ///
66  /// \param Implicit Whether the capture was implicit or explicit.
67  ///
68  /// \param Var The local variable being captured, or null if capturing
69  /// \c this.
70  ///
71  /// \param EllipsisLoc The location of the ellipsis (...) for a
72  /// capture that is a pack expansion, or an invalid source
73  /// location to indicate that this is not a pack expansion.
74  LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
75                VarDecl *Var = nullptr,
76                SourceLocation EllipsisLoc = SourceLocation());
77
78  /// \brief Determine the kind of capture.
79  LambdaCaptureKind getCaptureKind() const;
80
81  /// \brief Determine whether this capture handles the C++ \c this
82  /// pointer.
83  bool capturesThis() const {
84    return DeclAndBits.getPointer() == nullptr &&
85          (DeclAndBits.getInt() & Capture_This);
86  }
87
88  /// \brief Determine whether this capture handles a variable.
89  bool capturesVariable() const {
90    return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
91  }
92
93  /// \brief Determine whether this captures a variable length array bound
94  /// expression.
95  bool capturesVLAType() const {
96    return DeclAndBits.getPointer() == nullptr &&
97           !(DeclAndBits.getInt() & Capture_This);
98  }
99
100  /// \brief Retrieve the declaration of the local variable being
101  /// captured.
102  ///
103  /// This operation is only valid if this capture is a variable capture
104  /// (other than a capture of \c this).
105  VarDecl *getCapturedVar() const {
106    assert(capturesVariable() && "No variable available for capture");
107    return static_cast<VarDecl *>(DeclAndBits.getPointer());
108  }
109
110  /// \brief Determine whether this was an implicit capture (not
111  /// written between the square brackets introducing the lambda).
112  bool isImplicit() const {
113    return DeclAndBits.getInt() & Capture_Implicit;
114  }
115
116  /// \brief Determine whether this was an explicit capture (written
117  /// between the square brackets introducing the lambda).
118  bool isExplicit() const { return !isImplicit(); }
119
120  /// \brief Retrieve the source location of the capture.
121  ///
122  /// For an explicit capture, this returns the location of the
123  /// explicit capture in the source. For an implicit capture, this
124  /// returns the location at which the variable or \c this was first
125  /// used.
126  SourceLocation getLocation() const { return Loc; }
127
128  /// \brief Determine whether this capture is a pack expansion,
129  /// which captures a function parameter pack.
130  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
131
132  /// \brief Retrieve the location of the ellipsis for a capture
133  /// that is a pack expansion.
134  SourceLocation getEllipsisLoc() const {
135    assert(isPackExpansion() && "No ellipsis location for a non-expansion");
136    return EllipsisLoc;
137  }
138};
139
140} // end namespace clang
141
142#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
143