Skip to content

Commit 3b6ec6c

Browse files
committed
IRGen: Move some deployment target checks to LangOptions
1 parent f863700 commit 3b6ec6c

File tree

8 files changed

+44
-44
lines changed

8 files changed

+44
-44
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,15 @@ namespace swift {
385385
return EffectiveLanguageVersion.isVersionAtLeast(major, minor);
386386
}
387387

388+
// The following deployment targets ship an Objective-C runtime supporting
389+
// the class metadata update callback mechanism:
390+
//
391+
// - macOS 10.14.4
392+
// - iOS 12.2
393+
// - tvOS 12.2
394+
// - watchOS 5.2
395+
bool doesTargetSupportObjCMetadataUpdateCallback() const;
396+
388397
/// Returns true if the given platform condition argument represents
389398
/// a supported target operating system.
390399
///

lib/Basic/LangOptions.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,16 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
275275

276276
return { false, false };
277277
}
278+
279+
bool LangOptions::doesTargetSupportObjCMetadataUpdateCallback() const {
280+
if (Target.isMacOSX())
281+
return !Target.isMacOSXVersionLT(10, 14, 4);
282+
if (Target.isiOS()) // also returns true on tvOS
283+
return !Target.isOSVersionLT(12, 2);
284+
if (Target.isWatchOS())
285+
return !Target.isOSVersionLT(5, 2);
286+
287+
// If we're running on a non-Apple platform, we still want to allow running
288+
// tests that -enable-objc-interop.
289+
return false;
290+
}

lib/IRGen/GenClass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2327,7 +2327,7 @@ IRGenModule::getClassMetadataStrategy(const ClassDecl *theClass) {
23272327

23282328
// If the Objective-C runtime is new enough, we can just use the update
23292329
// pattern unconditionally.
2330-
if (Types.doesPlatformSupportObjCMetadataUpdateCallback())
2330+
if (Context.LangOpts.doesTargetSupportObjCMetadataUpdateCallback())
23312331
return ClassMetadataStrategy::Update;
23322332

23332333
// Otherwise, check if we have legacy type info for backward deployment.

lib/IRGen/GenDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,8 +1483,8 @@ void IRGenerator::emitEagerClassInitialization() {
14831483
RegisterFn->setCallingConv(IGM->DefaultCC);
14841484

14851485
for (ClassDecl *CD : ClassesForEagerInitialization) {
1486-
Type Ty = CD->getDeclaredType();
1487-
llvm::Value *MetaData = RegisterIGF.emitTypeMetadataRef(getAsCanType(Ty));
1486+
auto Ty = CD->getDeclaredType()->getCanonicalType();
1487+
llvm::Value *MetaData = RegisterIGF.emitTypeMetadataRef(Ty);
14881488
assert(CD->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>());
14891489

14901490
// Get the metadata to make sure that the class is registered. We need to

lib/IRGen/GenType.cpp

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,37 +1147,19 @@ static bool doesPlatformUseLegacyLayouts(StringRef platformName,
11471147
return false;
11481148
}
11491149

1150-
// The following Apple platforms ship an Objective-C runtime supporting
1151-
// the class metadata update hook:
1152-
//
1153-
// - macOS 10.14.4
1154-
// - iOS 12.2
1155-
// - tvOS 12.2
1156-
// - watchOS 5.2
1157-
static bool doesPlatformSupportObjCMetadataUpdateCallback(
1158-
const llvm::Triple &triple) {
1159-
if (triple.isMacOSX())
1160-
return !triple.isMacOSXVersionLT(10, 14, 4);
1161-
if (triple.isiOS()) // also returns true on tvOS
1162-
return !triple.isOSVersionLT(12, 2);
1163-
if (triple.isWatchOS())
1164-
return !triple.isOSVersionLT(5, 2);
1165-
1166-
return false;
1167-
}
1168-
11691150
TypeConverter::TypeConverter(IRGenModule &IGM)
11701151
: IGM(IGM),
11711152
FirstType(invalidTypeInfo()) {
1172-
const auto &Triple = IGM.Context.LangOpts.Target;
1173-
1174-
SupportsObjCMetadataUpdateCallback =
1175-
::doesPlatformSupportObjCMetadataUpdateCallback(Triple);
1153+
// Whether the Objective-C runtime is guaranteed to invoke the class
1154+
// metadata update callback when realizing a Swift class referenced from
1155+
// Objective-C.
1156+
bool supportsObjCMetadataUpdateCallback =
1157+
IGM.Context.LangOpts.doesTargetSupportObjCMetadataUpdateCallback();
11761158

11771159
// If our deployment target allows us to rely on the metadata update
11781160
// callback being called, we don't have to emit a legacy layout for a
11791161
// class with resiliently-sized fields.
1180-
if (SupportsObjCMetadataUpdateCallback)
1162+
if (supportsObjCMetadataUpdateCallback)
11811163
return;
11821164

11831165
// We have a bunch of -parse-stdlib tests that pass a -target in the test
@@ -1191,6 +1173,8 @@ TypeConverter::TypeConverter(IRGenModule &IGM)
11911173

11921174
StringRef path = IGM.IRGen.Opts.ReadLegacyTypeInfoPath;
11931175
if (path.empty()) {
1176+
const auto &Triple = IGM.Context.LangOpts.Target;
1177+
11941178
// If the flag was not explicitly specified, look for a file in a
11951179
// platform-specific location, if this platform is known to require
11961180
// one.

lib/IRGen/GenType.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ class TypeConverter {
114114
const LoadableTypeInfo *SwiftRetainablePointerBoxTI = nullptr,
115115
*UnknownObjectRetainablePointerBoxTI = nullptr;
116116

117-
bool SupportsObjCMetadataUpdateCallback = false;
118117
llvm::StringMap<YAMLTypeInfoNode> LegacyTypeInfos;
119118
llvm::DenseMap<NominalTypeDecl *, std::string> DeclMangledNames;
120119

@@ -160,10 +159,6 @@ class TypeConverter {
160159
return LoweringMode;
161160
}
162161

163-
bool doesPlatformSupportObjCMetadataUpdateCallback() const {
164-
return SupportsObjCMetadataUpdateCallback;
165-
}
166-
167162
const TypeInfo *getTypeEntry(CanType type);
168163
const TypeInfo &getCompleteTypeInfo(CanType type);
169164
const LoadableTypeInfo &getNativeObjectTypeInfo();

lib/IRGen/IRGenModule.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -814,15 +814,8 @@ void IRGenerator::addClassForEagerInitialization(ClassDecl *ClassDecl) {
814814
if (!ClassDecl->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>())
815815
return;
816816

817-
// Exclude some classes where those attributes make no sense but could be set
818-
// for some reason. Just to be on the safe side.
819-
Type ClassTy = ClassDecl->getDeclaredType();
820-
if (ClassTy->is<UnboundGenericType>())
821-
return;
822-
if (ClassTy->hasArchetype())
823-
return;
824-
if (ClassDecl->hasClangNode())
825-
return;
817+
assert(!ClassDecl->isGenericContext());
818+
assert(!ClassDecl->hasClangNode());
826819

827820
ClassesForEagerInitialization.push_back(ClassDecl);
828821
}

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4756,11 +4756,16 @@ static bool isNSCoding(ProtocolDecl *protocol) {
47564756

47574757
/// Whether the given class has an explicit '@objc' name.
47584758
static bool hasExplicitObjCName(ClassDecl *classDecl) {
4759+
// FIXME: Turn this function into a request instead of computing this
4760+
// as part of the @objc request.
4761+
(void) classDecl->isObjC();
4762+
47594763
if (classDecl->getAttrs().hasAttribute<ObjCRuntimeNameAttr>())
47604764
return true;
47614765

47624766
auto objcAttr = classDecl->getAttrs().getAttribute<ObjCAttr>();
4763-
if (!objcAttr) return false;
4767+
if (!objcAttr)
4768+
return false;
47644769

47654770
return objcAttr->hasName() && !objcAttr->isNameImplicit();
47664771
}
@@ -4843,7 +4848,7 @@ static void inferStaticInitializeObjCMetadata(TypeChecker &tc,
48434848
// If this class isn't always available on the deployment target, don't
48444849
// mark it as statically initialized.
48454850
// FIXME: This is a workaround. The proper solution is for IRGen to
4846-
// only statically initializae the Objective-C metadata when running on
4851+
// only statically initialize the Objective-C metadata when running on
48474852
// a new-enough OS.
48484853
if (auto sourceFile = classDecl->getParentSourceFile()) {
48494854
AvailabilityContext availableInfo = AvailabilityContext::alwaysAvailable();
@@ -4993,7 +4998,8 @@ void TypeChecker::checkConformancesInContext(DeclContext *dc,
49934998
if (auto classDecl = dc->getSelfClassDecl()) {
49944999
if (Context.LangOpts.EnableObjCInterop &&
49955000
isNSCoding(conformance->getProtocol()) &&
4996-
!classDecl->isGenericContext()) {
5001+
!classDecl->isGenericContext() &&
5002+
!classDecl->hasClangNode()) {
49975003
diagnoseUnstableName(*this, conformance, classDecl);
49985004
// Infer @_staticInitializeObjCMetadata if needed.
49995005
inferStaticInitializeObjCMetadata(*this, classDecl);

0 commit comments

Comments
 (0)