diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index e31f294cf801e..69ce0d8de9a5f 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -104,6 +104,11 @@ set(hlsl_files ${hlsl_subdir_files} ) +set(swift_bridging_files + swift/bridging + swift/bridging.modulemap + ) + set(loongarch_files larchintrin.h lasxintrin.h @@ -456,7 +461,7 @@ endfunction(clang_generate_header) # Copy header files from the source directory to the build directory foreach( f ${files} ${cuda_wrapper_files} ${cuda_wrapper_bits_files} ${ppc_wrapper_files} ${openmp_wrapper_files} ${zos_wrapper_files} ${hlsl_files} - ${llvm_libc_wrapper_files} ${llvm_offload_wrapper_files}) + ${llvm_libc_wrapper_files} ${llvm_offload_wrapper_files} ${swift_bridging_files}) copy_header_to_output_dir(${CMAKE_CURRENT_SOURCE_DIR} ${f}) endforeach( f ) @@ -548,6 +553,7 @@ add_dependencies("clang-resource-headers" "ppc-htm-resource-headers" "riscv-resource-headers" "spirv-resource-headers" + "swift-bridging-resource-headers" "systemz-resource-headers" "ve-resource-headers" "webassembly-resource-headers" @@ -581,6 +587,7 @@ add_header_target("gpu-resource-headers" "${gpu_files}") # Other header groupings add_header_target("hlsl-resource-headers" ${hlsl_files}) +add_header_target("swift-bridging-resource-headers" ${swift_bridging_files}) add_header_target("spirv-resource-headers" ${spirv_files}) add_header_target("opencl-resource-headers" ${opencl_files}) add_header_target("llvm-libc-resource-headers" ${llvm_libc_wrapper_files}) @@ -637,6 +644,11 @@ install( DESTINATION ${header_install_dir}/zos_wrappers COMPONENT clang-resource-headers) +install( + FILES ${swift_bridging_files} + DESTINATION ${header_install_dir}/swift + COMPONENT clang-resource-headers) + ############################################################# # Install rules for separate header lists install( @@ -787,6 +799,12 @@ install( ${EXCLUDE_HLSL} COMPONENT hlsl-resource-headers) +install( + FILES ${swift_bridging_files} + DESTINATION ${header_install_dir}/swift + EXCLUDE_FROM_ALL + COMPONENT swift-bridging-resource-headers) + install( FILES ${spirv_files} DESTINATION ${header_install_dir} @@ -881,6 +899,9 @@ if (NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-hlsl-resource-headers DEPENDS hlsl-resource-headers COMPONENT hlsl-resource-headers) + add_llvm_install_targets(install-swift-bridging-resource-headers + DEPENDS swift-bridging-resource-headers + COMPONENT swift-bridging-resource-headers) add_llvm_install_targets(install-opencl-resource-headers DEPENDS opencl-resource-headers COMPONENT opencl-resource-headers) diff --git a/clang/lib/Headers/module.modulemap b/clang/lib/Headers/module.modulemap index 2258d154b4a4c..bc6d2a54ef207 100644 --- a/clang/lib/Headers/module.modulemap +++ b/clang/lib/Headers/module.modulemap @@ -391,3 +391,5 @@ module lifetimebound { export * } /* TO_UPSTREAM(Lifetimebound) OFF */ + +extern module SwiftBridging "swift/bridging.modulemap" diff --git a/clang/lib/Headers/swift/bridging b/clang/lib/Headers/swift/bridging new file mode 100644 index 0000000000000..b890b8060bf39 --- /dev/null +++ b/clang/lib/Headers/swift/bridging @@ -0,0 +1,399 @@ +// -*- C -*- +//===------------------ bridging - C and Swift Interop ----------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file provides common utilities and annotations that are useful for C++ +// codebases that interoperate with Swift. +// +//===----------------------------------------------------------------------===// +#ifndef SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H +#define SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H + +#ifdef __has_attribute +#define _CXX_INTEROP_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +#define _CXX_INTEROP_HAS_ATTRIBUTE(x) 0 +#endif + +#if _CXX_INTEROP_HAS_ATTRIBUTE(swift_attr) + +/// Specifies that a C++ `class` or `struct` owns and controls the lifetime of all +/// of the objects it references. Such type should not reference any objects whose +/// lifetime is controlled externally. This annotation allows Swift to import methods +/// that return a `class` or `struct` type that is annotated with this macro. +#define SWIFT_SELF_CONTAINED __attribute__((swift_attr("import_owned"))) + +/// Specifies that a method returns a value that is presumed to contain +/// objects whose lifetime is not dependent on `this` or other parameters passed +/// to the method. +#define SWIFT_RETURNS_INDEPENDENT_VALUE __attribute__((swift_attr("import_unsafe"))) + +#define _CXX_INTEROP_STRINGIFY(_x) #_x + +#define _CXX_INTEROP_CONCAT_(a,b,c,d,e,f,g,i,j,k,l,m,n,o,p,...) \ + #a "," #b "," #c "," #d "," #e "," #f "," #g "," #i "," #j "," #k "," \ + #l "," #m "," #n "," #o "," #p +#define _CXX_INTEROP_CONCAT(...) \ + _CXX_INTEROP_CONCAT_(__VA_ARGS__,,,,,,,,,,,,,,,,,) + +/// Specifies that a `class` or `struct` is reference-counted using +/// the given `retain` and `release` functions. This annotation lets Swift import +/// such a type as reference counted type in Swift, taking advantage of Swift's +/// automatic reference counting. +/// +/// This example shows how to use this macro to let Swift know that +/// a reference counted C++ class can be imported as a reference counted type in Swift: +/// ```c++ +/// class SWIFT_SHARED_REFERENCE(retainSharedObject, releaseSharedObject) +/// SharedObject : IntrusiveReferenceCounted { +/// public: +/// static SharedObject* create(); +/// void doSomething(); +/// }; +/// +/// void retainSharedObject(SharedObject *); +/// void releaseSharedObject(SharedObject *); +/// ``` +/// +/// Then, the Swift programmer would be able to use it in the following manner: +/// +/// ```swift +/// let object = SharedObject.create() +/// object.doSomething() +/// // The Swift compiler will release object here. +/// ``` +#define SWIFT_SHARED_REFERENCE(_retain, _release) \ + __attribute__((swift_attr("import_reference"))) \ + __attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(retain:_retain)))) \ + __attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(release:_release)))) + +/// Specifies that a `class` or `struct` is a reference type whose lifetime +/// is presumed to be immortal, i.e. the reference to such object is presumed to +/// always be valid. This annotation lets Swift import such a type as a reference +/// type in Swift. +/// +/// This example shows how to use this macro to let Swift know that +/// a singleton C++ class can be imported as a reference type in Swift: +/// ```c++ +/// class SWIFT_IMMORTAL_REFERENCE LoggerSingleton { +/// public: +/// static LoggerSingleton &getInstance(); +/// void log(int x); +/// }; +/// ``` +/// +/// Then, the Swift programmer would be able to use it in the following manner: +/// +/// ```swift +/// let logger = LoggerSingleton.getInstance() +/// logger.log(123) +/// ``` +#define SWIFT_IMMORTAL_REFERENCE \ + __attribute__((swift_attr("import_reference"))) \ + __attribute__((swift_attr("retain:immortal"))) \ + __attribute__((swift_attr("release:immortal"))) + +/// Specifies that a `class` or `struct` is a reference type whose lifetime +/// is not managed automatically. The programmer must validate that any reference +/// to such object is valid themselves. This annotation lets Swift import such a type as a reference type in Swift. +#define SWIFT_UNSAFE_REFERENCE \ + __attribute__((swift_attr("import_reference"))) \ + __attribute__((swift_attr("retain:immortal"))) \ + __attribute__((swift_attr("release:immortal"))) \ + __attribute__((swift_attr("unsafe"))) + +/// This annotation makes smart pointers to intrusively reference counted +/// objects more ergonomic to use in Swift by: +/// +/// * introducing explicit conversions between the smart pointer type and +/// the underlying reference type and +/// * importing C++ APIs that return the smart pointer type or take it as a +/// parameter as returning or taking the underlying reference type. +/// +/// Place this annotation on a smart pointer class or struct. The argument +/// to the annotation names an accessor function, which can be a file-scope +/// function or (if prefixed by .) a member function of the smart pointer +/// class. The return type of the accessor function determines the underlying +/// reference type of the smart pointer; it must be a pointer to a class or +/// struct with the SWIFT_SHARED_REFERENCE annotation. Note that +/// SWIFT_SHARED_REFERENCE requires the underlying reference type +/// to provide independent retain and release operations; Swift does not +/// currently support this ergonomic import of smart pointers to objects +/// that can only be managed through a smart pointer class. +/// +/// The Swift importer will diagnose a class with this annotation as an +/// error if it cannot determine an underlying reference type. If the class +/// is templated, this applies to instantiations of the template, not to the +/// template pattern. (That is, it is okay to have a templated smart pointer +/// type as long as the concrete instantiations used in your C++ interface +/// all have determinable underlying reference types.) +/// +/// The smart pointer type is required to have a constructor that takes a raw +/// pointer. This constructor is expected to perform a retain of the object. +/// (In the +0 / +1 language of Objective-C reference counting, it would be +/// said to take the object at +0: it does not take responsibility for a retain +/// performed by its caller.) Generally, this kind of constructor matches with +/// object models where the object constructor initializes the reference +/// count to 0. +/// +/// The argument of this annotation is required to be the name of an +/// "accessor" method that returns a raw-pointer to the object. This method +/// is required to return a raw pointer to the object without changing the +/// reference count. +/// +/// Swift will define conversion operations using these functions to +/// convert between the raw pointer and the smart pointer representations. +/// +/// By default, smart pointer types are assumed to have a valid null state. +/// Passing a null pointer to the raw-pointer constructor will create a smart +/// pointer in the null state, and calling the raw-pointer accessor method +/// on a smart pointer in the null state will return a null pointer. In case the +/// constructor and the raw-pointer accessor are annotated with _Nonnull, we +/// assume the smart pointer does not have a null state. +/// +/// ```c++ +/// template +/// struct SWIFT_REFCOUNTED_PTR(.getPtr) Ptr { +/// Ptr(T* ptr); +/// T *_Nullable getPtr() const { return ptr; } +/// }; +/// +/// using PtrOfSharedRef = Ptr; +/// ``` +/// +/// In Swift, we can convert the smart pointer type to the corresponding native +/// Swift reference: +/// ```swift +/// func f(_ x: PtrOfSharedRef) { +/// let y = x.asReference +/// } +/// ``` +/// +/// Moreover, this annotation introduces implicit bridging for functions taking +/// or returning smart pointers by value: +/// ```c++ +/// PtrOfSharedRef foo(PtrOfSharedRef param); +/// ``` +/// Imported with the signature `func foo(_ param: SharedRef) -> SharedRef` +#define SWIFT_REFCOUNTED_PTR(_toRawPointer) \ + __attribute__((swift_attr( \ + "@_refCountedPtr(ToRawPointer: \"" _CXX_INTEROP_STRINGIFY(_toRawPointer) "\")"))) + +/// Specifies a name that will be used in Swift for this declaration instead of its original name. +#define SWIFT_NAME(_name) __attribute__((swift_name(#_name))) + +/// Specifies that a specific `class` or `struct` conforms to a +/// a specific Swift protocol. +/// +/// This example shows how to use this macro to conform a class template to a Swift protocol: +/// ``` +/// template +/// class SWIFT_CONFORMS_TO_PROTOCOL(SwiftModule.ProtocolName) +/// CustomClass {}; +/// ``` +#define SWIFT_CONFORMS_TO_PROTOCOL(_moduleName_protocolName) \ + __attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(conforms_to:_moduleName_protocolName)))) + +/// Specifies that a specific C++ method should be imported as a computed +/// property. If this macro is specified on a getter, a getter will be +/// synthesized. If this macro is specified on a setter, both a getter and +/// setter will be synthesized. +/// +/// For example: +/// ``` +/// int getX() SWIFT_COMPUTED_PROPERTY; +/// ``` +/// Will be imported as `var x: CInt {...}`. +#define SWIFT_COMPUTED_PROPERTY \ + __attribute__((swift_attr("import_computed_property"))) + +/// Specifies that a specific **constant** C++ member function should be imported as +/// `mutating` Swift method. This annotation should be added to constant C++ member functions +/// that mutate `mutable` fields in a C++ object, to let Swift know that this function is still mutating +/// and thus that it should become a `mutating` method in Swift. +#define SWIFT_MUTATING \ + __attribute__((swift_attr("mutating"))) + +/// Specifies that a specific class or struct should be imported as type marked +/// as `@unchecked Sendable` type in swift. If this annotation is used, the type is therefore allowed to +/// use safely across async contexts. +/// +/// For example +/// ``` +/// class SWIFT_UNCHECKED_SENDABLE CustomUserType +/// { ... } +/// ``` +/// Will be imported as `struct CustomUserType: @unchecked Sendable` +#define SWIFT_UNCHECKED_SENDABLE \ + __attribute__((swift_attr("@Sendable"))) + +/// Specifies that a `class` or `struct` should be imported as a non-copyable +/// Swift value type. +#define SWIFT_NONCOPYABLE \ + __attribute__((swift_attr("~Copyable"))) + +/// Specifies that a `class` or `struct` should be imported as a non-copyable +/// Swift value type that calls the given `_destroy` function when a value is no +/// longer used. +/// +/// This example shows how to use this macro to let Swift know that +/// a given C struct should have its members freed when it goes out of scope: +/// ```c +/// typedef struct SWIFT_NONCOPYABLE_WITH_DESTROY(mytypeFreeMembers) MyType { +/// void *storage +/// } MyType; +/// +/// void mytypeFreeMembers(MyType toBeDestroyed); +/// MyType mytypeCreate(void); +/// ``` +/// +/// Usage in Swift: +/// ```swift +/// let mt = mytypeCreate() +/// let mt2 = mt // consumes mt +/// // once mt2 is unused, Swift will call mytypeFreeMembers(mt2) +/// ``` +#define SWIFT_NONCOPYABLE_WITH_DESTROY(_destroy) \ + __attribute__((swift_attr("~Copyable"))) \ + __attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(destroy:_destroy)))) + +/// Specifies that a C++ `class` or `struct` should be imported as a copyable +/// Swift value if all of the specified template arguments are copyable. +#define SWIFT_COPYABLE_IF(...) \ + __attribute__((swift_attr("copyable_if:" _CXX_INTEROP_CONCAT(__VA_ARGS__)))) + +/// Specifies that a specific class or struct should be imported +/// as a non-escapable Swift value type. +#define SWIFT_NONESCAPABLE \ + __attribute__((swift_attr("~Escapable"))) + +/// Specifies that a specific class or struct should be imported +/// as an escapable Swift value. While this matches the default behavior, +/// in safe mode interop mode it ensures that the type is not marked as +/// unsafe. +#define SWIFT_ESCAPABLE \ + __attribute__((swift_attr("Escapable"))) + +/// Specifies that a C++ `class` or `struct` should be imported as a escapable +/// Swift value if all of the specified template arguments are escapable. +#define SWIFT_ESCAPABLE_IF(...) \ + __attribute__((swift_attr("escapable_if:" _CXX_INTEROP_CONCAT(__VA_ARGS__)))) + +/// Specifies that the return value is passed as owned for functions and +/// methods returning types annotated as `SWIFT_SHARED_REFERENCE` +#define SWIFT_RETURNS_RETAINED __attribute__((swift_attr("returns_retained"))) +/// Specifies that the return value is passed as unowned for functions and +/// methods returning types annotated as `SWIFT_SHARED_REFERENCE` +#define SWIFT_RETURNS_UNRETAINED \ + __attribute__((swift_attr("returns_unretained"))) + +/// Applied to a foreign reference type annotated with +/// SWIFT_SHARED_REFERENCE. Indicates that APIs returning this type are +/// assumed to return an unowned (+0) value by default, unless explicitly annotated +/// with SWIFT_RETURNS_RETAINED. +/// +/// For example: +/// ```c++ +/// struct SWIFT_SHARED_REFERENCE(retainBar, releaseBar) +/// SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT +/// Bar { ... }; +/// ``` +/// +/// In Swift, APIs returning `Bar*` will be assumed to return an unowned +/// value. +#define SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT \ + __attribute__((swift_attr("returned_as_unretained_by_default"))) + +/// Specifies that the non-public members of a C++ class, struct, or union can +/// be accessed from extensions of that type, in the given file ID. +/// +/// In other words, Swift's access controls will behave as if the non-public +/// members of the annotated C++ class were privated declared in the specified +/// Swift source file, rather than in a C++ header file/Clang module. +/// +/// For example, we can annotate a C++ class definition like this: +/// +/// ```c++ +/// class SWIFT_PRIVATE_FILEID("MySwiftModule/MySwiftFile.swift") +/// MyCxxClass { +/// private: +/// void privateMethod(); +/// int privateStorage; +/// }; +/// ``` +/// +/// Then, Swift extensions of `MyCxxClass` in `MySwiftModule/MySwiftFile.swift` +/// are allowed to access `privateMethod()` and `privateStorage`: +/// +/// ```swift +/// //-- MySwiftModule/SwiftFile.swift +/// extension MyCxxClass { +/// func ext() { +/// privateMethod() +/// print("\(privateStorage)") +/// } +/// } +/// ``` +/// +/// Non-public access is still forbidden outside of extensions and outside of +/// the designated file ID. +#define SWIFT_PRIVATE_FILEID(_fileID) \ + __attribute__((swift_attr("private_fileid:" _fileID))) + +/// A type or function annotated with SWIFT_UNSAFE will be imported as an unsafe +/// declaration into Swift. Using these declarations will trigger a warning in +/// strictly memory safe Swift. The 'unsafe' keyword can be used to suppress +/// these warnings. +#define SWIFT_UNSAFE __attribute__((swift_attr("unsafe"))) + +/// A type or function annotated with SWIFT_SAFE safely encapsulates some +/// unsafe behavior. Such declarations will be considered safe even if they have +/// unsafe constituents. +#define SWIFT_SAFE __attribute__((swift_attr("safe"))) + +/// Do not generate a safe wrapper overload function even if this function +/// contains annotations that would trigger it otherwise. +#define SWIFT_NO_SAFE_WRAPPER __attribute__((swift_attr("no_safe_wrapper"))) + +#else // #if _CXX_INTEROP_HAS_ATTRIBUTE(swift_attr) + +// Empty defines for compilers that don't support `attribute(swift_attr)`. +#define SWIFT_SELF_CONTAINED +#define SWIFT_RETURNS_INDEPENDENT_VALUE +#define SWIFT_SHARED_REFERENCE(_retain, _release) +#define SWIFT_IMMORTAL_REFERENCE +#define SWIFT_UNSAFE_REFERENCE +#define SWIFT_REFCOUNTED_PTR(_toRawPointer) +#define SWIFT_NAME(_name) +#define SWIFT_CONFORMS_TO_PROTOCOL(_moduleName_protocolName) +#define SWIFT_COMPUTED_PROPERTY +#define SWIFT_MUTATING +#define SWIFT_UNCHECKED_SENDABLE +#define SWIFT_NONCOPYABLE +#define SWIFT_NONCOPYABLE_WITH_DESTROY(_destroy) +#define SWIFT_COPYABLE_IF(...) +#define SWIFT_NONESCAPABLE +#define SWIFT_ESCAPABLE +#define SWIFT_ESCAPABLE_IF(...) +#define SWIFT_RETURNS_RETAINED +#define SWIFT_RETURNS_UNRETAINED +#define SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT +#define SWIFT_PRIVATE_FILEID(_fileID) +#define SWIFT_UNSAFE +#define SWIFT_SAFE +#define SWIFT_NO_SAFE_WRAPPER + +#endif // #if _CXX_INTEROP_HAS_ATTRIBUTE(swift_attr) + +#undef _CXX_INTEROP_HAS_ATTRIBUTE + +#endif // SWIFT_CLANGIMPORTER_SWIFT_INTEROP_SUPPORT_H diff --git a/clang/lib/Headers/swift/bridging.modulemap b/clang/lib/Headers/swift/bridging.modulemap new file mode 100644 index 0000000000000..6bc6dcc26e609 --- /dev/null +++ b/clang/lib/Headers/swift/bridging.modulemap @@ -0,0 +1,17 @@ +//===------------------ module.modulemap - C++ and Swift module -*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +module SwiftBridging { + header "bridging" + + export * +}