@@ -124,7 +124,31 @@ namespace irgen {
124124
125125 // / A function pointer value.
126126 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.
128152 llvm::Value *Value;
129153
130154 PointerAuthInfo AuthInfo;
@@ -135,25 +159,27 @@ namespace irgen {
135159 // / Construct a FunctionPointer for an arbitrary pointer value.
136160 // / We may add more arguments to this; try to use the other
137161 // / constructors/factories if possible.
138- explicit FunctionPointer (llvm::Value *value, PointerAuthInfo authInfo,
162+ explicit FunctionPointer (KindTy kind, llvm::Value *value,
163+ PointerAuthInfo authInfo,
139164 const Signature &signature)
140- : Value(value), AuthInfo(authInfo), Sig(signature) {
165+ : Kind(kind), Value(value), AuthInfo(authInfo), Sig(signature) {
141166 // The function pointer should have function type.
142167 assert (value->getType ()->getPointerElementType ()->isFunctionTy ());
143168 // TODO: maybe assert similarity to signature.getType()?
144169 }
145170
146171 // 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) {}
149175
150176 static FunctionPointer forDirect (IRGenModule &IGM,
151177 llvm::Constant *value,
152178 CanSILFunctionType fnType);
153179
154- static FunctionPointer forDirect (llvm::Constant *value,
180+ static FunctionPointer forDirect (KindTy kind, llvm::Constant *value,
155181 const Signature &signature) {
156- return FunctionPointer (value, PointerAuthInfo (), signature);
182+ return FunctionPointer (kind, value, PointerAuthInfo (), signature);
157183 }
158184
159185 static FunctionPointer forExplosionValue (IRGenFunction &IGF,
@@ -166,8 +192,17 @@ namespace irgen {
166192 return (isa<llvm::Constant>(Value) && AuthInfo.isConstant ());
167193 }
168194
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+
169201 // / 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; }
171206
172207 // / Given that this value is known to have been constructed from
173208 // / a direct function, return the function pointer.
@@ -205,6 +240,9 @@ namespace irgen {
205240
206241 llvm::Value *getExplosionValue (IRGenFunction &IGF,
207242 CanSILFunctionType fnType) const ;
243+
244+ // / Form a FunctionPointer whose KindTy is ::Function.
245+ FunctionPointer getAsFunction (IRGenFunction &IGF) const ;
208246 };
209247
210248 class Callee {
0 commit comments