mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[cxx-interop] Fix exporting Swift enums with C POD associated data
These types are OK to by copied using memcpy. Previously, the generated code assumed these types are exported swift types with all the value witness functions. rdar://111812577
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include "swift/AST/GenericEnvironment.h"
|
||||
#include "swift/AST/PrettyStackTrace.h"
|
||||
#include "swift/AST/SwiftNameTranslation.h"
|
||||
#include "swift/AST/Type.h"
|
||||
#include "swift/AST/TypeCheckRequests.h"
|
||||
#include "swift/AST/TypeVisitor.h"
|
||||
#include "swift/AST/Types.h"
|
||||
@@ -45,6 +46,7 @@
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/Basic/CharInfo.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
@@ -475,6 +477,17 @@ private:
|
||||
os << "@end\n";
|
||||
}
|
||||
|
||||
static bool isClangPOD(const NominalTypeDecl *ntd) {
|
||||
auto clangDecl = ntd->getClangDecl();
|
||||
if (!clangDecl)
|
||||
return false;
|
||||
if (const auto *rd = dyn_cast<clang::RecordDecl>(clangDecl)) {
|
||||
return !isa<clang::CXXRecordDecl>(rd) ||
|
||||
cast<clang::CXXRecordDecl>(rd)->isPOD();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void visitEnumDeclCxx(EnumDecl *ED) {
|
||||
assert(owningPrinter.outputLang == OutputLanguageMode::Cxx);
|
||||
|
||||
@@ -588,7 +601,9 @@ private:
|
||||
assert(objectTypeDecl != nullptr || paramType->isOptional());
|
||||
|
||||
if (objectTypeDecl &&
|
||||
owningPrinter.typeMapping.getKnownCxxTypeInfo(objectTypeDecl)) {
|
||||
(owningPrinter.typeMapping.getKnownCxxTypeInfo(
|
||||
objectTypeDecl) ||
|
||||
isClangPOD(objectTypeDecl))) {
|
||||
outOfLineOS << " " << types[paramType] << " result;\n";
|
||||
outOfLineOS << " "
|
||||
"memcpy(&result, payloadFromDestruction, "
|
||||
@@ -755,8 +770,9 @@ private:
|
||||
assert(objectTypeDecl != nullptr || paramType->isOptional());
|
||||
|
||||
if (objectTypeDecl &&
|
||||
owningPrinter.typeMapping.getKnownCxxTypeInfo(
|
||||
objectTypeDecl)) {
|
||||
(owningPrinter.typeMapping.getKnownCxxTypeInfo(
|
||||
objectTypeDecl) ||
|
||||
isClangPOD(objectTypeDecl))) {
|
||||
outOfLineOS
|
||||
<< " memcpy(result._getOpaquePointer(), &val, "
|
||||
"sizeof(val));\n";
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
// 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
|
||||
// RUN: %FileCheck %s < %t/UseCoreFoundation.h
|
||||
|
||||
// RUN: echo "#include <netinet/in.h>" > %t/full-header.h
|
||||
// RUN: cat %t/UseCoreFoundation.h >> %t/full-header.h
|
||||
// RUN: %target-interop-build-clangxx -std=gnu++20 -fobjc-arc -c -x objective-c++-header %t/full-header.h -o %t/o.o
|
||||
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
import CoreFoundation
|
||||
@@ -16,5 +20,9 @@ public func networkThing() -> in_addr? {
|
||||
return nil
|
||||
}
|
||||
|
||||
public enum MyEnum {
|
||||
case value(in_addr)
|
||||
}
|
||||
|
||||
// CHECK: SWIFT_EXTERN bool $s17UseCoreFoundation6foobarySbSo9CFDataRefaF(CFDataRef _Nonnull a) SWIFT_NOEXCEPT SWIFT_CALL; // foobar(_:)
|
||||
// CHECK: SWIFT_INLINE_THUNK swift::Optional<in_addr> networkThing() noexcept SWIFT_SYMBOL("s:17UseCoreFoundation12networkThingSo7in_addrVSgyF") SWIFT_WARN_UNUSED_RESULT {
|
||||
|
||||
Reference in New Issue
Block a user