From 435d0a6f5f2a592f3d1fa5e3c6da1d4b20863c94 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Tue, 11 Jul 2023 18:50:15 -0700 Subject: [PATCH] [interop][SwiftToCxx] ensure swift::Int and swift::UInt are usable in generic context Fixes https://github.com/apple/swift/issues/63452 (cherry picked from commit 85a431eedf65b69c131f06c3213c9d61050275c7) --- .../PrintSwiftToClangCoreScaffold.cpp | 24 +++++- .../swift-impl-defs-in-cxx-darwin64bit.swift | 75 +++++++++++++++++++ .../core/swift-impl-defs-in-cxx.swift | 5 +- .../stdlib/stdlib-dep-inline-in-cxx.swift | 5 ++ 4 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx-darwin64bit.swift diff --git a/lib/PrintAsClang/PrintSwiftToClangCoreScaffold.cpp b/lib/PrintAsClang/PrintSwiftToClangCoreScaffold.cpp index 098d369749821..daf94efe1d5ef 100644 --- a/lib/PrintAsClang/PrintSwiftToClangCoreScaffold.cpp +++ b/lib/PrintAsClang/PrintSwiftToClangCoreScaffold.cpp @@ -19,6 +19,7 @@ #include "swift/AST/Type.h" #include "swift/IRGen/IRABIDetailsProvider.h" #include "swift/IRGen/Linking.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/ADT/STLExtras.h" using namespace swift; @@ -164,9 +165,26 @@ void printPrimitiveGenericTypeTraits(raw_ostream &os, ASTContext &astContext, // Pointer types. // FIXME: support raw pointers? - astContext.getOpaquePointerType()}; - - for (Type type : llvm::makeArrayRef(supportedPrimitiveTypes)) { + astContext.getOpaquePointerType(), + + astContext.getIntType(), astContext.getUIntType()}; + + auto primTypesArray = llvm::makeArrayRef(supportedPrimitiveTypes); + + // Ensure that `long` and `unsigned long` are treated as valid + // generic Swift types (`Int` and `UInt`) on platforms + // that do define `Int`/`ptrdiff_t` as `long` and don't define `int64_t` to be + // `long`. + auto &clangTI = + astContext.getClangModuleLoader()->getClangASTContext().getTargetInfo(); + bool isSwiftIntLong = + clangTI.getPtrDiffType(0) == clang::TransferrableTargetInfo::SignedLong; + bool isInt64Long = + clangTI.getInt64Type() == clang::TransferrableTargetInfo::SignedLong; + if (!(isSwiftIntLong && !isInt64Long)) + primTypesArray = primTypesArray.drop_back(2); + + for (Type type : primTypesArray) { auto typeInfo = *typeMapping.getKnownCxxTypeInfo( type->getNominalOrBoundGenericNominal()); diff --git a/test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx-darwin64bit.swift b/test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx-darwin64bit.swift new file mode 100644 index 0000000000000..749edab999137 --- /dev/null +++ b/test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx-darwin64bit.swift @@ -0,0 +1,75 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend %s -typecheck -module-name Core -clang-header-expose-decls=all-public -emit-clang-header-path %t/core.h +// RUN: %FileCheck %s < %t/core.h + +// RUN: %check-interop-cxx-header-in-clang(%t/core.h) + +// REQUIRES: PTRSIZE=64 +// REQUIRES: OS=macosx + +// CHECK: // type metadata address for Bool. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $sSbN; +// CHECK-NEXT: // type metadata address for Int8. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss4Int8VN; +// CHECK-NEXT: // type metadata address for UInt8. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss5UInt8VN; +// CHECK-NEXT: // type metadata address for Int16. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss5Int16VN; +// CHECK-NEXT: // type metadata address for UInt16. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss6UInt16VN; +// CHECK-NEXT: // type metadata address for Int32. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss5Int32VN; +// CHECK-NEXT: // type metadata address for UInt32. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss6UInt32VN; +// CHECK-NEXT: // type metadata address for Int64. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss5Int64VN; +// CHECK-NEXT: // type metadata address for UInt64. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss6UInt64VN; +// CHECK-NEXT: // type metadata address for Float. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $sSfN; +// CHECK-NEXT: // type metadata address for Double. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $sSdN; +// CHECK-NEXT: // type metadata address for OpaquePointer. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss13OpaquePointerVN; +// CHECK-NEXT: // type metadata address for Int. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $sSiN; +// CHECK-NEXT: // type metadata address for UInt. +// CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $sSuN; +// CHECK-EMPTY: +// CHECK-NEXT: #ifdef __cplusplus +// CHECK-NEXT: } +// CHECK-NEXT: #endif + +// CHECK: static inline const constexpr bool isUsableInGenericContext = true; +// CHECK-EMPTY: +// CHECK-NEXT: template<> +// CHECK-NEXT: struct TypeMetadataTrait { +// CHECK-NEXT: static SWIFT_INLINE_THUNK void * _Nonnull getTypeMetadata() { +// CHECK-NEXT: return &_impl::$ss13OpaquePointerVN; +// CHECK-NEXT: } +// CHECK-NEXT: }; +// CHECK-EMPTY: +// CHECK-NEXT: template<> +// CHECK-NEXT: static inline const constexpr bool isUsableInGenericContext = true; +// CHECK-EMPTY: +// CHECK-NEXT: template<> +// CHECK-NEXT: struct TypeMetadataTrait { +// CHECK-NEXT: static SWIFT_INLINE_THUNK void * _Nonnull getTypeMetadata() { +// CHECK-NEXT: return &_impl::$sSiN; +// CHECK-NEXT: } +// CHECK-NEXT: }; +// CHECK-EMPTY: +// CHECK-NEXT: template<> +// CHECK-NEXT: static inline const constexpr bool isUsableInGenericContext = true; +// CHECK-EMPTY: +// CHECK-NEXT: template<> +// CHECK-NEXT: struct TypeMetadataTrait { +// CHECK-NEXT: static SWIFT_INLINE_THUNK void * _Nonnull getTypeMetadata() { +// CHECK-NEXT: return &_impl::$sSuN; +// CHECK-NEXT: } +// CHECK-NEXT: }; +// CHECK-EMPTY: +// CHECK-NEXT: #pragma clang diagnostic pop +// CHECK-EMPTY: +// CHECK-NEXT: } // namespace swift + diff --git a/test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx.swift b/test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx.swift index d4e6c963754e2..d98a9b28d6022 100644 --- a/test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx.swift +++ b/test/Interop/SwiftToCxx/core/swift-impl-defs-in-cxx.swift @@ -93,8 +93,7 @@ // CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $sSdN; // CHECK-NEXT: // type metadata address for OpaquePointer. // CHECK-NEXT: SWIFT_IMPORT_STDLIB_SYMBOL extern size_t $ss13OpaquePointerVN; -// CHECK-EMPTY: -// CHECK-NEXT: #ifdef __cplusplus +// CHECK: #ifdef __cplusplus // CHECK-NEXT: } // CHECK-NEXT: #endif // CHECK-EMPTY: @@ -224,7 +223,7 @@ // CHECK-NEXT: } // CHECK-NEXT: }; // CHECK-EMPTY: -// CHECK-NEXT: #pragma clang diagnostic pop +// CHECK: #pragma clang diagnostic pop // CHECK-EMPTY: // CHECK-NEXT: } // namespace swift // CHECK-EMPTY: diff --git a/test/Interop/SwiftToCxx/stdlib/stdlib-dep-inline-in-cxx.swift b/test/Interop/SwiftToCxx/stdlib/stdlib-dep-inline-in-cxx.swift index 78c9950810641..df84ba327241a 100644 --- a/test/Interop/SwiftToCxx/stdlib/stdlib-dep-inline-in-cxx.swift +++ b/test/Interop/SwiftToCxx/stdlib/stdlib-dep-inline-in-cxx.swift @@ -17,5 +17,10 @@ public func test() -> String { return "" } +@_expose(Cxx) +public func testIntArray() -> [Int] { + return [] +} + // CHECK: namespace swift SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("swift") { // CHECK: class SWIFT_SYMBOL("{{.*}}") String final {