Skip to content

Commit 673da6b

Browse files
authored
Merge pull request swiftlang#80017 from swiftlang/gaborh/pod-foreign-types
[cxx-interop] Fix exporting Swift enums with C POD associated data
2 parents bf387c5 + e7a8fb1 commit 673da6b

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/AST/GenericEnvironment.h"
3333
#include "swift/AST/PrettyStackTrace.h"
3434
#include "swift/AST/SwiftNameTranslation.h"
35+
#include "swift/AST/Type.h"
3536
#include "swift/AST/TypeCheckRequests.h"
3637
#include "swift/AST/TypeVisitor.h"
3738
#include "swift/AST/Types.h"
@@ -45,6 +46,7 @@
4546
#include "clang/AST/ASTContext.h"
4647
#include "clang/AST/Attr.h"
4748
#include "clang/AST/Decl.h"
49+
#include "clang/AST/DeclCXX.h"
4850
#include "clang/AST/DeclObjC.h"
4951
#include "clang/Basic/CharInfo.h"
5052
#include "clang/Basic/SourceManager.h"
@@ -475,6 +477,17 @@ class DeclAndTypePrinter::Implementation
475477
os << "@end\n";
476478
}
477479

480+
static bool isClangPOD(const NominalTypeDecl *ntd) {
481+
auto clangDecl = ntd->getClangDecl();
482+
if (!clangDecl)
483+
return false;
484+
if (const auto *rd = dyn_cast<clang::RecordDecl>(clangDecl)) {
485+
return !isa<clang::CXXRecordDecl>(rd) ||
486+
cast<clang::CXXRecordDecl>(rd)->isPOD();
487+
}
488+
return false;
489+
}
490+
478491
void visitEnumDeclCxx(EnumDecl *ED) {
479492
assert(owningPrinter.outputLang == OutputLanguageMode::Cxx);
480493

@@ -588,7 +601,9 @@ class DeclAndTypePrinter::Implementation
588601
assert(objectTypeDecl != nullptr || paramType->isOptional());
589602

590603
if (objectTypeDecl &&
591-
owningPrinter.typeMapping.getKnownCxxTypeInfo(objectTypeDecl)) {
604+
(owningPrinter.typeMapping.getKnownCxxTypeInfo(
605+
objectTypeDecl) ||
606+
isClangPOD(objectTypeDecl))) {
592607
outOfLineOS << " " << types[paramType] << " result;\n";
593608
outOfLineOS << " "
594609
"memcpy(&result, payloadFromDestruction, "
@@ -755,8 +770,9 @@ class DeclAndTypePrinter::Implementation
755770
assert(objectTypeDecl != nullptr || paramType->isOptional());
756771

757772
if (objectTypeDecl &&
758-
owningPrinter.typeMapping.getKnownCxxTypeInfo(
759-
objectTypeDecl)) {
773+
(owningPrinter.typeMapping.getKnownCxxTypeInfo(
774+
objectTypeDecl) ||
775+
isClangPOD(objectTypeDecl))) {
760776
outOfLineOS
761777
<< " memcpy(result._getOpaquePointer(), &val, "
762778
"sizeof(val));\n";

test/Interop/SwiftToCxx/stdlib/core-foundation-types-in-cxx.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
// RUN: %target-swift-frontend %s -module-name UseCoreFoundation -enable-experimental-cxx-interop -clang-header-expose-decls=all-public -typecheck -verify -emit-clang-header-path %t/UseCoreFoundation.h
44
// RUN: %FileCheck %s < %t/UseCoreFoundation.h
55

6+
// RUN: echo "#include <netinet/in.h>" > %t/full-header.h
7+
// RUN: cat %t/UseCoreFoundation.h >> %t/full-header.h
8+
// RUN: %target-interop-build-clangxx -std=gnu++20 -fobjc-arc -c -x objective-c++-header %t/full-header.h -o %t/o.o
9+
610
// REQUIRES: objc_interop
711

812
import CoreFoundation
@@ -16,5 +20,9 @@ public func networkThing() -> in_addr? {
1620
return nil
1721
}
1822

23+
public enum MyEnum {
24+
case value(in_addr)
25+
}
26+
1927
// CHECK: SWIFT_EXTERN bool $s17UseCoreFoundation6foobarySbSo9CFDataRefaF(CFDataRef _Nonnull a) SWIFT_NOEXCEPT SWIFT_CALL; // foobar(_:)
2028
// CHECK: SWIFT_INLINE_THUNK swift::Optional<in_addr> networkThing() noexcept SWIFT_SYMBOL("s:17UseCoreFoundation12networkThingSo7in_addrVSgyF") SWIFT_WARN_UNUSED_RESULT {

0 commit comments

Comments
 (0)