2020#include " clang/AST/ASTLambda.h"
2121#include " clang/AST/Attr.h"
2222#include " clang/AST/Decl.h"
23+ #include " llvm/ADT/PointerUnion.h"
2324#include " llvm/Support/raw_ostream.h"
2425
2526namespace clang {
@@ -55,6 +56,9 @@ class Scope final {
5556 LocalVectorTy Descriptors;
5657};
5758
59+ using FunctionDeclTy =
60+ llvm::PointerUnion<const FunctionDecl *, const BlockExpr *>;
61+
5862// / Bytecode function.
5963// /
6064// / Contains links to the bytecode of the function, as well as metadata
@@ -89,15 +93,20 @@ class Function final {
8993 CodePtr getCodeEnd () const { return Code.data () + Code.size (); }
9094
9195 // / Returns the original FunctionDecl.
92- const FunctionDecl *getDecl () const { return F; }
96+ const FunctionDecl *getDecl () const {
97+ return Source.dyn_cast <const FunctionDecl *>();
98+ }
99+ const BlockExpr *getExpr () const {
100+ return Source.dyn_cast <const BlockExpr *>();
101+ }
93102
94103 // / Returns the name of the function decl this code
95104 // / was generated for.
96105 const std::string getName () const {
97- if (!F )
106+ if (!Source )
98107 return " <<expr>>" ;
99108
100- return F ->getQualifiedNameAsString ();
109+ return Source. get < const FunctionDecl *>() ->getQualifiedNameAsString ();
101110 }
102111
103112 // / Returns a parameter descriptor.
@@ -135,29 +144,38 @@ class Function final {
135144 bool isVirtual () const ;
136145
137146 // / Checks if the function is a constructor.
138- bool isConstructor () const { return isa<CXXConstructorDecl>(F); }
147+ bool isConstructor () const {
148+ return isa_and_nonnull<CXXConstructorDecl>(
149+ Source.dyn_cast <const FunctionDecl *>());
150+ }
139151 // / Checks if the function is a destructor.
140- bool isDestructor () const { return isa<CXXDestructorDecl>(F); }
152+ bool isDestructor () const {
153+ return isa_and_nonnull<CXXDestructorDecl>(
154+ Source.dyn_cast <const FunctionDecl *>());
155+ }
141156
142157 // / Returns the parent record decl, if any.
143158 const CXXRecordDecl *getParentDecl () const {
144- if (const auto *MD = dyn_cast<CXXMethodDecl>(F))
159+ if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
160+ Source.dyn_cast <const FunctionDecl *>()))
145161 return MD->getParent ();
146162 return nullptr ;
147163 }
148164
149165 // / Returns whether this function is a lambda static invoker,
150166 // / which we generate custom byte code for.
151167 bool isLambdaStaticInvoker () const {
152- if (const auto *MD = dyn_cast<CXXMethodDecl>(F))
168+ if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
169+ Source.dyn_cast <const FunctionDecl *>()))
153170 return MD->isLambdaStaticInvoker ();
154171 return false ;
155172 }
156173
157174 // / Returns whether this function is the call operator
158175 // / of a lambda record decl.
159176 bool isLambdaCallOperator () const {
160- if (const auto *MD = dyn_cast<CXXMethodDecl>(F))
177+ if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
178+ Source.dyn_cast <const FunctionDecl *>()))
161179 return clang::isLambdaCallOperator (MD);
162180 return false ;
163181 }
@@ -175,9 +193,13 @@ class Function final {
175193
176194 bool isVariadic () const { return Variadic; }
177195
178- unsigned getBuiltinID () const { return F->getBuiltinID (); }
196+ unsigned getBuiltinID () const {
197+ return Source.get <const FunctionDecl *>()->getBuiltinID ();
198+ }
179199
180- bool isBuiltin () const { return F->getBuiltinID () != 0 ; }
200+ bool isBuiltin () const {
201+ return Source.get <const FunctionDecl *>()->getBuiltinID () != 0 ;
202+ }
181203
182204 bool isUnevaluatedBuiltin () const { return IsUnevaluatedBuiltin; }
183205
@@ -194,7 +216,8 @@ class Function final {
194216 }
195217
196218 bool isThisPointerExplicit () const {
197- if (const auto *MD = dyn_cast<CXXMethodDecl>(F))
219+ if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
220+ Source.dyn_cast <const FunctionDecl *>()))
198221 return MD->isExplicitObjectMemberFunction ();
199222 return false ;
200223 }
@@ -205,7 +228,7 @@ class Function final {
205228
206229private:
207230 // / Construct a function representing an actual function.
208- Function (Program &P, const FunctionDecl *F , unsigned ArgSize,
231+ Function (Program &P, FunctionDeclTy Source , unsigned ArgSize,
209232 llvm::SmallVectorImpl<PrimType> &&ParamTypes,
210233 llvm::DenseMap<unsigned , ParamDescriptor> &&Params,
211234 llvm::SmallVectorImpl<unsigned > &&ParamOffsets, bool HasThisPointer,
@@ -233,7 +256,7 @@ class Function final {
233256 // / Program reference.
234257 Program &P;
235258 // / Declaration this function was compiled from.
236- const FunctionDecl *F ;
259+ FunctionDeclTy Source ;
237260 // / Local area size: storage + metadata.
238261 unsigned FrameSize = 0 ;
239262 // / Size of the argument stack.
0 commit comments