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 /// \brief 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 /// \brief Describes the capture of a variable or of \c this, or of a 25 /// C++1y init-capture. 26 class LambdaCapture { 27 enum { 28 /// \brief Flag used by the Capture class to indicate that the given 29 /// capture was implicit. 30 Capture_Implicit = 0x01, 31 32 /// \brief 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 /// \brief 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 /// \brief 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 /// \brief Determine the kind of capture. 79 LambdaCaptureKind getCaptureKind() const; 80 81 /// \brief Determine whether this capture handles the C++ \c this 82 /// pointer. capturesThis()83 bool capturesThis() const { 84 return DeclAndBits.getPointer() == nullptr && 85 (DeclAndBits.getInt() & Capture_This); 86 } 87 88 /// \brief Determine whether this capture handles a variable. capturesVariable()89 bool capturesVariable() const { 90 return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer()); 91 } 92 93 /// \brief Determine whether this captures a variable length array bound 94 /// expression. capturesVLAType()95 bool capturesVLAType() const { 96 return DeclAndBits.getPointer() == nullptr && 97 !(DeclAndBits.getInt() & Capture_This); 98 } 99 100 /// \brief 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). getCapturedVar()105 VarDecl *getCapturedVar() const { 106 assert(capturesVariable() && "No variable available for capture"); 107 return static_cast<VarDecl *>(DeclAndBits.getPointer()); 108 } 109 110 /// \brief Determine whether this was an implicit capture (not 111 /// written between the square brackets introducing the lambda). isImplicit()112 bool isImplicit() const { 113 return DeclAndBits.getInt() & Capture_Implicit; 114 } 115 116 /// \brief Determine whether this was an explicit capture (written 117 /// between the square brackets introducing the lambda). isExplicit()118 bool isExplicit() const { return !isImplicit(); } 119 120 /// \brief 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. getLocation()126 SourceLocation getLocation() const { return Loc; } 127 128 /// \brief Determine whether this capture is a pack expansion, 129 /// which captures a function parameter pack. isPackExpansion()130 bool isPackExpansion() const { return EllipsisLoc.isValid(); } 131 132 /// \brief Retrieve the location of the ellipsis for a capture 133 /// that is a pack expansion. getEllipsisLoc()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