Skip to content

Commit ab71f7a

Browse files
committed
[IRGen] Foreign metadata is lazy metadata, always.
Treat foreign metadata as lazy metadata, emitted when needed. Fixes SR-9397 / rdar://problem/46423275. (cherry picked from commit f18aa80)
1 parent 9f7531d commit ab71f7a

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,12 @@ void IRGenerator::noteUseOfTypeGlobals(NominalTypeDecl *type,
11841184
// Try to create a new record of the fact that we used this type.
11851185
auto insertResult = LazyTypeGlobals.try_emplace(type);
11861186
auto &entry = insertResult.first->second;
1187-
1187+
1188+
// Imported structs and enums types are known to be lazy.
1189+
if (insertResult.second) {
1190+
entry.IsLazy = requiresForeignTypeMetadata(type);
1191+
}
1192+
11881193
bool metadataWasUsed = entry.IsMetadataUsed;
11891194
bool descriptorWasUsed = entry.IsDescriptorUsed;
11901195

lib/IRGen/GenMeta.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,10 @@ void irgen::emitLazyTypeContextDescriptor(IRGenModule &IGM,
16751675
void irgen::emitLazyTypeMetadata(IRGenModule &IGM, NominalTypeDecl *type) {
16761676
eraseExistingTypeContextDescriptor(IGM, type);
16771677

1678-
if (auto sd = dyn_cast<StructDecl>(type)) {
1678+
if (requiresForeignTypeMetadata(type)) {
1679+
(void)IGM.getAddrOfForeignTypeMetadataCandidate(
1680+
type->getDeclaredInterfaceType()->getCanonicalType());
1681+
} else if (auto sd = dyn_cast<StructDecl>(type)) {
16791682
return emitStructMetadata(IGM, sd);
16801683
} else if (auto ed = dyn_cast<EnumDecl>(type)) {
16811684
emitEnumMetadata(IGM, ed);
@@ -3878,7 +3881,8 @@ bool irgen::requiresForeignTypeMetadata(NominalTypeDecl *decl) {
38783881
llvm_unreachable("bad foreign class kind");
38793882
}
38803883

3881-
return isa<ClangModuleUnit>(decl->getModuleScopeContext());
3884+
return isa<ClangModuleUnit>(decl->getModuleScopeContext()) &&
3885+
!isa<ProtocolDecl>(decl);
38823886
}
38833887

38843888
llvm::Constant *

test/IRGen/extension_type_metadata_linking.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import Foundation
2121
// CHECK-LABEL: @"$sSo8NSNumberC31extension_type_metadata_linkingE6StructVMn" = constant
2222
// CHECK-LABEL: @"$sSo8NSNumberC31extension_type_metadata_linkingE6StructVMf" = internal constant
2323

24+
// CHECK-LABEL: "$sSo18NSComparisonResultVMn" = linkonce_odr hidden
25+
2426
// CHECK-LABEL: @"$sSo8NSNumberC31extension_type_metadata_linkingE4BaseCN" = alias
2527
// CHECK-LABEL: @"$sSo8NSNumberC31extension_type_metadata_linkingE7DerivedCN" = alias
2628
// CHECK-LABEL: @"$sSo8NSNumberC31extension_type_metadata_linkingE6StructVN" = alias
@@ -47,3 +49,22 @@ extension NSNumber {
4749
public struct Struct {}
4850
}
4951

52+
// SR-9397: not emitting metadata for NSComparisonResult
53+
protocol CommandTypes {
54+
associatedtype Result
55+
associatedtype Message
56+
}
57+
58+
struct EnumCommand: CommandTypes {
59+
typealias Result = ComparisonResult
60+
typealias Message = String
61+
}
62+
63+
struct Command<T: CommandTypes> {
64+
var result: T.Result?
65+
var message: T.Message?
66+
}
67+
68+
func createCommandArray() -> Any {
69+
return [Command<EnumCommand>]()
70+
}

0 commit comments

Comments
 (0)