1e5dd7070Spatrick //===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===// 2e5dd7070Spatrick // 3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information. 5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e5dd7070Spatrick // 7e5dd7070Spatrick //===----------------------------------------------------------------------===// 8e5dd7070Spatrick /// 9e5dd7070Spatrick /// \file 10e5dd7070Spatrick /// Defines the LambdaCapture class. 11e5dd7070Spatrick /// 12e5dd7070Spatrick //===----------------------------------------------------------------------===// 13e5dd7070Spatrick 14e5dd7070Spatrick #ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H 15e5dd7070Spatrick #define LLVM_CLANG_AST_LAMBDACAPTURE_H 16e5dd7070Spatrick 17e5dd7070Spatrick #include "clang/AST/Decl.h" 18e5dd7070Spatrick #include "clang/Basic/Lambda.h" 19e5dd7070Spatrick #include "llvm/ADT/PointerIntPair.h" 20e5dd7070Spatrick 21e5dd7070Spatrick namespace clang { 22e5dd7070Spatrick 23e5dd7070Spatrick /// Describes the capture of a variable or of \c this, or of a 24e5dd7070Spatrick /// C++1y init-capture. 25e5dd7070Spatrick class LambdaCapture { 26e5dd7070Spatrick enum { 27e5dd7070Spatrick /// Flag used by the Capture class to indicate that the given 28e5dd7070Spatrick /// capture was implicit. 29e5dd7070Spatrick Capture_Implicit = 0x01, 30e5dd7070Spatrick 31e5dd7070Spatrick /// Flag used by the Capture class to indicate that the 32e5dd7070Spatrick /// given capture was by-copy. 33e5dd7070Spatrick /// 34e5dd7070Spatrick /// This includes the case of a non-reference init-capture. 35e5dd7070Spatrick Capture_ByCopy = 0x02, 36e5dd7070Spatrick 37e5dd7070Spatrick /// Flag used by the Capture class to distinguish between a capture 38e5dd7070Spatrick /// of '*this' and a capture of a VLA type. 39e5dd7070Spatrick Capture_This = 0x04 40e5dd7070Spatrick }; 41e5dd7070Spatrick 42e5dd7070Spatrick // Decl could represent: 43e5dd7070Spatrick // - a VarDecl* that represents the variable that was captured or the 44e5dd7070Spatrick // init-capture. 45e5dd7070Spatrick // - or, is a nullptr and Capture_This is set in Bits if this represents a 46e5dd7070Spatrick // capture of '*this' by value or reference. 47e5dd7070Spatrick // - or, is a nullptr and Capture_This is not set in Bits if this represents 48e5dd7070Spatrick // a capture of a VLA type. 49e5dd7070Spatrick llvm::PointerIntPair<Decl*, 3> DeclAndBits; 50e5dd7070Spatrick 51e5dd7070Spatrick SourceLocation Loc; 52e5dd7070Spatrick SourceLocation EllipsisLoc; 53e5dd7070Spatrick 54e5dd7070Spatrick friend class ASTStmtReader; 55e5dd7070Spatrick friend class ASTStmtWriter; 56e5dd7070Spatrick 57e5dd7070Spatrick public: 58e5dd7070Spatrick /// Create a new capture of a variable or of \c this. 59e5dd7070Spatrick /// 60e5dd7070Spatrick /// \param Loc The source location associated with this capture. 61e5dd7070Spatrick /// 62e5dd7070Spatrick /// \param Kind The kind of capture (this, byref, bycopy), which must 63e5dd7070Spatrick /// not be init-capture. 64e5dd7070Spatrick /// 65e5dd7070Spatrick /// \param Implicit Whether the capture was implicit or explicit. 66e5dd7070Spatrick /// 67e5dd7070Spatrick /// \param Var The local variable being captured, or null if capturing 68e5dd7070Spatrick /// \c this. 69e5dd7070Spatrick /// 70e5dd7070Spatrick /// \param EllipsisLoc The location of the ellipsis (...) for a 71e5dd7070Spatrick /// capture that is a pack expansion, or an invalid source 72e5dd7070Spatrick /// location to indicate that this is not a pack expansion. 73e5dd7070Spatrick LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind, 74*12c85518Srobert ValueDecl *Var = nullptr, 75e5dd7070Spatrick SourceLocation EllipsisLoc = SourceLocation()); 76e5dd7070Spatrick 77e5dd7070Spatrick /// Determine the kind of capture. 78e5dd7070Spatrick LambdaCaptureKind getCaptureKind() const; 79e5dd7070Spatrick 80e5dd7070Spatrick /// Determine whether this capture handles the C++ \c this 81e5dd7070Spatrick /// pointer. capturesThis()82e5dd7070Spatrick bool capturesThis() const { 83e5dd7070Spatrick return DeclAndBits.getPointer() == nullptr && 84e5dd7070Spatrick (DeclAndBits.getInt() & Capture_This); 85e5dd7070Spatrick } 86e5dd7070Spatrick 87e5dd7070Spatrick /// Determine whether this capture handles a variable. capturesVariable()88e5dd7070Spatrick bool capturesVariable() const { 89*12c85518Srobert return isa_and_nonnull<ValueDecl>(DeclAndBits.getPointer()); 90e5dd7070Spatrick } 91e5dd7070Spatrick 92e5dd7070Spatrick /// Determine whether this captures a variable length array bound 93e5dd7070Spatrick /// expression. capturesVLAType()94e5dd7070Spatrick bool capturesVLAType() const { 95e5dd7070Spatrick return DeclAndBits.getPointer() == nullptr && 96e5dd7070Spatrick !(DeclAndBits.getInt() & Capture_This); 97e5dd7070Spatrick } 98e5dd7070Spatrick 99e5dd7070Spatrick /// Retrieve the declaration of the local variable being 100e5dd7070Spatrick /// captured. 101e5dd7070Spatrick /// 102e5dd7070Spatrick /// This operation is only valid if this capture is a variable capture 103e5dd7070Spatrick /// (other than a capture of \c this). getCapturedVar()104*12c85518Srobert ValueDecl *getCapturedVar() const { 105e5dd7070Spatrick assert(capturesVariable() && "No variable available for capture"); 106*12c85518Srobert return static_cast<ValueDecl *>(DeclAndBits.getPointer()); 107e5dd7070Spatrick } 108e5dd7070Spatrick 109e5dd7070Spatrick /// Determine whether this was an implicit capture (not 110e5dd7070Spatrick /// written between the square brackets introducing the lambda). isImplicit()111e5dd7070Spatrick bool isImplicit() const { 112e5dd7070Spatrick return DeclAndBits.getInt() & Capture_Implicit; 113e5dd7070Spatrick } 114e5dd7070Spatrick 115e5dd7070Spatrick /// Determine whether this was an explicit capture (written 116e5dd7070Spatrick /// between the square brackets introducing the lambda). isExplicit()117e5dd7070Spatrick bool isExplicit() const { return !isImplicit(); } 118e5dd7070Spatrick 119e5dd7070Spatrick /// Retrieve the source location of the capture. 120e5dd7070Spatrick /// 121e5dd7070Spatrick /// For an explicit capture, this returns the location of the 122e5dd7070Spatrick /// explicit capture in the source. For an implicit capture, this 123e5dd7070Spatrick /// returns the location at which the variable or \c this was first 124e5dd7070Spatrick /// used. getLocation()125e5dd7070Spatrick SourceLocation getLocation() const { return Loc; } 126e5dd7070Spatrick 127e5dd7070Spatrick /// Determine whether this capture is a pack expansion, 128e5dd7070Spatrick /// which captures a function parameter pack. isPackExpansion()129e5dd7070Spatrick bool isPackExpansion() const { return EllipsisLoc.isValid(); } 130e5dd7070Spatrick 131e5dd7070Spatrick /// Retrieve the location of the ellipsis for a capture 132e5dd7070Spatrick /// that is a pack expansion. getEllipsisLoc()133e5dd7070Spatrick SourceLocation getEllipsisLoc() const { 134e5dd7070Spatrick assert(isPackExpansion() && "No ellipsis location for a non-expansion"); 135e5dd7070Spatrick return EllipsisLoc; 136e5dd7070Spatrick } 137e5dd7070Spatrick }; 138e5dd7070Spatrick 139e5dd7070Spatrick } // end namespace clang 140e5dd7070Spatrick 141e5dd7070Spatrick #endif // LLVM_CLANG_AST_LAMBDACAPTURE_H 142