@@ -83,7 +83,6 @@ static clang::CXXDestructorDecl *getCXXDestructor(SILType type) {
83
83
return nullptr ;
84
84
return cxxRecordDecl->getDestructor ();
85
85
}
86
-
87
86
namespace {
88
87
class StructFieldInfo : public RecordField <StructFieldInfo> {
89
88
public:
@@ -415,6 +414,97 @@ namespace {
415
414
}
416
415
};
417
416
417
+ class AddressOnlyPointerAuthRecordTypeInfo final
418
+ : public StructTypeInfoBase<AddressOnlyPointerAuthRecordTypeInfo,
419
+ FixedTypeInfo, ClangFieldInfo> {
420
+ const clang::RecordDecl *clangDecl;
421
+
422
+ void emitCopyWithCopyFunction (IRGenFunction &IGF, SILType T, Address src,
423
+ Address dst) const {
424
+ auto *copyFunction =
425
+ clang::CodeGen::getNonTrivialCStructCopyAssignmentOperator (
426
+ IGF.IGM .getClangCGM (), dst.getAlignment (), src.getAlignment (),
427
+ /* isVolatile*/ false ,
428
+ clang::QualType (clangDecl->getTypeForDecl (), 0 ));
429
+ auto *dstValue = dst.getAddress ();
430
+ auto *srcValue = src.getAddress ();
431
+ if (IGF.IGM .getLLVMContext ().supportsTypedPointers ()) {
432
+ dstValue = IGF.coerceValue (
433
+ dst.getAddress (), copyFunction->getFunctionType ()->getParamType (0 ),
434
+ IGF.IGM .DataLayout );
435
+ srcValue = IGF.coerceValue (
436
+ src.getAddress (), copyFunction->getFunctionType ()->getParamType (1 ),
437
+ IGF.IGM .DataLayout );
438
+ }
439
+ IGF.Builder .CreateCall (copyFunction->getFunctionType (), copyFunction,
440
+ {dstValue, srcValue});
441
+ }
442
+
443
+ public:
444
+ AddressOnlyPointerAuthRecordTypeInfo (ArrayRef<ClangFieldInfo> fields,
445
+ llvm::Type *storageType, Size size,
446
+ Alignment align,
447
+ const clang::RecordDecl *clangDecl)
448
+ : StructTypeInfoBase(StructTypeInfoKind::AddressOnlyClangRecordTypeInfo,
449
+ fields, storageType, size,
450
+ // We can't assume any spare bits in a C++ type
451
+ // with user-defined special member functions.
452
+ SpareBitVector (llvm::Optional<APInt>{
453
+ llvm::APInt (size.getValueInBits (), 0 )}),
454
+ align, IsNotPOD, IsNotBitwiseTakable, IsFixedSize),
455
+ clangDecl(clangDecl) {
456
+ (void )clangDecl;
457
+ }
458
+
459
+ TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
460
+ SILType T) const override {
461
+ if (!IGM.getOptions ().ForceStructTypeLayouts ) {
462
+ return IGM.typeLayoutCache .getOrCreateTypeInfoBasedEntry (*this , T);
463
+ }
464
+ assert (false && " Implement proper type layout info in the future" );
465
+ return IGM.typeLayoutCache .getOrCreateTypeInfoBasedEntry (*this , T);
466
+ }
467
+
468
+ void initializeFromParams (IRGenFunction &IGF, Explosion ¶ms,
469
+ Address addr, SILType T,
470
+ bool isOutlined) const override {
471
+ llvm_unreachable (" Address-only C++ types must be created by C++ special "
472
+ " member functions." );
473
+ }
474
+
475
+ void initializeWithCopy (IRGenFunction &IGF, Address dst, Address src,
476
+ SILType T, bool isOutlined) const override {
477
+ emitCopyWithCopyFunction (IGF, T, src, dst);
478
+ }
479
+
480
+ void assignWithCopy (IRGenFunction &IGF, Address dst, Address src, SILType T,
481
+ bool isOutlined) const override {
482
+ emitCopyWithCopyFunction (IGF, T, src, dst);
483
+ }
484
+
485
+ void initializeWithTake (IRGenFunction &IGF, Address dst, Address src,
486
+ SILType T, bool isOutlined) const override {
487
+ emitCopyWithCopyFunction (IGF, T, src, dst);
488
+ destroy (IGF, src, T, isOutlined);
489
+ }
490
+
491
+ void assignWithTake (IRGenFunction &IGF, Address dst, Address src, SILType T,
492
+ bool isOutlined) const override {
493
+ emitCopyWithCopyFunction (IGF, T, src, dst);
494
+ destroy (IGF, src, T, isOutlined);
495
+ }
496
+
497
+ llvm::NoneType getNonFixedOffsets (IRGenFunction &IGF) const { return None; }
498
+ llvm::NoneType getNonFixedOffsets (IRGenFunction &IGF, SILType T) const {
499
+ return None;
500
+ }
501
+ MemberAccessStrategy
502
+ getNonFixedFieldAccessStrategy (IRGenModule &IGM, SILType T,
503
+ const ClangFieldInfo &field) const {
504
+ llvm_unreachable (" non-fixed field in Clang type?" );
505
+ }
506
+ };
507
+
418
508
class AddressOnlyCXXClangRecordTypeInfo final
419
509
: public StructTypeInfoBase<AddressOnlyCXXClangRecordTypeInfo,
420
510
FixedTypeInfo, ClangFieldInfo> {
@@ -1045,8 +1135,10 @@ class ClangRecordLowering {
1045
1135
return AddressOnlyCXXClangRecordTypeInfo::create (
1046
1136
FieldInfos, llvmType, TotalStride, TotalAlignment, ClangDecl);
1047
1137
}
1048
- // TODO: New AddressOnlyPtrAuthTypeInfo to handle address diversified field
1049
- // function ptrs in C structs.
1138
+ if (SwiftType.getStructOrBoundGenericStruct ()->isNonTrivialPtrAuth ()) {
1139
+ return AddressOnlyPointerAuthRecordTypeInfo::create (
1140
+ FieldInfos, llvmType, TotalStride, TotalAlignment, ClangDecl);
1141
+ }
1050
1142
return LoadableClangRecordTypeInfo::create (
1051
1143
FieldInfos, NextExplosionIndex, llvmType, TotalStride,
1052
1144
std::move (SpareBits), TotalAlignment, ClangDecl);
0 commit comments