20
20
#include " clang/AST/ASTLambda.h"
21
21
#include " clang/AST/Attr.h"
22
22
#include " clang/AST/Decl.h"
23
+ #include " llvm/ADT/PointerUnion.h"
23
24
#include " llvm/Support/raw_ostream.h"
24
25
25
26
namespace clang {
@@ -55,6 +56,9 @@ class Scope final {
55
56
LocalVectorTy Descriptors;
56
57
};
57
58
59
+ using FunctionDeclTy =
60
+ llvm::PointerUnion<const FunctionDecl *, const BlockExpr *>;
61
+
58
62
// / Bytecode function.
59
63
// /
60
64
// / Contains links to the bytecode of the function, as well as metadata
@@ -89,15 +93,20 @@ class Function final {
89
93
CodePtr getCodeEnd () const { return Code.data () + Code.size (); }
90
94
91
95
// / 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
+ }
93
102
94
103
// / Returns the name of the function decl this code
95
104
// / was generated for.
96
105
const std::string getName () const {
97
- if (!F )
106
+ if (!Source )
98
107
return " <<expr>>" ;
99
108
100
- return F ->getQualifiedNameAsString ();
109
+ return Source. get < const FunctionDecl *>() ->getQualifiedNameAsString ();
101
110
}
102
111
103
112
// / Returns a parameter descriptor.
@@ -135,29 +144,38 @@ class Function final {
135
144
bool isVirtual () const ;
136
145
137
146
// / 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
+ }
139
151
// / 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
+ }
141
156
142
157
// / Returns the parent record decl, if any.
143
158
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 *>()))
145
161
return MD->getParent ();
146
162
return nullptr ;
147
163
}
148
164
149
165
// / Returns whether this function is a lambda static invoker,
150
166
// / which we generate custom byte code for.
151
167
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 *>()))
153
170
return MD->isLambdaStaticInvoker ();
154
171
return false ;
155
172
}
156
173
157
174
// / Returns whether this function is the call operator
158
175
// / of a lambda record decl.
159
176
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 *>()))
161
179
return clang::isLambdaCallOperator (MD);
162
180
return false ;
163
181
}
@@ -175,9 +193,13 @@ class Function final {
175
193
176
194
bool isVariadic () const { return Variadic; }
177
195
178
- unsigned getBuiltinID () const { return F->getBuiltinID (); }
196
+ unsigned getBuiltinID () const {
197
+ return Source.get <const FunctionDecl *>()->getBuiltinID ();
198
+ }
179
199
180
- bool isBuiltin () const { return F->getBuiltinID () != 0 ; }
200
+ bool isBuiltin () const {
201
+ return Source.get <const FunctionDecl *>()->getBuiltinID () != 0 ;
202
+ }
181
203
182
204
bool isUnevaluatedBuiltin () const { return IsUnevaluatedBuiltin; }
183
205
@@ -194,7 +216,8 @@ class Function final {
194
216
}
195
217
196
218
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 *>()))
198
221
return MD->isExplicitObjectMemberFunction ();
199
222
return false ;
200
223
}
@@ -205,7 +228,7 @@ class Function final {
205
228
206
229
private:
207
230
// / Construct a function representing an actual function.
208
- Function (Program &P, const FunctionDecl *F , unsigned ArgSize,
231
+ Function (Program &P, FunctionDeclTy Source , unsigned ArgSize,
209
232
llvm::SmallVectorImpl<PrimType> &&ParamTypes,
210
233
llvm::DenseMap<unsigned , ParamDescriptor> &&Params,
211
234
llvm::SmallVectorImpl<unsigned > &&ParamOffsets, bool HasThisPointer,
@@ -233,7 +256,7 @@ class Function final {
233
256
// / Program reference.
234
257
Program &P;
235
258
// / Declaration this function was compiled from.
236
- const FunctionDecl *F ;
259
+ FunctionDeclTy Source ;
237
260
// / Local area size: storage + metadata.
238
261
unsigned FrameSize = 0 ;
239
262
// / Size of the argument stack.
0 commit comments