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.
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool capturesThis() const { return DeclAndBits.getPointer() == nullptr; }
726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this capture handles a variable.
746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool capturesVariable() const {
756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this is an init-capture.
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isInitCapture() const {
806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return capturesVariable() && getCapturedVar()->isInitCapture();
816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Retrieve the declaration of the local variable being
846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// captured.
856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// This operation is only valid if this capture is a variable capture
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// (other than a capture of \c this).
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  VarDecl *getCapturedVar() const {
896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(capturesVariable() && "No variable available for 'this' capture");
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return cast<VarDecl>(DeclAndBits.getPointer());
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this was an implicit capture (not
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// written between the square brackets introducing the lambda).
956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this was an explicit capture (written
986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// between the square brackets introducing the lambda).
996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isExplicit() const { return !isImplicit(); }
1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Retrieve the source location of the capture.
1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ///
1036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// For an explicit capture, this returns the location of the
1046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// explicit capture in the source. For an implicit capture, this
1056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// returns the location at which the variable or \c this was first
1066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// used.
1076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceLocation getLocation() const { return Loc; }
1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Determine whether this capture is a pack expansion,
1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// which captures a function parameter pack.
1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// \brief Retrieve the location of the ellipsis for a capture
1146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// that is a pack expansion.
1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceLocation getEllipsisLoc() const {
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(isPackExpansion() && "No ellipsis location for a non-expansion");
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return EllipsisLoc;
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} // end namespace clang
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
124