@@ -3683,6 +3683,28 @@ struct TargetResilientSuperclass {
36833683 TargetRelativeDirectPointer<Runtime, const void , /* nullable*/ true > Superclass;
36843684};
36853685
3686+ // / A structure that stores a reference to an Objective-C class stub.
3687+ // /
3688+ // / This is not the class stub itself; it is part of a class context
3689+ // / descriptor.
3690+ template <typename Runtime>
3691+ struct TargetObjCResilientClassStubInfo {
3692+ // / A relative pointer to an Objective-C resilient class stub.
3693+ // /
3694+ // / We do not declare a struct type for class stubs since the Swift runtime
3695+ // / does not need to interpret them. The class stub struct is part of
3696+ // / the Objective-C ABI, and is laid out as follows:
3697+ // / - isa pointer, always 1
3698+ // / - an update callback, of type 'Class (*)(Class *, objc_class_stub *)'
3699+ // /
3700+ // / Class stubs are used for two purposes:
3701+ // /
3702+ // / - Objective-C can reference class stubs when calling static methods.
3703+ // / - Objective-C and Swift can reference class stubs when emitting
3704+ // / categories (in Swift, extensions with @objc members).
3705+ TargetRelativeDirectPointer<Runtime, const void > Stub;
3706+ };
3707+
36863708template <typename Runtime>
36873709class TargetClassDescriptor final
36883710 : public TargetTypeContextDescriptor<Runtime>,
@@ -3695,7 +3717,8 @@ class TargetClassDescriptor final
36953717 TargetVTableDescriptorHeader<Runtime>,
36963718 TargetMethodDescriptor<Runtime>,
36973719 TargetOverrideTableHeader<Runtime>,
3698- TargetMethodOverrideDescriptor<Runtime>> {
3720+ TargetMethodOverrideDescriptor<Runtime>,
3721+ TargetObjCResilientClassStubInfo<Runtime>> {
36993722private:
37003723 using TrailingGenericContextObjects =
37013724 TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
@@ -3706,7 +3729,8 @@ class TargetClassDescriptor final
37063729 TargetVTableDescriptorHeader<Runtime>,
37073730 TargetMethodDescriptor<Runtime>,
37083731 TargetOverrideTableHeader<Runtime>,
3709- TargetMethodOverrideDescriptor<Runtime>>;
3732+ TargetMethodOverrideDescriptor<Runtime>,
3733+ TargetObjCResilientClassStubInfo<Runtime>>;
37103734
37113735 using TrailingObjects =
37123736 typename TrailingGenericContextObjects::TrailingObjects;
@@ -3722,6 +3746,8 @@ class TargetClassDescriptor final
37223746 TargetForeignMetadataInitialization<Runtime>;
37233747 using SingletonMetadataInitialization =
37243748 TargetSingletonMetadataInitialization<Runtime>;
3749+ using ObjCResilientClassStubInfo =
3750+ TargetObjCResilientClassStubInfo<Runtime>;
37253751
37263752 using StoredPointer = typename Runtime::StoredPointer;
37273753 using StoredPointerDifference = typename Runtime::StoredPointerDifference;
@@ -3759,7 +3785,9 @@ class TargetClassDescriptor final
37593785 // / positive size of metadata objects of this class (in words).
37603786 uint32_t MetadataPositiveSizeInWords;
37613787
3762- // Maybe add something here that's useful only for resilient types?
3788+ // / Otherwise, these flags are used to do things like indicating
3789+ // / the presence of an Objective-C resilient class stub.
3790+ ExtraClassDescriptorFlags ExtraClassFlags;
37633791 };
37643792
37653793 // / The number of additional members added by this class to the class
@@ -3835,6 +3863,10 @@ class TargetClassDescriptor final
38353863 return getOverrideTable ()->NumEntries ;
38363864 }
38373865
3866+ size_t numTrailingObjects (OverloadToken<ObjCResilientClassStubInfo>) const {
3867+ return hasObjCResilientClassStub () ? 1 : 0 ;
3868+ }
3869+
38383870public:
38393871 const TargetRelativeDirectPointer<Runtime, const void , /* nullable*/ true > &
38403872 getResilientSuperclass () const {
@@ -3954,7 +3986,24 @@ class TargetClassDescriptor final
39543986 && i < numTrailingObjects (OverloadToken<MethodDescriptor>{}));
39553987 return getMethodDescriptors ()[i].Impl .get ();
39563988 }
3957-
3989+
3990+ // / Whether this context descriptor references an Objective-C resilient
3991+ // / class stub. See the above description of TargetObjCResilientClassStubInfo
3992+ // / for details.
3993+ bool hasObjCResilientClassStub () const {
3994+ if (!hasResilientSuperclass ())
3995+ return false ;
3996+ return ExtraClassFlags.hasObjCResilientClassStub ();
3997+ }
3998+
3999+ const void *getObjCResilientClassStub () const {
4000+ if (!hasObjCResilientClassStub ())
4001+ return nullptr ;
4002+
4003+ return this ->template getTrailingObjects <ObjCResilientClassStubInfo>()
4004+ ->Stub .get ();
4005+ }
4006+
39584007 static bool classof (const TargetContextDescriptor<Runtime> *cd) {
39594008 return cd->getKind () == ContextDescriptorKind::Class;
39604009 }
0 commit comments