Skip to content

Commit c078113

Browse files
committed
[Generated header] Emit members of enum extensions into C++ class
As we do with Swift structs, emit the members of extensions of Swift enums into the corresponding C++ class. This includes exposing more of the Optional API from the standard library into Swift.
1 parent 1752b48 commit c078113

File tree

4 files changed

+29
-5
lines changed

4 files changed

+29
-5
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,14 @@ class DeclAndTypePrinter::Implementation
882882
os << "\n";
883883

884884
printMembers(ED->getMembers());
885+
886+
for (const auto *ext :
887+
owningPrinter.interopContext.getExtensionsForNominalType(ED)) {
888+
if (!cxx_translation::isExposableToCxx(ext->getGenericSignature()))
889+
continue;
890+
891+
printMembers(ext->getMembers());
892+
}
885893
},
886894
owningPrinter);
887895
recordEmittedDeclInCurrentCxxLexicalScope(ED);
@@ -2782,13 +2790,13 @@ static bool isStringNestedType(const ValueDecl *VD, StringRef Typename) {
27822790
VD->getASTContext().getStringDecl();
27832791
}
27842792

2785-
static bool hasExposeAttr(const ValueDecl *VD, bool isExtension = false) {
2793+
static bool hasExposeAttr(const ValueDecl *VD) {
27862794
if (isa<NominalTypeDecl>(VD) && VD->getModuleContext()->isStdlibModule()) {
27872795
if (VD == VD->getASTContext().getStringDecl())
27882796
return true;
27892797
if (VD == VD->getASTContext().getArrayDecl())
27902798
return true;
2791-
if (VD == VD->getASTContext().getOptionalDecl() && !isExtension)
2799+
if (VD == VD->getASTContext().getOptionalDecl())
27922800
return true;
27932801
if (isStringNestedType(VD, "UTF8View") || isStringNestedType(VD, "Index"))
27942802
return true;
@@ -2825,7 +2833,7 @@ static bool hasExposeAttr(const ValueDecl *VD, bool isExtension = false) {
28252833
return false;
28262834
}
28272835

2828-
return hasExposeAttr(ED->getExtendedNominal(), /*isExtension=*/true);
2836+
return hasExposeAttr(ED->getExtendedNominal());
28292837
}
28302838
return false;
28312839
}

lib/PrintAsClang/ModuleContentsWriter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ class ModuleWriter {
750750
for (const Decl *D : declsToWrite) {
751751
if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
752752
const auto *type = ED->getExtendedNominal();
753-
if (isa<StructDecl>(type))
753+
if (isa<StructDecl>(type) || isa<EnumDecl>(type))
754754
printer.getInteropContext().recordExtensions(type, ED);
755755
}
756756
}

test/Interop/SwiftToCxx/enums/enum-associated-value-class-type-cxx.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ public enum E {
1414
case i(Int)
1515
}
1616

17+
extension E {
18+
public func matchesIntValue(_ value: Int) -> Bool {
19+
switch self {
20+
case .c:
21+
return false
22+
23+
case .i(let mine):
24+
return mine == value
25+
}
26+
}
27+
}
28+
1729
// CHECK: SWIFT_INLINE_THUNK E E::_impl_c::operator()(const C& val) const {
1830
// CHECK-NEXT: auto result = E::_make();
1931
// CHECK-NEXT: auto op = swift::_impl::_impl_RefCountedClass::copyOpaquePointer(val);
@@ -29,3 +41,6 @@ public enum E {
2941
// CHECK-NEXT: char * _Nonnull payloadFromDestruction = thisCopy->_destructiveProjectEnumData();
3042
// CHECK-NEXT: return swift::_impl::implClassFor<C>::type::makeRetained(*reinterpret_cast<void **>(payloadFromDestruction));
3143
// CHECK-NEXT: }
44+
45+
// CHECK: SWIFT_INLINE_THUNK bool E::matchesIntValue(swift::Int value) const {
46+
// CHECK-NEXT: return _impl::$s5Enums1EO15matchesIntValueySbSiF(value, _impl::swift_interop_passDirect_Enums_uint64_t_0_8_uint8_t_8_9(_getOpaquePointer()));

test/Interop/SwiftToCxx/stdlib/swift-stdlib-in-cxx.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
// CHECK-NEXT: };
6767
// CHECK: SWIFT_INLINE_THUNK bool isSome() const;
6868
// CHECK: SWIFT_INLINE_THUNK bool isNone() const;
69-
// CHECK: SWIFT_INLINE_THUNK T_0_0 getUnsafelyUnwrapped() const SWIFT_SYMBOL({{.*}});
69+
// CHECK-DAG: SWIFT_INLINE_THUNK T_0_0 getUnsafelyUnwrapped() const SWIFT_SYMBOL({{.*}});
70+
// CHECK-DAG: SWIFT_INLINE_THUNK String getDebugDescription() const SWIFT_SYMBOL("s:SqslE16debugDescriptionSSvp");
7071

7172
// CHECK: class SWIFT_SYMBOL({{.*}}) String final {
7273
// CHECK-NEXT: public:

0 commit comments

Comments
 (0)