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 Retrieve the declaration of the local variable being 89 /// captured. 90 /// 91 /// This operation is only valid if this capture is a variable capture 92 /// (other than a capture of \c this). getCapturedVar()93 VarDecl *getCapturedVar() const { 94 assert(capturesVariable() && "No variable available for 'this' capture"); 95 return cast<VarDecl>(DeclAndBits.getPointer()); 96 } 97 98 /// \brief Determine whether this was an implicit capture (not 99 /// written between the square brackets introducing the lambda). isImplicit()100 bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; } 101 102 /// \brief Determine whether this was an explicit capture (written 103 /// between the square brackets introducing the lambda). isExplicit()104 bool isExplicit() const { return !isImplicit(); } 105 106 /// \brief Retrieve the source location of the capture. 107 /// 108 /// For an explicit capture, this returns the location of the 109 /// explicit capture in the source. For an implicit capture, this 110 /// returns the location at which the variable or \c this was first 111 /// used. getLocation()112 SourceLocation getLocation() const { return Loc; } 113 114 /// \brief Determine whether this capture is a pack expansion, 115 /// which captures a function parameter pack. isPackExpansion()116 bool isPackExpansion() const { return EllipsisLoc.isValid(); } 117 118 /// \brief Retrieve the location of the ellipsis for a capture 119 /// that is a pack expansion. getEllipsisLoc()120 SourceLocation getEllipsisLoc() const { 121 assert(isPackExpansion() && "No ellipsis location for a non-expansion"); 122 return EllipsisLoc; 123 } 124 }; 125 126 } // end namespace clang 127 128 #endif // LLVM_CLANG_AST_LAMBDACAPTURE_H 129