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