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 | /// 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 | /// Describes the capture of a variable or of \c this, or of a |

25 | /// C++1y init-capture. |

26 | class LambdaCapture { |

27 | enum { |

28 | /// Flag used by the Capture class to indicate that the given |

29 | /// capture was implicit. |

30 | Capture_Implicit = 0x01, |

31 | |

32 | /// 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 | /// 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 | /// 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 | /// Determine the kind of capture. |

79 | LambdaCaptureKind getCaptureKind() const; |

80 | |

81 | /// Determine whether this capture handles the C++ \c this |

82 | /// pointer. |

83 | bool capturesThis() const { |

84 | return DeclAndBits.getPointer() == nullptr && |

85 | (DeclAndBits.getInt() & Capture_This); |

86 | } |

87 | |

88 | /// Determine whether this capture handles a variable. |

89 | bool capturesVariable() const { |

90 | return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer()); |

91 | } |

92 | |

93 | /// Determine whether this captures a variable length array bound |

94 | /// expression. |

95 | bool capturesVLAType() const { |

96 | return DeclAndBits.getPointer() == nullptr && |

97 | !(DeclAndBits.getInt() & Capture_This); |

98 | } |

99 | |

100 | /// 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). |

105 | VarDecl *getCapturedVar() const { |

106 | assert(capturesVariable() && "No variable available for capture"); |

107 | return static_cast<VarDecl *>(DeclAndBits.getPointer()); |

108 | } |

109 | |

110 | /// Determine whether this was an implicit capture (not |

111 | /// written between the square brackets introducing the lambda). |

112 | bool isImplicit() const { |

113 | return DeclAndBits.getInt() & Capture_Implicit; |

114 | } |

115 | |

116 | /// Determine whether this was an explicit capture (written |

117 | /// between the square brackets introducing the lambda). |

118 | bool isExplicit() const { return !isImplicit(); } |

119 | |

120 | /// 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. |

126 | SourceLocation getLocation() const { return Loc; } |

127 | |

128 | /// Determine whether this capture is a pack expansion, |

129 | /// which captures a function parameter pack. |

130 | bool isPackExpansion() const { return EllipsisLoc.isValid(); } |

131 | |

132 | /// Retrieve the location of the ellipsis for a capture |

133 | /// that is a pack expansion. |

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 |