@@ -176,8 +176,9 @@ namespace {
176
176
class FuncTypeInfo : public ScalarTypeInfo <FuncTypeInfo, ReferenceTypeInfo>,
177
177
public FuncSignatureInfo {
178
178
FuncTypeInfo (CanSILFunctionType formalType, llvm::StructType *storageType,
179
- Size size, Alignment align, SpareBitVector &&spareBits)
180
- : ScalarTypeInfo(storageType, size, std::move(spareBits), align),
179
+ Size size, Alignment align, SpareBitVector &&spareBits,
180
+ IsPOD_t pod)
181
+ : ScalarTypeInfo(storageType, size, std::move(spareBits), align, pod),
181
182
FuncSignatureInfo (formalType)
182
183
{
183
184
}
@@ -186,9 +187,10 @@ namespace {
186
187
static const FuncTypeInfo *create (CanSILFunctionType formalType,
187
188
llvm::StructType *storageType,
188
189
Size size, Alignment align,
189
- SpareBitVector &&spareBits) {
190
+ SpareBitVector &&spareBits,
191
+ IsPOD_t pod) {
190
192
return new FuncTypeInfo (formalType, storageType, size, align,
191
- std::move (spareBits));
193
+ std::move (spareBits), pod );
192
194
}
193
195
194
196
// Function types do not satisfy allowsOwnership.
@@ -247,7 +249,8 @@ namespace {
247
249
248
250
Address dataAddr = projectData (IGF, address);
249
251
auto data = IGF.Builder .CreateLoad (dataAddr);
250
- IGF.emitNativeStrongRetain (data);
252
+ if (!isPOD (ResilienceExpansion::Maximal))
253
+ IGF.emitNativeStrongRetain (data);
251
254
e.add (data);
252
255
}
253
256
@@ -268,7 +271,11 @@ namespace {
268
271
IGF.Builder .CreateStore (e.claimNext (), fnAddr);
269
272
270
273
Address dataAddr = projectData (IGF, address);
271
- IGF.emitNativeStrongAssign (e.claimNext (), dataAddr);
274
+ auto context = e.claimNext ();
275
+ if (isPOD (ResilienceExpansion::Maximal))
276
+ IGF.Builder .CreateStore (context, dataAddr);
277
+ else
278
+ IGF.emitNativeStrongAssign (context, dataAddr);
272
279
}
273
280
274
281
void initialize (IRGenFunction &IGF, Explosion &e,
@@ -279,21 +286,28 @@ namespace {
279
286
280
287
// Store the data pointer, if any, transferring the +1.
281
288
Address dataAddr = projectData (IGF, address);
282
- IGF.emitNativeStrongInit (e.claimNext (), dataAddr);
289
+ auto context = e.claimNext ();
290
+ if (isPOD (ResilienceExpansion::Maximal))
291
+ IGF.Builder .CreateStore (context, dataAddr);
292
+ else
293
+ IGF.emitNativeStrongInit (context, dataAddr);
283
294
}
284
295
285
296
void copy (IRGenFunction &IGF, Explosion &src,
286
297
Explosion &dest, Atomicity atomicity) const override {
287
298
src.transferInto (dest, 1 );
288
299
auto data = src.claimNext ();
289
- IGF.emitNativeStrongRetain (data, atomicity);
300
+ if (!isPOD (ResilienceExpansion::Maximal))
301
+ IGF.emitNativeStrongRetain (data, atomicity);
290
302
dest.add (data);
291
303
}
292
304
293
305
void consume (IRGenFunction &IGF, Explosion &src,
294
306
Atomicity atomicity) const override {
295
307
src.claimNext ();
296
- IGF.emitNativeStrongRelease (src.claimNext (), atomicity);
308
+ auto context = src.claimNext ();
309
+ if (!isPOD (ResilienceExpansion::Maximal))
310
+ IGF.emitNativeStrongRelease (context, atomicity);
297
311
}
298
312
299
313
void fixLifetime (IRGenFunction &IGF, Explosion &src) const override {
@@ -304,13 +318,17 @@ namespace {
304
318
void strongRetain (IRGenFunction &IGF, Explosion &e,
305
319
Atomicity atomicity) const override {
306
320
e.claimNext ();
307
- IGF.emitNativeStrongRetain (e.claimNext (), atomicity);
321
+ auto context = e.claimNext ();
322
+ if (!isPOD (ResilienceExpansion::Maximal))
323
+ IGF.emitNativeStrongRetain (context, atomicity);
308
324
}
309
325
310
326
void strongRelease (IRGenFunction &IGF, Explosion &e,
311
327
Atomicity atomicity) const override {
312
328
e.claimNext ();
313
- IGF.emitNativeStrongRelease (e.claimNext (), atomicity);
329
+ auto context = e.claimNext ();
330
+ if (!isPOD (ResilienceExpansion::Maximal))
331
+ IGF.emitNativeStrongRelease (context, atomicity);
314
332
}
315
333
316
334
void strongRetainUnowned (IRGenFunction &IGF, Explosion &e) const override {
@@ -352,7 +370,8 @@ namespace {
352
370
353
371
void destroy (IRGenFunction &IGF, Address addr, SILType T) const override {
354
372
auto data = IGF.Builder .CreateLoad (projectData (IGF, addr));
355
- IGF.emitNativeStrongRelease (data);
373
+ if (!isPOD (ResilienceExpansion::Maximal))
374
+ IGF.emitNativeStrongRelease (data);
356
375
}
357
376
358
377
void packIntoEnumPayload (IRGenFunction &IGF,
@@ -534,7 +553,6 @@ const TypeInfo *TypeConverter::convertFunctionType(SILFunctionType *T) {
534
553
535
554
case SILFunctionType::Representation::Thin:
536
555
case SILFunctionType::Representation::Method:
537
- case SILFunctionType::Representation::WitnessMethod:
538
556
case SILFunctionType::Representation::ObjCMethod:
539
557
case SILFunctionType::Representation::CFunctionPointer:
540
558
return ThinFuncTypeInfo::create (CanSILFunctionType (T),
@@ -552,7 +570,21 @@ const TypeInfo *TypeConverter::convertFunctionType(SILFunctionType *T) {
552
570
IGM.FunctionPairTy ,
553
571
IGM.getPointerSize () * 2 ,
554
572
IGM.getPointerAlignment (),
555
- std::move (spareBits));
573
+ std::move (spareBits),
574
+ IsNotPOD);
575
+ }
576
+ // Witness method values carry a reference to their originating witness table
577
+ // as context.
578
+ case SILFunctionType::Representation::WitnessMethod: {
579
+ SpareBitVector spareBits;
580
+ spareBits.append (IGM.getFunctionPointerSpareBits ());
581
+ spareBits.append (IGM.getWitnessTablePtrSpareBits ());
582
+ return FuncTypeInfo::create (CanSILFunctionType (T),
583
+ IGM.WitnessFunctionPairTy ,
584
+ IGM.getPointerSize () * 2 ,
585
+ IGM.getPointerAlignment (),
586
+ std::move (spareBits),
587
+ IsPOD);
556
588
}
557
589
}
558
590
llvm_unreachable (" bad function type representation" );
0 commit comments