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