Home | History | Annotate | Download | only in AST
      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     /// \brief Flag used by the Capture class to distinguish between a capture
     39     /// of '*this' and a capture of a VLA type.
     40     Capture_This = 0x04
     41   };
     42 
     43   // Decl could represent:
     44   // - a VarDecl* that represents the variable that was captured or the
     45   //   init-capture.
     46   // - or, is a nullptr and Capture_This is set in Bits if this represents a
     47   //   capture of '*this' by value or reference.
     48   // - or, is a nullptr and Capture_This is not set in Bits if this represents
     49   //   a capture of a VLA type.
     50   llvm::PointerIntPair<Decl*, 3> DeclAndBits;
     51 
     52   SourceLocation Loc;
     53   SourceLocation EllipsisLoc;
     54 
     55   friend class ASTStmtReader;
     56   friend class ASTStmtWriter;
     57 
     58 public:
     59   /// \brief Create a new capture of a variable or of \c this.
     60   ///
     61   /// \param Loc The source location associated with this capture.
     62   ///
     63   /// \param Kind The kind of capture (this, byref, bycopy), which must
     64   /// not be init-capture.
     65   ///
     66   /// \param Implicit Whether the capture was implicit or explicit.
     67   ///
     68   /// \param Var The local variable being captured, or null if capturing
     69   /// \c this.
     70   ///
     71   /// \param EllipsisLoc The location of the ellipsis (...) for a
     72   /// capture that is a pack expansion, or an invalid source
     73   /// location to indicate that this is not a pack expansion.
     74   LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
     75                 VarDecl *Var = nullptr,
     76                 SourceLocation EllipsisLoc = SourceLocation());
     77 
     78   /// \brief Determine the kind of capture.
     79   LambdaCaptureKind getCaptureKind() const;
     80 
     81   /// \brief Determine whether this capture handles the C++ \c this
     82   /// pointer.
     83   bool capturesThis() const {
     84     return DeclAndBits.getPointer() == nullptr &&
     85           (DeclAndBits.getInt() & Capture_This);
     86   }
     87 
     88   /// \brief Determine whether this capture handles a variable.
     89   bool capturesVariable() const {
     90     return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
     91   }
     92 
     93   /// \brief Determine whether this captures a variable length array bound
     94   /// expression.
     95   bool capturesVLAType() const {
     96     return DeclAndBits.getPointer() == nullptr &&
     97            !(DeclAndBits.getInt() & Capture_This);
     98   }
     99 
    100   /// \brief Retrieve the declaration of the local variable being
    101   /// captured.
    102   ///
    103   /// This operation is only valid if this capture is a variable capture
    104   /// (other than a capture of \c this).
    105   VarDecl *getCapturedVar() const {
    106     assert(capturesVariable() && "No variable available for capture");
    107     return static_cast<VarDecl *>(DeclAndBits.getPointer());
    108   }
    109 
    110   /// \brief Determine whether this was an implicit capture (not
    111   /// written between the square brackets introducing the lambda).
    112   bool isImplicit() const {
    113     return DeclAndBits.getInt() & Capture_Implicit;
    114   }
    115 
    116   /// \brief Determine whether this was an explicit capture (written
    117   /// between the square brackets introducing the lambda).
    118   bool isExplicit() const { return !isImplicit(); }
    119 
    120   /// \brief Retrieve the source location of the capture.
    121   ///
    122   /// For an explicit capture, this returns the location of the
    123   /// explicit capture in the source. For an implicit capture, this
    124   /// returns the location at which the variable or \c this was first
    125   /// used.
    126   SourceLocation getLocation() const { return Loc; }
    127 
    128   /// \brief Determine whether this capture is a pack expansion,
    129   /// which captures a function parameter pack.
    130   bool isPackExpansion() const { return EllipsisLoc.isValid(); }
    131 
    132   /// \brief Retrieve the location of the ellipsis for a capture
    133   /// that is a pack expansion.
    134   SourceLocation getEllipsisLoc() const {
    135     assert(isPackExpansion() && "No ellipsis location for a non-expansion");
    136     return EllipsisLoc;
    137   }
    138 };
    139 
    140 } // end namespace clang
    141 
    142 #endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
    143