diff --git a/lib/PrintAsClang/ClangSyntaxPrinter.cpp b/lib/PrintAsClang/ClangSyntaxPrinter.cpp index 2310a4078cdc9..25b8f969bef49 100644 --- a/lib/PrintAsClang/ClangSyntaxPrinter.cpp +++ b/lib/PrintAsClang/ClangSyntaxPrinter.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "ClangSyntaxPrinter.h" +#include "DeclAndTypePrinter.h" #include "PrimitiveTypeMapping.h" #include "swift/ABI/MetadataValues.h" #include "swift/AST/ASTContext.h" @@ -99,6 +100,12 @@ bool ClangSyntaxPrinter::printNominalTypeOutsideMemberDeclInnerStaticAssert( } void ClangSyntaxPrinter::printClangTypeReference(const clang::Decl *typeDecl) { + StringRef osObjectName = DeclAndTypePrinter::maybeGetOSObjectBaseName( + dyn_cast(cast(typeDecl))); + if (!osObjectName.empty()) { + os << osObjectName << "_t"; + return; + } if (cast(typeDecl)->getDeclName().isEmpty() && isa(typeDecl)) { if (auto *tnd = diff --git a/lib/PrintAsClang/DeclAndTypePrinter.cpp b/lib/PrintAsClang/DeclAndTypePrinter.cpp index 445d52c21c2c7..934970a417919 100644 --- a/lib/PrintAsClang/DeclAndTypePrinter.cpp +++ b/lib/PrintAsClang/DeclAndTypePrinter.cpp @@ -3084,6 +3084,8 @@ const TypeDecl *DeclAndTypePrinter::getObjCTypeDecl(const TypeDecl* TD) { StringRef DeclAndTypePrinter::maybeGetOSObjectBaseName(const clang::NamedDecl *decl) { + if (!decl) + return StringRef(); StringRef name = decl->getName(); if (!name.consume_front("OS_")) return StringRef(); diff --git a/lib/PrintAsClang/PrintClangFunction.cpp b/lib/PrintAsClang/PrintClangFunction.cpp index 52dcaa6e1bf16..455a2f382ffaa 100644 --- a/lib/PrintAsClang/PrintClangFunction.cpp +++ b/lib/PrintAsClang/PrintClangFunction.cpp @@ -320,11 +320,16 @@ class CFunctionSignatureTypePrinter auto *cd = CT->getDecl(); if (cd->hasClangNode()) { const auto *clangDecl = cd->getClangDecl(); - ClangSyntaxPrinter(cd->getASTContext(), os).printClangTypeReference(clangDecl); + ClangSyntaxPrinter(cd->getASTContext(), os) + .printClangTypeReference(clangDecl); bool alreadyPointer = false; if (const auto *typedefDecl = dyn_cast(clangDecl)) if (importer::isCFTypeDecl(typedefDecl)) alreadyPointer = true; + if (!DeclAndTypePrinter::maybeGetOSObjectBaseName( + dyn_cast(clangDecl)) + .empty()) + alreadyPointer = true; os << (alreadyPointer ? " " : " *") << (!optionalKind || *optionalKind == OTK_None ? "_Nonnull" : "_Nullable"); diff --git a/lib/PrintAsClang/PrintClangValueType.cpp b/lib/PrintAsClang/PrintClangValueType.cpp index 2dec50f2d4235..cf2da5f1303b3 100644 --- a/lib/PrintAsClang/PrintClangValueType.cpp +++ b/lib/PrintAsClang/PrintClangValueType.cpp @@ -23,6 +23,7 @@ #include "swift/ClangImporter/ClangImporter.h" #include "swift/IRGen/IRABIDetailsProvider.h" #include "swift/IRGen/Linking.h" +#include "clang/AST/Decl.h" #include "clang/Basic/Module.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/raw_ostream.h" @@ -654,8 +655,13 @@ void ClangValueTypePrinter::printTypeGenericTraits( os << "} // end namespace \n\n"; os << "namespace swift SWIFT_PRIVATE_ATTR {\n"; auto classDecl = dyn_cast(typeDecl); - bool addPointer = - typeDecl->isObjC() || (classDecl && classDecl->isForeignReferenceType()); + + bool isOSObject = false; + if (const auto nd = + dyn_cast_or_null(typeDecl->getClangDecl())) + isOSObject = !DeclAndTypePrinter::maybeGetOSObjectBaseName(nd).empty(); + bool addPointer = (typeDecl->isObjC() && !isOSObject) || + (classDecl && classDecl->isForeignReferenceType()); if (objCxxOnly) os << "#if defined(__OBJC__)\n"; diff --git a/test/Interop/SwiftToCxx/stdlib/core-foundation-types-in-cxx.swift b/test/Interop/SwiftToCxx/stdlib/core-foundation-types-in-cxx.swift index aa62cd38ec94d..60e5260e4636c 100644 --- a/test/Interop/SwiftToCxx/stdlib/core-foundation-types-in-cxx.swift +++ b/test/Interop/SwiftToCxx/stdlib/core-foundation-types-in-cxx.swift @@ -4,6 +4,7 @@ // RUN: %FileCheck %s < %t/UseCoreFoundation.h // RUN: echo "#include " > %t/full-header.h +// RUN: echo "#include " >> %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 @@ -11,6 +12,9 @@ import CoreFoundation import Foundation +import Dispatch + +public func testDispatch(x: DispatchSemaphore) {} public func foobar(_ a: CFData) -> Bool { true @@ -33,7 +37,9 @@ public enum MyEnum { // CHECK: SWIFT_EXTERN bool $s17UseCoreFoundation6foobarySbSo9CFDataRefaF(CFDataRef _Nonnull a) SWIFT_NOEXCEPT SWIFT_CALL; // foobar(_:) // CHECK: SWIFT_EXTERN CFDateRef _Nullable $s17UseCoreFoundation13returnsCFDateSo0E3RefaSgyF(void) SWIFT_NOEXCEPT SWIFT_CALL; // returnsCFDate() // CHECK: SWIFT_EXTERN void $s17UseCoreFoundation11takesCFDate1xySo0E3RefaSg_tF(CFDateRef _Nullable x) SWIFT_NOEXCEPT SWIFT_CALL; // takesCFDate(x:) +// CHECK: SWIFT_EXTERN void $s17UseCoreFoundation12testDispatch1xySo21OS_dispatch_semaphoreC_tF(dispatch_semaphore_t _Nonnull x) SWIFT_NOEXCEPT SWIFT_CALL; // testDispatch(x:) // CHECK: SWIFT_INLINE_THUNK swift::Optional networkThing() noexcept SWIFT_SYMBOL("s:17UseCoreFoundation12networkThingSo7in_addrVSgyF") SWIFT_WARN_UNUSED_RESULT { // CHECK: SWIFT_INLINE_THUNK CFDateRef _Nullable returnsCFDate() noexcept SWIFT_SYMBOL("s:17UseCoreFoundation13returnsCFDateSo0E3RefaSgyF") SWIFT_WARN_UNUSED_RESULT { // CHECK: SWIFT_INLINE_THUNK void takesCFDate(CFDateRef _Nullable x) noexcept SWIFT_SYMBOL("s:17UseCoreFoundation11takesCFDate1xySo0E3RefaSg_tF") { +// CHECK: SWIFT_INLINE_THUNK void testDispatch(dispatch_semaphore_t _Nonnull x) noexcept SWIFT_SYMBOL("s:17UseCoreFoundation12testDispatch1xySo21OS_dispatch_semaphoreC_tF") {