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