/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/LambdaCapture.h
Line | Count | Source (jump to first uncovered line) |
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 | 8.70k | bool capturesThis() const { |
83 | 8.70k | return DeclAndBits.getPointer() == nullptr && |
84 | 8.70k | (DeclAndBits.getInt() & Capture_This)1.23k ; |
85 | 8.70k | } |
86 | | |
87 | | /// Determine whether this capture handles a variable. |
88 | 19.8k | bool capturesVariable() const { |
89 | 19.8k | return isa_and_nonnull<VarDecl>(DeclAndBits.getPointer()); |
90 | 19.8k | } |
91 | | |
92 | | /// Determine whether this captures a variable length array bound |
93 | | /// expression. |
94 | 4.48k | bool capturesVLAType() const { |
95 | 4.48k | return DeclAndBits.getPointer() == nullptr && |
96 | 4.48k | !(DeclAndBits.getInt() & Capture_This)594 ; |
97 | 4.48k | } |
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 | 8.39k | VarDecl *getCapturedVar() const { |
105 | 8.39k | assert(capturesVariable() && "No variable available for capture"); |
106 | 0 | return static_cast<VarDecl *>(DeclAndBits.getPointer()); |
107 | 8.39k | } |
108 | | |
109 | | /// Determine whether this was an implicit capture (not |
110 | | /// written between the square brackets introducing the lambda). |
111 | 9.04k | bool isImplicit() const { |
112 | 9.04k | return DeclAndBits.getInt() & Capture_Implicit; |
113 | 9.04k | } |
114 | | |
115 | | /// Determine whether this was an explicit capture (written |
116 | | /// between the square brackets introducing the lambda). |
117 | 7.06k | 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 | 2.76k | SourceLocation getLocation() const { return Loc; } |
126 | | |
127 | | /// Determine whether this capture is a pack expansion, |
128 | | /// which captures a function parameter pack. |
129 | 2.05k | bool isPackExpansion() const { return EllipsisLoc.isValid(); } |
130 | | |
131 | | /// Retrieve the location of the ellipsis for a capture |
132 | | /// that is a pack expansion. |
133 | 72 | SourceLocation getEllipsisLoc() const { |
134 | 72 | assert(isPackExpansion() && "No ellipsis location for a non-expansion"); |
135 | 0 | return EllipsisLoc; |
136 | 72 | } |
137 | | }; |
138 | | |
139 | | } // end namespace clang |
140 | | |
141 | | #endif // LLVM_CLANG_AST_LAMBDACAPTURE_H |