Commit Graph

73 Commits

Author SHA1 Message Date
Egor Zhdan
dcc3842535 [cxx-interop] Instantiate std::optional value constructors
This improves support for initializing instances of `std::optional` from Swift. Previously only a null optional could be initialized directly from Swift. Now instantiations of `std::optional` will get a Swift initializer that takes the wrapped value as a parameter.

rdar://118026392
2025-07-03 14:00:27 +01:00
Gabor Horvath
7474a51691 [cxx-interop] Avoid copies when accessing pointee
Previously, we would get two copies, one accessing the pointee and one
when we pass the pointee as a method as the implicit self argument.
These copies are unsafe as they might introduce slicing. When
addressable paramaters features are enabled, we no longer make these
copies for the standard STL types. Custom smart pointers can replicate
this by making the lifetime dependency between the implicit object
parameter and the returned reference of operator* explicit via a
lifetime annotation.

rdar://154213694&128293252&112690482
2025-06-25 17:09:55 +01:00
Gabor Horvath
868c85d5f0 [cxx-interop] Only swiftify template instantiations behind type aliases
While I could not trigger a scenario where the generated macro triggers
a compilation error, the generated code is definitely not valid Swift.

rdar://151422108
2025-06-06 10:31:52 +01:00
Henrik G. Olsson
ebe2c60f43 [Swiftify] Escape param decl refs (#81550)
Parameters can be named with keywords without escaping, because it's
unambiguous in the grammar that they are parameters. They still need to
escaped when referred to inside the function body however. This escapes
all references to parameters using backticks.

Parameter names are also checked for clashes with the function name - in
such cases the parameter is renamed in the same way as unnamed
parameters.

rdar://151024645
2025-05-23 12:33:58 -07:00
susmonteiro
72b13b3b48 [cxx-interop] Fix metadata mismatch regarding fields of structs 2025-05-20 10:15:14 +01:00
Henrik G. Olsson
87f5309144 [Swiftify] enable mutable span (#80387)
* [Swiftify] Emit Mutable[Raw]Span when possible

Previously wrappers would use UnsafeMutable[Raw]Pointer for mutable
pointers, and Span for non-const std::span, to prevent the compiler from
complaining that MutableSpan didn't exist.

Now that MutableSpan has landed we can finally emit MutableSpan without
causing compilation errors. While we had (disabled) support for MutableSpan
syntax already, some unexpected semantic errors required additional
changes:
 - Mutable[Raw]Span parameters need to be inout (for mutation)
 - inout ~Escapable paramters need explicit lifetime annotations
 - MutableSpan cannot be directly bitcast to std::span, because it is
   ~Copyable, so they need unwrapping to UnsafeMutableBufferPointer

rdar://147883022

* [Swiftify] Wrap if-expressions in Immediately Called Closures

When parameters in swiftified wrapper functions are nullable, we use
separate branches for the nil and nonnil cases, because
`withUnsafeBufferPointer` (and similar) cannot be called on nil.
If-expressions have some limitations on where they are allowed in the
grammar, and cannot be passed as arguments to a function. As such, when
the return value is also swiftified, we get an error when trying to
pass the if-expression to the UnsafeBufferPointer/Span constructor.
While it isn't pretty, the best way forward seems to be by wrapping the
if-expressions in Immediately Called Closures.

The closures have the side-effect of acting as a barrier for 'unsafe':
unsafe keywords outside the closure do not "reach" unsafe expressions
inside the closure. We therefore have to emit "unsafe" where unsafe
expressions are used, rather than just when returning.

rdar://148153063
2025-03-29 05:05:01 -07:00
Gabor Horvath
11593329ea [cxx-interop] Fix transforming spans that are not behind type aliases
While we expect our users to use type aliases for template
instantiations, there are some contexts when we import instantiations
without aliases. Unfortunately, in case of C++ span we generated a name
for the instantiation that cannot be a syntactically valid Swift type
due to unary negation appearing in the type name. This PR replaces the
unary negation with "Neg" in the type name and also fixed a bug that
ended up printing certain unsigned values as signed. Moreover, this PR
also fixes some other fallouts in the SwiftifyImport macro.

rdar://146833480
2025-03-14 17:59:09 +00:00
Henrik G. Olsson
6ba58f553c add cross platform counted_by defines in test case 2025-02-24 08:47:22 -08:00
Henrik G. Olsson
ad426fbc47 [Swiftify] Emit Span for counted_by return values with lifetime info
__counted_by return values with .lifetimeDependence are now mapped to
Span instead of UnsafeBufferPointer. Also fixes bug where std::span
return values would map to Span even if lifetime dependence info was
missing.
2025-02-21 20:30:58 -08:00
Henrik G. Olsson
957db2c959 [ClangImporter] Merge paths for std::span and __counted_by
importBoundsAttributes and importSpanAttributes are merged into a single
function named swiftify. This allows us to not have to duplicate the
effort of attaching _SwiftifyImport macros, but is also necessary to
allow importing a function with both __counted_by and std::span types.
2025-02-21 20:08:59 -08:00
Gabor Horvath
df27b79579 [cxx-interop] Work around lifetime errors in SwiftifyImport generated code
Unfortunately, this was not discovered earlier as swift-ide-test is not
invoking the SIL passes that produce this diagnostic. When creating
Swift spans from C++ spans we have no lifetime dependency information to
propagate as C++ spans are modeled as escapable types. Hence, this PR
introduces a helper function to bypass the lifetime checks triggered by
this discepancy. Hopefully, the new utility will go away as the lifetime
analysis matures on the Swift side and we get standardized way to deal
with unsafe lifetimes.
2025-02-14 16:40:43 +00:00
Gabor Horvath
dd3db51f60 [cxx-interop] Make borrowing specifiers more precise
We do not need to borrow from view objects passed by value but we need
to borrow from owners taken by const reference regardless of whether it
was annotated using lifetimebound or lifetime_capture_by.
2025-01-29 11:49:32 +00:00
Gábor Horváth
44fa6506c3 Merge pull request #78945 from swiftlang/gaborh/wrapper-method
[cxx-interop] Add safe wrapper test with a member function
2025-01-29 11:46:35 +00:00
Gabor Horvath
06e5ead8da [cxx-interop] Support borrowing from self in SwiftifyImport
Support adding safe wrappers for APIs returning std::span depending on
the this object. This also fixes an issue for APIs with 0 parameters.

rdar://139074571
2025-01-28 13:54:10 +00:00
Gabor Horvath
da3be5d99d [cxx-interop] Add safe wrapper test with a member function 2025-01-27 12:45:58 +00:00
Gabor Horvath
042b108e6f [cxx-interop] Make ClangImporter support lifetimebound annotated spans
Generate safe Swift Span wrappers using the new SwiftifyImport macro.

rdar://139074571
2025-01-22 15:07:02 +00:00
Gabor Horvath
4846c56795 [cxx-interop] Generate safe overloads for non-escapable spans
A previous PR already added support to the SwiftifyImport macro to
generate safe wrappers. This PR makes ClangImporter emit the macro to do
the transformation.
2025-01-08 11:19:35 +00:00
Egor Zhdan
0fa65bea8a Merge pull request #77864 from CrazyFanFan/feature_cxxmap
[cxx-interop]: Enhance CxxDictionary with Merging, Initializer, and Unsafe Erasure
2024-12-18 13:37:44 +00:00
Gábor Horváth
8398e693e7 Merge pull request #77700 from swiftlang/gaborh/span-conversion
[cxx-interop] Explicit conversions between Swift and C++ spans
2024-12-13 19:54:27 +00:00
Gabor Horvath
b6cc118f71 [cxx-interop] Explicit conversions between Swift and C++ spans
A first step towards creating safe overloads for C++ APIs using span
(rdar://139074571).

Note that we need to mark span as owned because it the libc++
implementation was mistakenly recognized as owned and might now rely on
span methods like `data` being renamed as `__dataUnsafe`. We will change
it under a new interop version. But for the time being, we want
consistent behavior across stdlib versions.
2024-12-13 16:01:02 +00:00
Alex Lorenz
9c44e01e07 [cxx-interop][stdlib] windows - use new hash inline functions like other platforms
The PR https://github.com/swiftlang/swift/pull/77857 added windows-specific workaround for https://github.com/swiftlang/swift/issues/77856, that happened after https://github.com/swiftlang/swift/pull/77843. Unfortunately this caused a new issue on windows - https://github.com/swiftlang/swift/issues/78119. It looks like windows is suffering from a similar serialization issue as libstdc++, although its even more complex as the callAsFunction is not only a derived function from a base class, the base class although has a static call operator. In any case, the libstdc++ callAsFunction deserialization fix should align with the static operator () deserialization too, so for now make windows use the same workaround as other platforms to avoid the deserialization crash (77856).

This change was tested on i686 windows too, ensuring that IR verifier crash no longer happens
2024-12-12 23:17:17 -08:00
Egor Zhdan
9472c4ca08 [cxx-interop] Avoid "libstdc++ not found" warning when -nostdinc++ is passed
When explicitly asked not to load the C++ standard library, Swift should not emit warnings for missing libstdc++.

This fixes a compiler warning when building the Cxx module on Linux.
2024-12-05 17:51:30 +00:00
Crazy凡
c6b10dffd7 "Enhance CxxDictionary with removeValue(forKey:), subscript(key:default:), mergemerging and init(grouping:by:)" 2024-11-28 13:11:31 +08:00
Egor Zhdan
cb486c6599 [cxx-interop] Allow creating a String from std::string_view
This adds overlay support for initializing a Swift String from C++ `std::string_view`, `std::u16string_view`, `std::u32string_view`.

rdar://138417835
2024-10-24 13:11:09 +01:00
Egor Zhdan
16e7cbeafa [cxx-interop] Modularize __msvc_bit_utils on Windows
`__msvc_bit_utils.hpp` was added in a recent version of MSVC, and it is causing build errors for SwiftCompilerSources:
```
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\numeric:598:12: error: function '_Select_countr_zero_impl<unsigned long long, (lambda at C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\numeric:598:55)>' with deduced return type cannot be used before it is defined
    return _Select_countr_zero_impl<_Common_unsigned>([=](auto _Countr_zero_impl) {
```

This change references the `__msvc_bit_utils.hpp` header from the modulemap. Since we still need to support older versions of Visual Studio that do not provide `__msvc_bit_utils.hpp`, this also teaches ClangImporter to inject an empty header file named `__msvc_bit_utils.hpp` into the system include directory, unless it already exists.

rdar://137066642
2024-10-04 13:15:20 +01:00
Ryan Mansfield
6989653b4f [test] Set _LIBCPP_VERSION check in check-libcxx-version.cpp to include 170004.
This fixes test failures of libcxx-module-interface.swift and
libcxx-symbolic-module-interface.swift where the std module was split.
e.g building against a MacOS 14.4 SDK.
2024-09-13 14:33:56 -04:00
Gabor Horvath
a8dde60a4e [cxx-interop] Add tests for move-only objects behind smart pointers 2024-09-03 11:38:24 +01:00
smonteiro2
2541735714 [cxx-interop] Test: initialize std::span in C++ from Swift array 2024-07-25 15:05:57 +01:00
Egor Zhdan
71c27a9d17 Merge pull request #75395 from swiftlang/egorzhdan/std-function-test
[cxx-interop] Add one more test for `std::function`
2024-07-22 19:28:45 +01:00
Egor Zhdan
d7212ff7f5 [cxx-interop] Add one more test for std::function
While initializing a `std::function` that takes `const std::string&` as a parameter currently crashes, changing the parameter type to `std::string` should work fine.
2024-07-22 13:54:09 +01:00
smonteiro2
684e9ebf0c [cxx-interop] Implements CxxMutableSpan, created from an UnsafeMutableBufferPointer
* Added tests for generic functions
* Add some tests for mutable spans
* Initialize ConstSpan from UnsafeMutableBufferPointer
* Change hardening flag
2024-07-19 10:38:52 +01:00
smonteiro2
f75a2f596f Add tests for span inside struct 2024-07-04 16:02:27 +01:00
Susana Monteiro
823e809db5 Merge pull request #74426 from apple/susmonteiro/cxx-span
[cxx-interop] Add `std::span` tests
2024-06-18 17:58:03 +01:00
susmonteiro
76feea8fa7 [cxx-interop] Add std::span tests
Add compiler flag to specify C++20

Disable swift-ci linux tests
2024-06-18 14:32:49 +01:00
Egor Zhdan
3243228897 [cxx-interop] Allow initializing std::function from Swift closures
This adds a Swift initializer to instantiations of `std::function` that accepts a Swift closure with `@convention(c)`.

rdar://103979602
2024-06-14 19:05:45 +01:00
Daniel Rodríguez Troitiño
8b4821f1a8 [cxx-interop] Fix test header to declare linkage for a implicit template (#72522)
The header was defining a function, the function created a lambda, and
the lambda was transformed into a `std::function`. This transformation
is incorrect because the function scope does not have linkage, so the
instantiated types will not have linkage either, causing the error
below.

```
.../include/c++/11.2.0/bits/invoke.h:104:5:
error: function 'std::__invoke_r<int, (lambda at .../swift/test/Interop/Cxx/stdlib/Inputs/std-function.h:9:10) &, int>' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage
102 │   template<typename _Res, typename _Callable, typename... _Args>
103 │     constexpr enable_if_t<is_invocable_r_v<_Res, _Callable,
    _Args...>, _Res>
    104 │     __invoke_r(_Callable&& __fn, _Args&&... __args)
        │     ╰─ error: function 'std::__invoke_r<int, (lambda at .../swift/test/Interop/Cxx/stdlib/Inputs/std-function.h:9:10) &, int>' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage
        105 │     noexcept(is_nothrow_invocable_r_v<_Res, _Callable,
            _Args...>)
  106 │     {

  }
```

Declaring the function `inline` forces each TU to have their own copies
of the function, which avoids the instantiated templates from being in a
different TU than the one using them.

The header would not have worked in a normal C++ program, since none of
the functions declare linkage, they would have been defined in each TU
that included the header and it would fail linking as soon as two of
those TU tried to be linked together. Declaring the functions `inline`
avoids the problem (a more normal header, only with declarations, would
also worked).
2024-03-23 07:55:28 -07:00
Egor Zhdan
db424e23cb Merge pull request #71243 from apple/egorzhdan/std-vector-bridging-header
[cxx-interop] Make automatic conformances work with the bridging header
2024-02-01 13:14:10 +00:00
Egor Zhdan
c26fe86754 [cxx-interop] Make automatic conformances work with the bridging header
For C++ types that are defined in the bridging header, or are `#include`-d from the bridging header, we did not generate the automatic conformances to `CxxSequence`, `CxxRandomAccessCollection` protocols.

To check whether we should try to conform a C++ type to those protocols, the compiler checks for the presence of `requires cplusplus` in the module declaration in a modulemap file. This check is there to prevent us from accidentally pulling in `Cxx`/`CxxStdlib` modules when a client is importing a C library.

This change makes sure those conformances are generated.

rdar://121927459
2024-01-31 13:56:18 +00:00
Egor Zhdan
840b1dfee8 Merge pull request #71181 from apple/egorzhdan/default-arg-copy-ctor
[cxx-interop] Check for unsafe types of default arguments consistently
2024-01-29 16:13:13 +00:00
Egor Zhdan
d594f475ee [cxx-interop] Check for unsafe types of default arguments consistently
If the C++ type of a function parameter defines a custom copy constructor, assume that it is safe to use from Swift. This matches the heuristic that we use to detect if a C++ method is safe based on the return type.

rdar://121391798
2024-01-26 19:26:27 +00:00
Egor Zhdan
997b2490ce [cxx-interop] Only run certain tests with older libc++
rdar://119869070
2024-01-26 13:49:11 +00:00
Egor Zhdan
a61d9333e9 [cxx-interop] Re-export C++ stdlib in tests that require it 2024-01-16 18:07:29 +00:00
Egor Zhdan
e9dd9109e7 [cxx-interop] Update the std::pair safety test
The test was passing by accident: we didn't properly check `std::pair` type for completeness, and assumed that it is incomplete.

This updates the test to actually verify the behavior that is specified in the vision document.
2024-01-12 16:21:43 +00:00
Egor Zhdan
2d0863aba2 [cxx-interop] Initial tests for std::function usage
This makes sure that `std::function` is imported consistently on supported platforms, and that it allows basic usage: calling a function with `callAsFunction`, initializing an empty function, and passing a function retrieved from C++ back to C++ as a parameter.

rdar://103979602
2024-01-11 12:02:12 +00:00
Alex Lorenz
633e7f1eb8 fix test 2023-12-02 20:03:36 -08:00
Alex Lorenz
99e6d331fb [cxx-interop] attempt to fix windows unique ptr test 2023-12-01 15:11:41 -08:00
zoecarver
4ba62e1abe [cxx-interop] Add tests for std::unique_ptr. 2023-11-16 10:08:25 -08:00
Alex Lorenz
41dc466108 Merge pull request #68846 from hyp/eng/base-member-cxx-synthesized-accessor
[cxx-interop] Use a synthesized C++ method when invoking a base metho…
2023-10-17 07:07:59 -07:00
mohanadkandil
d58943a508 Add filter method for ordered and unordered map (#67501)
Co-authored-by: mkandil <mkandil@synapse-analytics.io>
2023-10-05 19:13:34 +01:00
Alex Lorenz
ba5b1bab89 [cxx-interop] Use a synthesized C++ method when invoking a base method from a derived class synthesized method
The use of a synthesized C++ method allows us to avoid making a copy of self when invoking the base method from Swift
2023-09-29 13:52:10 -07:00