11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " ResultPlan.h"
14
+ #include " Callee.h"
14
15
#include " Initialization.h"
15
16
#include " RValue.h"
16
17
#include " SILGenFunction.h"
@@ -37,6 +38,10 @@ class InPlaceInitializationResultPlan : public ResultPlan {
37
38
init->finishInitialization (SGF);
38
39
return RValue ();
39
40
}
41
+ void
42
+ gatherIndirectResultAddrs (SmallVectorImpl<SILValue> &outList) const override {
43
+ outList.emplace_back (init->getAddressForInPlaceInitialization ());
44
+ }
40
45
};
41
46
42
47
// / A result plan for working with a single value and potentially
@@ -114,6 +119,13 @@ class ScalarResultPlan : public ResultPlan {
114
119
return RValue (SGF, loc, substType, value);
115
120
}
116
121
}
122
+
123
+ void
124
+ gatherIndirectResultAddrs (SmallVectorImpl<SILValue> &outList) const override {
125
+ if (!temporary)
126
+ return ;
127
+ outList.emplace_back (temporary->getAddress ());
128
+ }
117
129
};
118
130
119
131
// / A result plan which calls copyOrInitValueInto on an Initialization
@@ -142,6 +154,11 @@ class InitValueFromTemporaryResultPlan : public ResultPlan {
142
154
143
155
return RValue ();
144
156
}
157
+
158
+ void
159
+ gatherIndirectResultAddrs (SmallVectorImpl<SILValue> &outList) const override {
160
+ subPlan->gatherIndirectResultAddrs (outList);
161
+ }
145
162
};
146
163
147
164
// / A result plan which calls copyOrInitValueInto using the result of
@@ -164,6 +181,11 @@ class InitValueFromRValueResultPlan : public ResultPlan {
164
181
165
182
return RValue ();
166
183
}
184
+
185
+ void
186
+ gatherIndirectResultAddrs (SmallVectorImpl<SILValue> &outList) const override {
187
+ subPlan->gatherIndirectResultAddrs (outList);
188
+ }
167
189
};
168
190
169
191
// / A result plan which produces a larger RValue from a bunch of
@@ -198,6 +220,13 @@ class TupleRValueResultPlan : public ResultPlan {
198
220
199
221
return tupleRV;
200
222
}
223
+
224
+ void
225
+ gatherIndirectResultAddrs (SmallVectorImpl<SILValue> &outList) const override {
226
+ for (const auto &eltPlan : eltPlans) {
227
+ eltPlan->gatherIndirectResultAddrs (outList);
228
+ }
229
+ }
201
230
};
202
231
203
232
// / A result plan which evaluates into the sub-components
@@ -243,6 +272,13 @@ class TupleInitializationResultPlan : public ResultPlan {
243
272
244
273
return RValue ();
245
274
}
275
+
276
+ void
277
+ gatherIndirectResultAddrs (SmallVectorImpl<SILValue> &outList) const override {
278
+ for (const auto &eltPlan : eltPlans) {
279
+ eltPlan->gatherIndirectResultAddrs (outList);
280
+ }
281
+ }
246
282
};
247
283
248
284
} // end anonymous namespace
@@ -275,7 +311,6 @@ ResultPlanPtr ResultPlanBuilder::build(Initialization *init,
275
311
if (initAddr && SGF.silConv .isSILIndirect (result) &&
276
312
!initAddr->getType ().hasAbstractionDifference (
277
313
rep, result.getSILStorageType ())) {
278
- indirectResultAddrs.push_back (initAddr);
279
314
return ResultPlanPtr (new InPlaceInitializationResultPlan (init));
280
315
}
281
316
}
@@ -292,7 +327,6 @@ ResultPlanPtr ResultPlanBuilder::build(Initialization *init,
292
327
if (SGF.silConv .isSILIndirect (result)) {
293
328
auto &resultTL = SGF.getTypeLowering (result.getType ());
294
329
temporary = SGF.emitTemporary (loc, resultTL);
295
- indirectResultAddrs.push_back (temporary->getAddress ());
296
330
}
297
331
298
332
return ResultPlanPtr (
@@ -341,3 +375,46 @@ ResultPlanPtr ResultPlanBuilder::buildForTuple(Initialization *init,
341
375
return ResultPlanPtr (
342
376
new InitValueFromRValueResultPlan (init, std::move (subplan)));
343
377
}
378
+
379
+ ResultPlanPtr
380
+ ResultPlanBuilder::computeResultPlan (SILGenFunction &SGF,
381
+ CalleeTypeInfo &calleeTypeInfo,
382
+ SILLocation loc, SGFContext evalContext) {
383
+ auto origResultTypeForPlan = calleeTypeInfo.origResultType ;
384
+ auto substResultTypeForPlan = calleeTypeInfo.substResultType ;
385
+ ArrayRef<SILResultInfo> allResults = calleeTypeInfo.substFnType ->getResults ();
386
+ SILResultInfo optResult;
387
+
388
+ // The plan needs to be built using the formal result type
389
+ // after foreign-error adjustment.
390
+ if (auto foreignError = calleeTypeInfo.foreignError ) {
391
+ switch (foreignError->getKind ()) {
392
+ // These conventions make the formal result type ().
393
+ case ForeignErrorConvention::ZeroResult:
394
+ case ForeignErrorConvention::NonZeroResult:
395
+ assert (calleeTypeInfo.substResultType ->isVoid ());
396
+ allResults = {};
397
+ break ;
398
+
399
+ // These conventions leave the formal result alone.
400
+ case ForeignErrorConvention::ZeroPreservedResult:
401
+ case ForeignErrorConvention::NonNilError:
402
+ break ;
403
+
404
+ // This convention changes the formal result to the optional object
405
+ // type; we need to make our own make SILResultInfo array.
406
+ case ForeignErrorConvention::NilResult: {
407
+ assert (allResults.size () == 1 );
408
+ CanType objectType = allResults[0 ].getType ().getAnyOptionalObjectType ();
409
+ optResult = allResults[0 ].getWithType (objectType);
410
+ allResults = optResult;
411
+ break ;
412
+ }
413
+ }
414
+ }
415
+
416
+ ResultPlanBuilder builder (SGF, loc, allResults,
417
+ calleeTypeInfo.getOverrideRep ());
418
+ return builder.build (evalContext.getEmitInto (), origResultTypeForPlan,
419
+ substResultTypeForPlan);
420
+ }
0 commit comments