Skip to content

Commit 5fe6f85

Browse files
committed
---
yaml --- r: 347342 b: refs/heads/master c: 36d8c65 h: refs/heads/master
1 parent 7273a52 commit 5fe6f85

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+900
-323
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: fd5947d7b51688cc8f0cf0a71094dc798d5b26d7
2+
refs/heads/master: 36d8c65f535618aa7acf9d6d708ad13052789de5
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/docs/ABI/Mangling.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ Globals
112112
global ::= nominal-type 'Mn' // nominal type descriptor
113113
global ::= nominal-type 'Mu' // class method lookup function
114114
global ::= nominal-type 'MU' // ObjC metadata update callback function
115+
global ::= nominal-type 'Ms' // ObjC resilient class stub
116+
global ::= nominal-type 'Mt' // Full ObjC resilient class stub (private)
115117
global ::= module 'MXM' // module descriptor
116118
global ::= context 'MXE' // extension descriptor
117119
global ::= context 'MXX' // anonymous context descriptor

trunk/include/swift/ABI/Metadata.h

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
36863708
template <typename Runtime>
36873709
class 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>> {
36993722
private:
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+
38383870
public:
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
}

trunk/include/swift/ABI/MetadataValues.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,28 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
13091309
class_setResilientSuperclassReferenceKind)
13101310
};
13111311

1312+
/// Extra flags for resilient classes, since we need more than 16 bits of
1313+
/// flags there.
1314+
class ExtraClassDescriptorFlags : public FlagSet<uint32_t> {
1315+
enum {
1316+
/// Set if the context descriptor includes a pointer to an Objective-C
1317+
/// resilient class stub structure. See the description of
1318+
/// TargetObjCResilientClassStubInfo in Metadata.h for details.
1319+
///
1320+
/// Only meaningful for class descriptors when Objective-C interop is
1321+
/// enabled.
1322+
HasObjCResilientClassStub = 0,
1323+
};
1324+
1325+
public:
1326+
explicit ExtraClassDescriptorFlags(uint32_t bits) : FlagSet(bits) {}
1327+
constexpr ExtraClassDescriptorFlags() {}
1328+
1329+
FLAGSET_DEFINE_FLAG_ACCESSORS(HasObjCResilientClassStub,
1330+
hasObjCResilientClassStub,
1331+
setObjCResilientClassStub)
1332+
};
1333+
13121334
/// Flags for protocol context descriptors. These values are used as the
13131335
/// kindSpecificFlags of the ContextDescriptorFlags for the protocol.
13141336
class ProtocolContextDescriptorFlags : public FlagSet<uint16_t> {

trunk/include/swift/AST/Decl.h

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ class alignas(1 << DeclAlignInBits) Decl {
542542
NumRequirementsInSignature : 16
543543
);
544544

545-
SWIFT_INLINE_BITFIELD(ClassDecl, NominalTypeDecl, 1+2+1+2+1+3+1+1+1+1,
545+
SWIFT_INLINE_BITFIELD(ClassDecl, NominalTypeDecl, 1+2+1+2+1+6+1+1+1,
546546
/// Whether this class requires all of its instance variables to
547547
/// have in-class initializers.
548548
RequiresStoredPropertyInits : 1,
@@ -563,12 +563,11 @@ class alignas(1 << DeclAlignInBits) Decl {
563563
/// control inserting the implicit destructor.
564564
HasDestructorDecl : 1,
565565

566-
/// Whether the class has @objc ancestry.
567-
ObjCKind : 3,
566+
/// Information about the class's ancestry.
567+
Ancestry : 6,
568568

569-
/// Whether this class has @objc members.
570-
HasObjCMembersComputed : 1,
571-
HasObjCMembers : 1,
569+
/// Whether we have computed the above field or not.
570+
AncestryComputed : 1,
572571

573572
HasMissingDesignatedInitializers : 1,
574573
HasMissingVTableEntries : 1
@@ -3545,21 +3544,33 @@ enum class ArtificialMainKind : uint8_t {
35453544
UIApplicationMain,
35463545
};
35473546

3548-
enum class ObjCClassKind : uint8_t {
3549-
/// Neither the class nor any of its superclasses are @objc.
3550-
NonObjC,
3551-
/// One of the superclasses is @objc but another superclass or the
3552-
/// class itself has generic parameters, so while it cannot be
3553-
/// directly represented in Objective-C, it has implicitly @objc
3554-
/// members.
3555-
ObjCMembers,
3556-
/// The top-level ancestor of this class is not @objc, but the
3557-
/// class itself is.
3558-
ObjCWithSwiftRoot,
3559-
/// The class is bona-fide @objc.
3560-
ObjC,
3547+
/// This is the base type for AncestryOptions. Each flag describes possible
3548+
/// interesting kinds of superclasses that a class may have.
3549+
enum class AncestryFlags : uint8_t {
3550+
/// The class or one of its superclasses is @objc.
3551+
ObjC = (1<<0),
3552+
3553+
/// The class or one of its superclasses is @objcMembers.
3554+
ObjCMembers = (1<<1),
3555+
3556+
/// The class or one of its superclasses is generic.
3557+
Generic = (1<<2),
3558+
3559+
/// The class or one of its superclasses is resilient.
3560+
Resilient = (1<<3),
3561+
3562+
/// The class or one of its superclasses has resilient metadata and is in a
3563+
/// different resilience domain.
3564+
ResilientOther = (1<<4),
3565+
3566+
/// The class or one of its superclasses is imported from Clang.
3567+
ClangImported = (1<<5),
35613568
};
35623569

3570+
/// Return type of ClassDecl::checkAncestry(). Describes a set of interesting
3571+
/// kinds of superclasses that a class may have.
3572+
using AncestryOptions = OptionSet<AncestryFlags>;
3573+
35633574
/// ClassDecl - This is the declaration of a class, for example:
35643575
///
35653576
/// class Complex { var R : Double, I : Double }
@@ -3589,8 +3600,6 @@ class ClassDecl final : public NominalTypeDecl {
35893600
friend class SuperclassTypeRequest;
35903601
friend class TypeChecker;
35913602

3592-
bool hasObjCMembersSlow();
3593-
35943603
public:
35953604
ClassDecl(SourceLoc ClassLoc, Identifier Name, SourceLoc NameLoc,
35963605
MutableArrayRef<TypeLoc> Inherited,
@@ -3622,6 +3631,9 @@ class ClassDecl final : public NominalTypeDecl {
36223631
/// is no superclass.
36233632
ClassDecl *getSuperclassDecl() const;
36243633

3634+
/// Check if this class is a superclass or equal to the given class.
3635+
bool isSuperclassOf(ClassDecl *other) const;
3636+
36253637
/// Set the superclass of this class.
36263638
void setSuperclass(Type superclass);
36273639

@@ -3749,18 +3761,13 @@ class ClassDecl final : public NominalTypeDecl {
37493761
Bits.ClassDecl.InheritsSuperclassInits = true;
37503762
}
37513763

3752-
/// Returns if this class has any @objc ancestors, or if it is directly
3753-
/// visible to Objective-C. The latter is a stronger condition which is only
3754-
/// true if the class does not have any generic ancestry.
3755-
ObjCClassKind checkObjCAncestry() const;
3756-
3757-
/// Returns if the class has implicitly @objc members. This is true if any
3758-
/// ancestor class has the @objcMembers attribute.
3759-
bool hasObjCMembers() const {
3760-
if (Bits.ClassDecl.HasObjCMembersComputed)
3761-
return Bits.ClassDecl.HasObjCMembers;
3764+
/// Walks the class hierarchy starting from this class, checking various
3765+
/// conditions.
3766+
AncestryOptions checkAncestry() const;
37623767

3763-
return const_cast<ClassDecl *>(this)->hasObjCMembersSlow();
3768+
/// Check if the class has ancestry of the given kind.
3769+
bool checkAncestry(AncestryFlags flag) const {
3770+
return checkAncestry().contains(flag);
37643771
}
37653772

37663773
/// The type of metaclass to use for a class.

trunk/include/swift/AST/DiagnosticsSema.def

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3592,9 +3592,11 @@ ERROR(invalid_nonobjc_extension,none,
35923592
ERROR(objc_in_extension_context,none,
35933593
"members of constrained extensions cannot be declared @objc", ())
35943594
ERROR(objc_in_generic_extension,none,
3595-
"members of extensions of "
3596-
"%select{classes from generic context|generic classes}0 "
3597-
"cannot be declared @objc", (bool))
3595+
"extensions of %select{classes from generic context|generic classes}0 "
3596+
"cannot contain '@objc' members", (bool))
3597+
ERROR(objc_in_resilient_extension,none,
3598+
"extensions of classes built with library evolution support "
3599+
"cannot contain '@objc' members", ())
35983600
ERROR(objc_operator, none,
35993601
"operator methods cannot be declared @objc", ())
36003602
ERROR(objc_operator_proto, none,
@@ -3615,6 +3617,10 @@ NOTE(objc_inference_swift3_addnonobjc,none,
36153617
ERROR(objc_for_generic_class,none,
36163618
"generic subclasses of '@objc' classes cannot have an explicit '@objc' "
36173619
"because they are not directly visible from Objective-C", ())
3620+
ERROR(objc_for_resilient_class,none,
3621+
"classes built with library evolution support cannot have explicit "
3622+
"'@objc' subclasses because they are not directly "
3623+
"visible from Objective-C", ())
36183624
ERROR(objc_getter_for_nonobjc_property,none,
36193625
"'@objc' getter for non-'@objc' property", ())
36203626
ERROR(objc_getter_for_nonobjc_subscript,none,

trunk/include/swift/AST/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ class ModuleDecl : public DeclContext, public TypeDecl {
324324
Bits.ModuleDecl.RawResilienceStrategy = unsigned(strategy);
325325
}
326326

327+
bool isResilient() const {
328+
return getResilienceStrategy() != ResilienceStrategy::Default;
329+
}
330+
327331
/// Look up a (possibly overloaded) value set at top-level scope
328332
/// (but with the specified access path, which may come from an import decl)
329333
/// within the current module.

trunk/include/swift/Basic/LangOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ namespace swift {
296296
/// set to true.
297297
bool ExperimentalDependenciesIncludeIntrafileOnes = false;
298298

299+
/// Enable experimental support for emitting Objective-C resilient class
300+
/// stubs. This is a language option since it also determines if we admit
301+
/// @objc members in extensions of classes with resilient ancestry.
302+
bool EnableObjCResilientClassStubs = false;
303+
299304
/// Sets the target we are building for and updates platform conditions
300305
/// to match.
301306
///

trunk/include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ NODE(MetatypeRepresentation)
134134
NODE(Metaclass)
135135
NODE(MethodLookupFunction)
136136
NODE(ObjCMetadataUpdateFunction)
137+
NODE(ObjCResilientClassStub)
138+
NODE(FullObjCResilientClassStub)
137139
CONTEXT_NODE(ModifyAccessor)
138140
CONTEXT_NODE(Module)
139141
CONTEXT_NODE(NativeOwningAddressor)

trunk/include/swift/IRGen/Linking.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class LinkEntity {
9696
// This field appears in the ValueWitness kind.
9797
ValueWitnessShift = 8, ValueWitnessMask = 0xFF00,
9898

99-
// This field appears in the TypeMetadata kind.
99+
// This field appears in the TypeMetadata and ObjCResilientClassStub kinds.
100100
MetadataAddressShift = 8, MetadataAddressMask = 0x0300,
101101

102102
// This field appears in associated type access functions.
@@ -164,6 +164,12 @@ class LinkEntity {
164164
/// ClassMetadataStrategy::Update or ::FixedOrUpdate.
165165
ObjCMetadataUpdateFunction,
166166

167+
/// A stub that we emit to allow Clang-generated code to statically refer
168+
/// to Swift classes with resiliently-sized metadata, since the metadata
169+
/// is not statically-emitted. Used when getClassMetadataStrategy() is
170+
/// equal to ClassMetadataStrategy::Resilient.
171+
ObjCResilientClassStub,
172+
167173
/// A class metadata base offset global variable. This stores the offset
168174
/// of the immediate members of a class (generic parameters, field offsets,
169175
/// vtable offsets) in the class's metadata. The immediate members begin
@@ -613,13 +619,19 @@ class LinkEntity {
613619
return entity;
614620
}
615621

622+
static LinkEntity forObjCResilientClassStub(ClassDecl *decl,
623+
TypeMetadataAddress addr) {
624+
LinkEntity entity;
625+
entity.setForDecl(Kind::ObjCResilientClassStub, decl);
626+
entity.Data |= LINKENTITY_SET_FIELD(MetadataAddress, unsigned(addr));
627+
return entity;
628+
}
629+
616630
static LinkEntity forTypeMetadata(CanType concreteType,
617631
TypeMetadataAddress addr) {
618632
LinkEntity entity;
619-
entity.Pointer = concreteType.getPointer();
620-
entity.SecondaryPointer = nullptr;
621-
entity.Data = LINKENTITY_SET_FIELD(Kind, unsigned(Kind::TypeMetadata))
622-
| LINKENTITY_SET_FIELD(MetadataAddress, unsigned(addr));
633+
entity.setForType(Kind::TypeMetadata, concreteType);
634+
entity.Data |= LINKENTITY_SET_FIELD(MetadataAddress, unsigned(addr));
623635
return entity;
624636
}
625637

@@ -1021,7 +1033,8 @@ class LinkEntity {
10211033
return ValueWitness(LINKENTITY_GET_FIELD(Data, ValueWitness));
10221034
}
10231035
TypeMetadataAddress getMetadataAddress() const {
1024-
assert(getKind() == Kind::TypeMetadata);
1036+
assert(getKind() == Kind::TypeMetadata ||
1037+
getKind() == Kind::ObjCResilientClassStub);
10251038
return (TypeMetadataAddress)LINKENTITY_GET_FIELD(Data, MetadataAddress);
10261039
}
10271040
bool isForeignTypeMetadataCandidate() const {

trunk/include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,4 +555,8 @@ def type_info_dump_filter_EQ : Joined<["-"], "type-info-dump-filter=">,
555555
Flags<[FrontendOption]>,
556556
HelpText<"One of 'all', 'resilient' or 'fragile'">;
557557

558+
def enable_objc_resilient_class_stubs : Flag<["-"], "enable-resilient-objc-class-stubs">,
559+
HelpText<"Emit Objective-C resilient class stubs for classes with "
560+
"resiliently-sized metadata">;
561+
558562
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

0 commit comments

Comments
 (0)