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 39 llvm::PointerIntPair<Decl *, 2> DeclAndBits; 40 SourceLocation Loc; 41 SourceLocation EllipsisLoc; 42 43 friend class ASTStmtReader; 44 friend class ASTStmtWriter; 45 46 public: 47 /// \brief Create a new capture of a variable or of \c this. 48 /// 49 /// \param Loc The source location associated with this capture. 50 /// 51 /// \param Kind The kind of capture (this, byref, bycopy), which must 52 /// not be init-capture. 53 /// 54 /// \param Implicit Whether the capture was implicit or explicit. 55 /// 56 /// \param Var The local variable being captured, or null if capturing 57 /// \c this. 58 /// 59 /// \param EllipsisLoc The location of the ellipsis (...) for a 60 /// capture that is a pack expansion, or an invalid source 61 /// location to indicate that this is not a pack expansion. 62 LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind, 63 VarDecl *Var = nullptr, 64 SourceLocation EllipsisLoc = SourceLocation()); 65 66 /// \brief Determine the kind of capture. 67 LambdaCaptureKind getCaptureKind() const; 68 69 /// \brief Determine whether this capture handles the C++ \c this 70 /// pointer. capturesThis()71 bool capturesThis() const { 72 return (DeclAndBits.getPointer() == nullptr) && 73 !(DeclAndBits.getInt() & Capture_ByCopy); 74 } 75 76 /// \brief Determine whether this capture handles a variable. capturesVariable()77 bool capturesVariable() const { 78 return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer()); 79 } 80 81 /// \brief Determine whether this captures a variable length array bound 82 /// expression. capturesVLAType()83 bool capturesVLAType() const { 84 return (DeclAndBits.getPointer() == nullptr) && 85 (DeclAndBits.getInt() & Capture_ByCopy); 86 } 87 88 /// \brief Determine whether this is an init-capture. isInitCapture()89 bool isInitCapture() const { 90 return capturesVariable() && getCapturedVar()->isInitCapture(); 91 } 92 93 /// \brief Retrieve the declaration of the local variable being 94 /// captured. 95 /// 96 /// This operation is only valid if this capture is a variable capture 97 /// (other than a capture of \c this). getCapturedVar()98 VarDecl *getCapturedVar() const { 99 assert(capturesVariable() && "No variable available for 'this' capture"); 100 return cast<VarDecl>(DeclAndBits.getPointer()); 101 } 102 103 /// \brief Determine whether this was an implicit capture (not 104 /// written between the square brackets introducing the lambda). isImplicit()105 bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; } 106 107 /// \brief Determine whether this was an explicit capture (written 108 /// between the square brackets introducing the lambda). isExplicit()109 bool isExplicit() const { return !isImplicit(); } 110 111 /// \brief Retrieve the source location of the capture. 112 /// 113 /// For an explicit capture, this returns the location of the 114 /// explicit capture in the source. For an implicit capture, this 115 /// returns the location at which the variable or \c this was first 116 /// used. getLocation()117 SourceLocation getLocation() const { return Loc; } 118 119 /// \brief Determine whether this capture is a pack expansion, 120 /// which captures a function parameter pack. isPackExpansion()121 bool isPackExpansion() const { return EllipsisLoc.isValid(); } 122 123 /// \brief Retrieve the location of the ellipsis for a capture 124 /// that is a pack expansion. getEllipsisLoc()125 SourceLocation getEllipsisLoc() const { 126 assert(isPackExpansion() && "No ellipsis location for a non-expansion"); 127 return EllipsisLoc; 128 } 129 }; 130 131 } // end namespace clang 132 133 #endif // LLVM_CLANG_AST_LAMBDACAPTURE_H 134