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 ValueDecl *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. capturesThis()82 bool capturesThis() const { 83 return DeclAndBits.getPointer() == nullptr && 84 (DeclAndBits.getInt() & Capture_This); 85 } 86 87 /// Determine whether this capture handles a variable. capturesVariable()88 bool capturesVariable() const { 89 return isa_and_nonnull<ValueDecl>(DeclAndBits.getPointer()); 90 } 91 92 /// Determine whether this captures a variable length array bound 93 /// expression. capturesVLAType()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). getCapturedVar()104 ValueDecl *getCapturedVar() const { 105 assert(capturesVariable() && "No variable available for capture"); 106 return static_cast<ValueDecl *>(DeclAndBits.getPointer()); 107 } 108 109 /// Determine whether this was an implicit capture (not 110 /// written between the square brackets introducing the lambda). isImplicit()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). isExplicit()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. getLocation()125 SourceLocation getLocation() const { return Loc; } 126 127 /// Determine whether this capture is a pack expansion, 128 /// which captures a function parameter pack. isPackExpansion()129 bool isPackExpansion() const { return EllipsisLoc.isValid(); } 130 131 /// Retrieve the location of the ellipsis for a capture 132 /// that is a pack expansion. getEllipsisLoc()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