[IRGen] Consistently record runtime metadata for foreign types.

All Swift-defined nominal types have their runtime metadata recorded
in a special section, so it can be found later. This recording is
suppressed when that type is stated to conform to a protocol, because
the runtime can find nominal types in either place.

Imported types would get their conformances recorded, but would not
get recorded in the runtime metadata record otherwose. Therefore, the
runtime would not be able to find such types by name.

For any foreign type whose metadata we emit, make sure that metadata
can be found by a runtime lookup.
This commit is contained in:
Doug Gregor
2018-01-20 22:06:33 -08:00
parent 30ecd8ed7f
commit 902ea27a67
5 changed files with 15 additions and 12 deletions

View File

@@ -752,6 +752,11 @@ hasExplicitProtocolConformance(NominalTypeDecl *decl) {
if (conformance->getKind() == ProtocolConformanceKind::Inherited)
continue;
// Ignore conformances synthesized by the Clang importer.
if (isa<ClangModuleUnit>(
conformance->getDeclContext()->getModuleScopeContext()))
continue;
auto P = conformance->getProtocol();
// @objc protocols do not have conformance records
@@ -2826,8 +2831,7 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
if (!section.empty())
var->setSection(section);
// Keep type metadata around for all types, although the runtime can currently
// only perform name lookup of non-generic types.
// Keep type metadata around for all types.
addRuntimeResolvableType(concreteType);
// For metadata patterns, we're done.

View File

@@ -5307,8 +5307,8 @@ IRGenModule::getAddrOfForeignTypeMetadataCandidate(CanType type) {
llvm_unreachable("foreign metadata for unexpected type?!");
}
if (NominalTypeDecl *Nominal = type->getAnyNominal())
addLazyConformances(Nominal);
// Keep type metadata around for all types.
addRuntimeResolvableType(type);
return result;
}

View File

@@ -97,8 +97,8 @@ static inline void doubleTrouble(void) {
staticFloat *= 2.0;
}
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
typedef NS_ENUM(int, AmazingColor) {
typedef SWIFT_ENUM(int, AmazingColor) {
Cyan, Magenta, Yellow
};

View File

@@ -24,6 +24,11 @@ import c_layout
// CHECK-SAME: [[INT]] 0,
// CHECK-SAME: [[INT]] 4 }
// CHECK-LABEL: @"\01l_type_metadata_table" = private constant
// CHECK-SAME: @"$SSo14HasNestedUnionVMn"
// CHECK-SAME: @"$SSo12AmazingColorVMn"
// CHECK-SAME: @"$SSo14HasNestedUnionV18__Unnamed_struct_sVMn"
sil @test0 : $() -> () {
bb0:
%0 = metatype $@thick HasNestedUnion.Type

View File

@@ -42,9 +42,6 @@ DemangleToMetadataTests.test("Classes that don't exist") {
expectNil(_typeByMangledName("4main4BoomC"))
}
// FIXME: Shouldn't need this?
extension CFArray: P2 { }
DemangleToMetadataTests.test("CoreFoundation classes") {
expectEqual(CFArray.self, _typeByMangledName("So10CFArrayRefa")!)
}
@@ -60,9 +57,6 @@ DemangleToMetadataTests.test("Imported swift_wrapper types") {
_typeByMangledName("So21NSURLFileResourceTypea")!)
}
// FIXME: Shouldn't need this?
extension URLSessionTask.State: P2 { }
DemangleToMetadataTests.test("Imported enum types") {
expectEqual(NSURLSessionTask.State.self,
_typeByMangledName("So21NSURLSessionTaskStateV")!)