diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index 32dfde19d65aa..99cae11d0ac1a 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -2515,6 +2515,15 @@ void irgen::emitLazyTypeContextDescriptor(IRGenModule &IGM, void irgen::emitLazyTypeMetadata(IRGenModule &IGM, NominalTypeDecl *type) { eraseExistingTypeContextDescriptor(IGM, type); + // Special case, UFOs are opaque pointers for now. + if (auto cd = dyn_cast(type)) { + if (cd->isForeignReferenceType()) { + auto sd = cast(type->getASTContext().getOpaquePointerDecl()); + emitStructMetadata(IGM, sd); + return; + } + } + if (requiresForeignTypeMetadata(type)) { emitForeignTypeMetadata(IGM, type); } else if (auto sd = dyn_cast(type)) { diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp index b05cea28867e6..e3e43a74661ba 100644 --- a/lib/IRGen/GenReflection.cpp +++ b/lib/IRGen/GenReflection.cpp @@ -717,21 +717,21 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder { if (!type) { B.addInt32(0); } else { - if (type->isForeignReferenceType()) { - type->getASTContext().Diags.diagnose( - type->lookThroughAllOptionalTypes() - ->getClassOrBoundGenericClass() - ->getLoc(), - diag::foreign_reference_types_unsupported.ID, {}); - exit(1); - } - auto genericSig = NTD->getGenericSignature(); - // The standard library's Mirror demangles metadata from field - // descriptors, so use MangledTypeRefRole::Metadata to ensure - // runtime metadata is available. - addTypeRef(type, genericSig, MangledTypeRefRole::Metadata); + // Special case, UFOs are opaque pointers for now. + if (type->isForeignReferenceType()) { + auto opaqueType = type->getASTContext().getOpaquePointerType(); + // The standard library's Mirror demangles metadata from field + // descriptors, so use MangledTypeRefRole::Metadata to ensure + // runtime metadata is available. + addTypeRef(opaqueType, genericSig, MangledTypeRefRole::Metadata); + } else { + // The standard library's Mirror demangles metadata from field + // descriptors, so use MangledTypeRefRole::Metadata to ensure + // runtime metadata is available. + addTypeRef(type, genericSig, MangledTypeRefRole::Metadata); + } } if (IGM.IRGen.Opts.EnableReflectionNames) { diff --git a/test/Interop/Cxx/foreign-reference/error-as-class-member.swift b/test/Interop/Cxx/foreign-reference/error-as-class-member.swift deleted file mode 100644 index ba874d93b5e7b..0000000000000 --- a/test/Interop/Cxx/foreign-reference/error-as-class-member.swift +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: rm -rf %t -// RUN: split-file %s %t -// RUN: not %target-swift-frontend -emit-ir -I %t/Inputs %t/test.swift -enable-experimental-cxx-interop 2>&1 | %FileCheck %s - -// XFAIL: OS=windows-msvc - -//--- Inputs/module.modulemap -module Test { - header "test.h" - requires cplusplus -} - -//--- Inputs/test.h -#include - -inline void* operator new(size_t, void* p) { return p; } - -struct __attribute__((swift_attr("import_as_ref"))) Empty { - static Empty *create() { return new (malloc(sizeof(Empty))) Empty(); } -}; - -//--- test.swift - -import Test - -// CHECK: error: attempt to use a foreign reference type in a generic context. Foreign reference types are currently not supported. Using foreign reference types in a generic context is not yet implemented. -class C { let m: Empty = Empty.create() } diff --git a/test/Interop/Cxx/foreign-reference/error-as-struct-member.swift b/test/Interop/Cxx/foreign-reference/error-as-struct-member.swift deleted file mode 100644 index 1d3dac10ab250..0000000000000 --- a/test/Interop/Cxx/foreign-reference/error-as-struct-member.swift +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: rm -rf %t -// RUN: split-file %s %t -// RUN: not %target-swift-frontend -emit-ir -I %t/Inputs %t/test.swift -enable-experimental-cxx-interop 2>&1 | %FileCheck %s - -//--- Inputs/module.modulemap -module Test { - header "test.h" - requires cplusplus -} - -//--- Inputs/test.h -#include - -inline void* operator new(size_t, void* p) { return p; } - -struct __attribute__((swift_attr("import_as_ref"))) Empty { - static Empty *create() { return new (malloc(sizeof(Empty))) Empty(); } -}; - -//--- test.swift - -import Test - -// CHECK: error: attempt to use a foreign reference type in a generic context. Foreign reference types are currently not supported. Using foreign reference types in a generic context is not yet implemented. -struct S { let m: Empty } diff --git a/test/Interop/Cxx/foreign-reference/pod.swift b/test/Interop/Cxx/foreign-reference/pod.swift index 2f58a0e70bc17..6979d39da7a94 100644 --- a/test/Interop/Cxx/foreign-reference/pod.swift +++ b/test/Interop/Cxx/foreign-reference/pod.swift @@ -1,21 +1,20 @@ // RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-experimental-cxx-interop -Xfrontend -validate-tbd-against-ir=none -Xfrontend -disable-llvm-verify -g) // // REQUIRES: executable_test +// XFAIL: OS=windows-msvc import StdlibUnittest import POD -// TODO: Waiting on foreign reference type metadata implementation. -// -// struct StructHoldingPair { -// var pair: IntPair -// }; -// -// class ClassHoldingPair { -// var pair: IntPair -// -// init(pair: IntPair) { self.pair = pair } -// }; +struct StructHoldingPair { + var pair: IntPair +}; + +class ClassHoldingPair { + var pair: IntPair + + init(pair: IntPair) { self.pair = pair } +}; var globalPair: IntPair? = nil @@ -106,33 +105,31 @@ PODTestSuite.test("RefHoldingPairPtr") { expectEqual(x.test(), 41) } -// TODO: Waiting on foreign reference types metadata implementation. -// -// PODTestSuite.test("StructHoldingPair") { -// var x = StructHoldingPair(pair: IntPair.create()) -// expectEqual(x.pair.test(), 1) -// expectEqual(x.pair.testMutable(), 1) -// -// mutateIt(x.pair) -// expectEqual(x.pair.test(), 2) -// expectEqual(x.pair.testMutable(), 2) -// -// x.pair = IntPair.create() -// expectEqual(x.pair.test(), 1) -// } -// -// PODTestSuite.test("ClassHoldingPair") { -// var x = ClassHoldingPair(pair: IntPair.create()) -// expectEqual(x.pair.test(), 1) -// expectEqual(x.pair.testMutable(), 1) -// -// mutateIt(x.pair) -// expectEqual(x.pair.test(), 2) -// expectEqual(x.pair.testMutable(), 2) -// -// x.pair = IntPair.create() -// expectEqual(x.pair.test(), 1) -// } +PODTestSuite.test("StructHoldingPair") { + var x = StructHoldingPair(pair: IntPair.create()) + expectEqual(x.pair.test(), 1) + expectEqual(x.pair.testMutable(), 1) + + mutateIt(x.pair) + expectEqual(x.pair.test(), 2) + expectEqual(x.pair.testMutable(), 2) + + x.pair = IntPair.create() + expectEqual(x.pair.test(), 1) +} + +PODTestSuite.test("ClassHoldingPair") { + var x = ClassHoldingPair(pair: IntPair.create()) + expectEqual(x.pair.test(), 1) + expectEqual(x.pair.testMutable(), 1) + + mutateIt(x.pair) + expectEqual(x.pair.test(), 2) + expectEqual(x.pair.testMutable(), 2) + + x.pair = IntPair.create() + expectEqual(x.pair.test(), 1) +} PODTestSuite.test("BigType") { var x = BigType.create()