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 |

142 |