16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===//
26bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
36bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//                     The LLVM Compiler Infrastructure
46bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
56bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This file is distributed under the University of Illinois Open Source
66bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// License. See LICENSE.TXT for details.
76bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//
86bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===//
96bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines///
106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \file
116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Defines the LambdaCapture class.
126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines///
136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===//
146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H
166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define LLVM_CLANG_AST_LAMBDACAPTURE_H
176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/AST/Decl.h"
196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/Basic/Lambda.h"
206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/PointerIntPair.h"
216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace clang {
236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Describes the capture of a variable or of \c this, or of a
256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// C++1y init-capture.
266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass LambdaCapture {
276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  enum {
286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    /// \brief Flag used by the Capture class to indicate that the given
296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    /// capture was implicit.
306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Capture_Implicit = 0x01,
316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    /// \brief Flag used by the Capture class to indicate that the
336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    /// given capture was by-copy.
346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ///
356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    /// This includes the case of a non-reference init-capture.
366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Capture_ByCopy = 0x02
376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  };
386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  llvm::PointerIntPair<Decl *, 2> DeclAndBits;
406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceLocation Loc;
416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceLocation EllipsisLoc;
426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  friend class ASTStmtReader;
446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  friend class ASTStmtWriter;
456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic:
476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Create a new capture of a variable or of \c this.
486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param Loc The source location associated with this capture.
506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param Kind The kind of capture (this, byref, bycopy), which must
526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// not be init-capture.
536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param Implicit Whether the capture was implicit or explicit.
556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param Var The local variable being captured, or null if capturing
576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \c this.
586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \param EllipsisLoc The location of the ellipsis (...) for a
606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// capture that is a pack expansion, or an invalid source
616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// location to indicate that this is not a pack expansion.
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                VarDecl *Var = nullptr,
646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                SourceLocation EllipsisLoc = SourceLocation());
656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine the kind of capture.
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  LambdaCaptureKind getCaptureKind() const;
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this capture handles the C++ \c this
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// pointer.
71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  bool capturesThis() const {
72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return (DeclAndBits.getPointer() == nullptr) &&
73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines           !(DeclAndBits.getInt() & Capture_ByCopy);
74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this capture handles a variable.
776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool capturesVariable() const {
786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Determine whether this captures a variable length array bound
82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// expression.
83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  bool capturesVLAType() const {
84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return (DeclAndBits.getPointer() == nullptr) &&
85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines           (DeclAndBits.getInt() & Capture_ByCopy);
86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this is an init-capture.
896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isInitCapture() const {
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return capturesVariable() && getCapturedVar()->isInitCapture();
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Retrieve the declaration of the local variable being
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// captured.
956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// This operation is only valid if this capture is a variable capture
976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// (other than a capture of \c this).
986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  VarDecl *getCapturedVar() const {
996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(capturesVariable() && "No variable available for 'this' capture");
1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return cast<VarDecl>(DeclAndBits.getPointer());
1016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this was an implicit capture (not
1046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// written between the square brackets introducing the lambda).
1056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
1066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this was an explicit capture (written
1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// between the square brackets introducing the lambda).
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isExplicit() const { return !isImplicit(); }
1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Retrieve the source location of the capture.
1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// For an explicit capture, this returns the location of the
1146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// explicit capture in the source. For an implicit capture, this
1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// returns the location at which the variable or \c this was first
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// used.
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceLocation getLocation() const { return Loc; }
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this capture is a pack expansion,
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// which captures a function parameter pack.
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Retrieve the location of the ellipsis for a capture
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// that is a pack expansion.
1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceLocation getEllipsisLoc() const {
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isPackExpansion() && "No ellipsis location for a non-expansion");
1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return EllipsisLoc;
1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} // end namespace clang
1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
134