@@ -124,7 +124,31 @@ namespace irgen {
124
124
125
125
// / A function pointer value.
126
126
class FunctionPointer {
127
- // / The actual function pointer.
127
+ public:
128
+ struct KindTy {
129
+ enum class Value {
130
+ Function,
131
+ AsyncFunctionPointer,
132
+ };
133
+ static const Value Function = Value::Function;
134
+ static const Value AsyncFunctionPointer = Value::AsyncFunctionPointer;
135
+ Value value;
136
+ KindTy (Value value) : value(value) {}
137
+ KindTy (CanSILFunctionType fnType)
138
+ : value(fnType->isAsync () ? Value::AsyncFunctionPointer
139
+ : Value::Function) {}
140
+ friend bool operator ==(const KindTy &lhs, const KindTy &rhs) {
141
+ return lhs.value == rhs.value ;
142
+ }
143
+ friend bool operator !=(const KindTy &lhs, const KindTy &rhs) {
144
+ return !(lhs == rhs);
145
+ }
146
+ };
147
+
148
+ private:
149
+ KindTy Kind;
150
+
151
+ // / The actual pointer, either to the function or to its descriptor.
128
152
llvm::Value *Value;
129
153
130
154
PointerAuthInfo AuthInfo;
@@ -135,25 +159,27 @@ namespace irgen {
135
159
// / Construct a FunctionPointer for an arbitrary pointer value.
136
160
// / We may add more arguments to this; try to use the other
137
161
// / constructors/factories if possible.
138
- explicit FunctionPointer (llvm::Value *value, PointerAuthInfo authInfo,
162
+ explicit FunctionPointer (KindTy kind, llvm::Value *value,
163
+ PointerAuthInfo authInfo,
139
164
const Signature &signature)
140
- : Value(value), AuthInfo(authInfo), Sig(signature) {
165
+ : Kind(kind), Value(value), AuthInfo(authInfo), Sig(signature) {
141
166
// The function pointer should have function type.
142
167
assert (value->getType ()->getPointerElementType ()->isFunctionTy ());
143
168
// TODO: maybe assert similarity to signature.getType()?
144
169
}
145
170
146
171
// Temporary only!
147
- explicit FunctionPointer (llvm::Value *value, const Signature &signature)
148
- : FunctionPointer(value, PointerAuthInfo(), signature) {}
172
+ explicit FunctionPointer (KindTy kind, llvm::Value *value,
173
+ const Signature &signature)
174
+ : FunctionPointer(kind, value, PointerAuthInfo(), signature) {}
149
175
150
176
static FunctionPointer forDirect (IRGenModule &IGM,
151
177
llvm::Constant *value,
152
178
CanSILFunctionType fnType);
153
179
154
- static FunctionPointer forDirect (llvm::Constant *value,
180
+ static FunctionPointer forDirect (KindTy kind, llvm::Constant *value,
155
181
const Signature &signature) {
156
- return FunctionPointer (value, PointerAuthInfo (), signature);
182
+ return FunctionPointer (kind, value, PointerAuthInfo (), signature);
157
183
}
158
184
159
185
static FunctionPointer forExplosionValue (IRGenFunction &IGF,
@@ -166,8 +192,17 @@ namespace irgen {
166
192
return (isa<llvm::Constant>(Value) && AuthInfo.isConstant ());
167
193
}
168
194
195
+ KindTy getKind () const { return Kind; }
196
+
197
+ // / Given that this value is known to have been constructed from a direct
198
+ // / function, Return the name of that function.
199
+ StringRef getName (IRGenModule &IGM) const ;
200
+
169
201
// / Return the actual function pointer.
170
- llvm::Value *getPointer () const { return Value; }
202
+ llvm::Value *getPointer (IRGenFunction &IGF) const ;
203
+
204
+ // / Return the actual function pointer.
205
+ llvm::Value *getRawPointer () const { return Value; }
171
206
172
207
// / Given that this value is known to have been constructed from
173
208
// / a direct function, return the function pointer.
@@ -205,6 +240,9 @@ namespace irgen {
205
240
206
241
llvm::Value *getExplosionValue (IRGenFunction &IGF,
207
242
CanSILFunctionType fnType) const ;
243
+
244
+ // / Form a FunctionPointer whose KindTy is ::Function.
245
+ FunctionPointer getAsFunction (IRGenFunction &IGF) const ;
208
246
};
209
247
210
248
class Callee {
0 commit comments