@@ -36,82 +36,162 @@ namespace irgen {
36
36
class Callee ;
37
37
class IRGenFunction ;
38
38
39
- class Callee {
39
+ class CalleeInfo {
40
+ public:
40
41
// / The unsubstituted function type being called.
41
42
CanSILFunctionType OrigFnType;
42
43
43
44
// / The substituted result type of the function being called.
44
45
CanSILFunctionType SubstFnType;
45
46
46
- // / The clang information for the function being called, if applicable.
47
- ForeignFunctionInfo ForeignInfo;
48
-
49
- // / The pointer to the actual function.
50
- llvm::Value *FnPtr;
51
-
52
- // / The data pointer required by the function. There's an
53
- // / invariant that this never stores an llvm::ConstantPointerNull.
54
- llvm::Value *DataPtr;
55
-
56
47
// / The archetype substitutions under which the function is being
57
48
// / called.
58
49
std::vector<Substitution> Substitutions;
59
50
51
+ CalleeInfo (CanSILFunctionType origFnType,
52
+ CanSILFunctionType substFnType,
53
+ SubstitutionList substitutions)
54
+ : OrigFnType(origFnType), SubstFnType(substFnType),
55
+ Substitutions (substitutions.begin(), substitutions.end()) {
56
+ }
57
+ };
58
+
59
+ // / A function pointer value.
60
+ class FunctionPointer {
61
+ // / The actual function pointer.
62
+ llvm::Value *Value;
63
+
64
+ Signature Sig;
65
+
66
+ public:
67
+ // / Construct a FunctionPointer for an arbitrary pointer value.
68
+ // / We may add more arguments to this; try to use the other
69
+ // / constructors/factories if possible.
70
+ explicit FunctionPointer (llvm::Value *value, const Signature &signature)
71
+ : Value(value), Sig(signature) {
72
+ // The function pointer should have function type.
73
+ assert (value->getType ()->getPointerElementType ()->isFunctionTy ());
74
+ // TODO: maybe assert similarity to signature.getType()?
75
+ }
76
+
77
+ static FunctionPointer forDirect (IRGenModule &IGM,
78
+ llvm::Constant *value,
79
+ CanSILFunctionType fnType);
80
+
81
+ static FunctionPointer forDirect (llvm::Constant *value,
82
+ const Signature &signature) {
83
+ return FunctionPointer (value, signature);
84
+ }
85
+
86
+ static FunctionPointer forExplosionValue (IRGenFunction &IGF,
87
+ llvm::Value *fnPtr,
88
+ CanSILFunctionType fnType);
89
+
90
+ // / Return the actual function pointer.
91
+ llvm::Value *getPointer () const { return Value; }
92
+
93
+ // / Given that this value is known to have been constructed from
94
+ // / a direct function, return the function pointer.
95
+ llvm::Constant *getDirectPointer () const {
96
+ return cast<llvm::Constant>(Value);
97
+ }
98
+
99
+ llvm::FunctionType *getFunctionType () const {
100
+ return cast<llvm::FunctionType>(
101
+ Value->getType ()->getPointerElementType ());
102
+ }
103
+
104
+ const Signature &getSignature () const {
105
+ return Sig;
106
+ }
107
+
108
+ llvm::CallingConv::ID getCallingConv () const {
109
+ return Sig.getCallingConv ();
110
+ }
111
+
112
+ llvm::AttributeSet getAttributes () const {
113
+ return Sig.getAttributes ();
114
+ }
115
+ llvm::AttributeSet &getMutableAttributes () & {
116
+ return Sig.getMutableAttributes ();
117
+ }
118
+
119
+ ForeignFunctionInfo getForeignInfo () const {
120
+ return Sig.getForeignInfo ();
121
+ }
122
+
123
+ llvm::Value *getExplosionValue (IRGenFunction &IGF,
124
+ CanSILFunctionType fnType) const ;
125
+ };
126
+
127
+ class Callee {
128
+ CalleeInfo Info;
129
+
130
+ // / The actual function pointer to invoke.
131
+ FunctionPointer Fn;
132
+
133
+ // / The first data pointer required by the function invocation.
134
+ llvm::Value *FirstData;
135
+
136
+ // / The second data pointer required by the function invocation.
137
+ llvm::Value *SecondData;
138
+
60
139
public:
61
- Callee () = default ;
62
-
63
- // / Prepare a callee for a known function with a known data pointer.
64
- static Callee forKnownFunction (CanSILFunctionType origFnType,
65
- CanSILFunctionType substFnType,
66
- SubstitutionList subs,
67
- llvm::Value *fn, llvm::Value *data,
68
- ForeignFunctionInfo foreignInfo) {
69
- // Invariant on the function pointer.
70
- assert (fn->getType ()->getPointerElementType ()->isFunctionTy ());
71
- assert ((foreignInfo.ClangInfo != nullptr ) ==
72
- (origFnType->getLanguage () == SILFunctionLanguage::C));
73
-
74
- Callee result;
75
- result.OrigFnType = origFnType;
76
- result.SubstFnType = substFnType;
77
- result.FnPtr = fn;
78
- result.DataPtr = data;
79
- result.Substitutions = subs;
80
- result.ForeignInfo = foreignInfo;
81
- return result;
82
- }
83
-
140
+ Callee (const Callee &other) = delete ;
141
+ Callee &operator =(const Callee &other) = delete ;
142
+
143
+ Callee (Callee &&other) = default ;
144
+ Callee &operator =(Callee &&other) = default ;
145
+
146
+ Callee (CalleeInfo &&info, const FunctionPointer &fn,
147
+ llvm::Value *firstData = nullptr ,
148
+ llvm::Value *secondData = nullptr );
149
+
84
150
SILFunctionTypeRepresentation getRepresentation () const {
85
- return OrigFnType->getRepresentation ();
151
+ return Info. OrigFnType ->getRepresentation ();
86
152
}
87
153
88
- CanSILFunctionType getOrigFunctionType () const { return OrigFnType; }
89
- CanSILFunctionType getSubstFunctionType () const { return SubstFnType; }
154
+ CanSILFunctionType getOrigFunctionType () const {
155
+ return Info.OrigFnType ;
156
+ }
157
+ CanSILFunctionType getSubstFunctionType () const {
158
+ return Info.SubstFnType ;
159
+ }
90
160
91
- bool hasSubstitutions () const { return !Substitutions.empty (); }
92
- SubstitutionList getSubstitutions () const { return Substitutions; }
161
+ bool hasSubstitutions () const { return !Info. Substitutions .empty (); }
162
+ SubstitutionList getSubstitutions () const { return Info. Substitutions ; }
93
163
94
- llvm::Value * getFunction () const { return FnPtr ; }
164
+ const FunctionPointer & getFunctionPointer () const { return Fn ; }
95
165
96
166
llvm::FunctionType *getLLVMFunctionType () {
97
- return cast<llvm::FunctionType>(FnPtr->getType ()->getPointerElementType ());
167
+ return Fn.getFunctionType ();
168
+ }
169
+
170
+ llvm::AttributeSet getAttributes () const {
171
+ return Fn.getAttributes ();
172
+ }
173
+ llvm::AttributeSet &getMutableAttributes () & {
174
+ return Fn.getMutableAttributes ();
98
175
}
99
176
100
- const ForeignFunctionInfo & getForeignInfo () const {
101
- return ForeignInfo ;
177
+ ForeignFunctionInfo getForeignInfo () const {
178
+ return Fn. getForeignInfo () ;
102
179
}
103
180
104
- // / Return the function pointer as an i8*.
105
- llvm::Value *getOpaqueFunctionPointer (IRGenFunction &IGF) const ;
181
+ // / If this callee has a value for the Swift context slot, return
182
+ // / it; otherwise return non-null.
183
+ llvm::Value *getSwiftContext () const ;
106
184
107
- // / Return the function pointer as an appropriate pointer-to-function .
108
- llvm::Value *getFunctionPointer () const { return FnPtr; }
185
+ // / Given that this callee is a block, return the block pointer.
186
+ llvm::Value *getBlockObject () const ;
109
187
110
- // / Is it possible that this function requires a non-null data pointer?
111
- bool hasDataPointer () const { return DataPtr != nullptr ; }
188
+ // / Given that this callee is an ObjC method, return the receiver
189
+ // / argument. This might not be 'self' anymore.
190
+ llvm::Value *getObjCMethodReceiver () const ;
112
191
113
- // / Return the data pointer as a %swift.refcounted*.
114
- llvm::Value *getDataPointer (IRGenFunction &IGF) const ;
192
+ // / Given that this callee is an ObjC method, return the receiver
193
+ // / argument. This might not be 'self' anymore.
194
+ llvm::Value *getObjCMethodSelector () const ;
115
195
};
116
196
117
197
} // end namespace irgen
0 commit comments