Skip to content

Commit 8b807c1

Browse files
committed
Cherry-pick #73128 (Handle resilient stored properties in objcImpl)
1 parent aa9094e commit 8b807c1

37 files changed

+1085
-229
lines changed

include/swift/AST/DiagnosticsIRGen.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,16 @@ NOTE(layout_strings_blocked,none,
6969
"Layout string value witnesses have been disabled for module '%0' "
7070
"through block list entry", (StringRef))
7171

72+
ERROR(attr_objc_implementation_resilient_property_not_supported, none,
73+
"'@implementation' does not support stored properties whose size can "
74+
"change due to library evolution; store this value in an object or 'any' "
75+
"type",
76+
())
77+
ERROR(attr_objc_implementation_resilient_property_deployment_target, none,
78+
"'@implementation' on %0 %1 does not support stored properties whose "
79+
"size can change due to library evolution; raise the minimum deployment "
80+
"target to %0 %2 or store this value in an object or 'any' type",
81+
(StringRef, const llvm::VersionTuple, const llvm::VersionTuple))
82+
7283
#define UNDEFINE_DIAGNOSTIC_MACROS
7384
#include "DefineDiagnosticMacros.h"

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,10 @@ ERROR(attr_objc_implementation_no_conformance,none,
17961796
"add this conformance %select{with an ordinary extension|"
17971797
"in the Objective-C header}1",
17981798
(Type, bool))
1799+
ERROR(attr_objc_implementation_raise_minimum_deployment_target,none,
1800+
"'@implementation' of an Objective-C class requires a minimum deployment "
1801+
"target of at least %0 %1",
1802+
(StringRef, llvm::VersionTuple))
17991803

18001804
ERROR(member_of_objc_implementation_not_objc_or_final,none,
18011805
"%kind0 does not match any %kindonly0 declared in the headers for %1; "

include/swift/AST/FeatureAvailability.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ FEATURE(IsolatedAny, (6, 0))
7474
FEATURE(TaskExecutor, FUTURE)
7575
FEATURE(Differentiation, FUTURE)
7676
FEATURE(InitRawStructMetadata, FUTURE)
77+
FEATURE(UpdatePureObjCClassMetadata, FUTURE)
7778

7879
#undef FEATURE
7980
#undef FUTURE

include/swift/Basic/Features.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,11 @@ EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE(MemberImportVisibility, true
378378
// Enable @implementation on extensions of ObjC classes.
379379
EXPERIMENTAL_FEATURE(ObjCImplementation, true)
380380

381+
// Enable @implementation on extensions of ObjC classes with non-fixed layout
382+
// due to resilient stored properties. Requires OS support; this flag exists for
383+
// staging purposes.
384+
EXPERIMENTAL_FEATURE(ObjCImplementationWithResilientStorage, true)
385+
381386
// Enable @implementation on @_cdecl functions.
382387
EXPERIMENTAL_FEATURE(CImplementation, true)
383388

include/swift/Runtime/Metadata.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,13 @@ swift_updateClassMetadata2(ClassMetadata *self,
782782
size_t numFields,
783783
const TypeLayout * const *fieldTypes,
784784
size_t *fieldOffsets);
785+
786+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
787+
Class
788+
swift_updatePureObjCClassMetadata(Class self,
789+
ClassLayoutFlags flags,
790+
size_t numFields,
791+
const TypeLayout * const *fieldTypes);
785792
#endif
786793

787794
/// Given class metadata, a class descriptor and a method descriptor, look up

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,19 @@ FUNCTION(UpdateClassMetadata2,
14371437
EFFECT(MetaData),
14381438
UNKNOWN_MEMEFFECTS)
14391439

1440+
// objc_class *swift_updatePureObjCClassMetadata(
1441+
// objc_class *self,
1442+
// ClassLayoutFlags flags,
1443+
// size_t numFields,
1444+
// TypeLayout * const *fieldTypes);
1445+
FUNCTION(UpdatePureObjCClassMetadata,
1446+
swift_updatePureObjCClassMetadata, SwiftCC, AlwaysAvailable,
1447+
RETURNS(ObjCClassPtrTy),
1448+
ARGS(ObjCClassPtrTy, SizeTy, SizeTy, Int8PtrPtrTy->getPointerTo()),
1449+
ATTRS(NoUnwind),
1450+
EFFECT(MetaData),
1451+
UNKNOWN_MEMEFFECTS)
1452+
14401453
// void *swift_lookUpClassMethod(Metadata *metadata,
14411454
// ClassDescriptor *description,
14421455
// MethodDescriptor *method);

lib/AST/FeatureSet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,7 @@ UNINTERESTING_FEATURE(IsolatedAny2)
762762

763763
UNINTERESTING_FEATURE(ObjCImplementation)
764764
UNINTERESTING_FEATURE(CImplementation)
765+
UNINTERESTING_FEATURE(ObjCImplementationWithResilientStorage)
765766

766767
UNINTERESTING_FEATURE(DebugDescriptionMacro)
767768

lib/IRGen/ClassMetadataVisitor.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SWIFT_IRGEN_CLASSMETADATAVISITOR_H
2020

2121
#include "swift/AST/ASTContext.h"
22+
#include "swift/AST/Decl.h"
2223
#include "swift/AST/SubstitutionMap.h"
2324
#include "swift/SIL/SILDeclRef.h"
2425
#include "swift/SIL/SILModule.h"
@@ -67,6 +68,9 @@ template <class Impl> class ClassMetadataVisitor
6768
: super(IGM), Target(target), VTable(vtable) {}
6869

6970
public:
71+
bool isPureObjC() const {
72+
return Target->getObjCImplementationDecl();
73+
}
7074

7175
// Layout in embedded mode while considering the class type.
7276
// This is important for adding the right superclass pointer.
@@ -93,6 +97,16 @@ template <class Impl> class ClassMetadataVisitor
9397
return;
9498
}
9599

100+
if (isPureObjC()) {
101+
assert(IGM.ObjCInterop);
102+
asImpl().noteAddressPoint();
103+
asImpl().addMetadataFlags();
104+
asImpl().addSuperclass();
105+
asImpl().addClassCacheData();
106+
asImpl().addClassDataPointer();
107+
return;
108+
}
109+
96110
// Pointer to layout string
97111
asImpl().addLayoutStringPointer();
98112

lib/IRGen/GenClass.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,12 +2561,27 @@ static llvm::Function *emitObjCMetadataUpdateFunction(IRGenModule &IGM,
25612561
Explosion params = IGF.collectParameters();
25622562
(void) params.claimAll();
25632563

2564-
// Just directly call our metadata accessor. This should actually
2565-
// return the same metadata; the Objective-C runtime enforces this.
2566-
auto type = D->getDeclaredType()->getCanonicalType();
2567-
auto *metadata = IGF.emitTypeMetadataRef(type,
2568-
MetadataState::Complete)
2569-
.getMetadata();
2564+
llvm::Value *metadata;
2565+
if (D->getObjCImplementationDecl()) {
2566+
// This is an @objc @implementation class, so it has no metadata completion
2567+
// function. We must do the completion function's work here, taking care to
2568+
// fetch the address of the ObjC class without going through either runtime.
2569+
metadata = IGM.getAddrOfObjCClass(D, NotForDefinition);
2570+
auto loweredTy = IGM.getLoweredType(D->getDeclaredTypeInContext());
2571+
2572+
IGF.emitInitializeFieldOffsetVector(loweredTy, metadata,
2573+
/*isVWTMutable=*/false,
2574+
/*collector=*/nullptr);
2575+
} else {
2576+
// Just call our metadata accessor, which will cause the Swift runtime to
2577+
// call the metadata completion function if there is one. This should
2578+
// actually return the same metadata; the Objective-C runtime enforces this.
2579+
auto type = D->getDeclaredType()->getCanonicalType();
2580+
metadata = IGF.emitTypeMetadataRef(type,
2581+
MetadataState::Complete)
2582+
.getMetadata();
2583+
}
2584+
25702585
IGF.Builder.CreateRet(
25712586
IGF.Builder.CreateBitCast(metadata,
25722587
IGM.ObjCClassPtrTy));

0 commit comments

Comments
 (0)