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