• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 namespace clang {
23 
24 /// \brief Describes the capture of a variable or of \c this, or of a
25 /// C++1y init-capture.
26 class 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 
58 public:
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.
capturesThis()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.
capturesVariable()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.
capturesVLAType()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).
getCapturedVar()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).
isImplicit()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).
isExplicit()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.
getLocation()126   SourceLocation getLocation() const { return Loc; }
127 
128   /// \brief Determine whether this capture is a pack expansion,
129   /// which captures a function parameter pack.
isPackExpansion()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.
getEllipsisLoc()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