Commit Graph

7 Commits

Author SHA1 Message Date
Egor Zhdan
e5899ee167 [cxx-interop] Use fully-qualified type names of C++ template parameters
When importing C++ class template instantiations, Swift generates a type name for each instantiation. The generated names must be unique, since they are used for mangling.

If multiple different C++ types declare nested types with the same name, which are then used as template arguments, Swift was generating the same name for those template instantiations (e.g. `shared_ptr<Impl>` for different `Impl` types).

This change makes sure we use fully-qualified type names of template parameters when generating Swift type names for class template instantiations (e.g. `shared_ptr<MyNamespace.MyClass.Impl>`).

This fixes an assertion failure coming out of IRGen:
```
Assertion failed: (Buffer.empty() && "didn't claim all values out of buffer"), function ~ConstantInitBuilderBase, file ConstantInitBuilder.h, line 75.
```

rdar://141962480
2025-01-02 18:03:56 +00:00
Egor Zhdan
041005af7c [cxx-interop] Use more correct type names in C++ template parameters
When importing a C++ class template instantiation, Swift translates the template parameter type names from C++ into their Swift equivalent.

For instance, `basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>` gets imported as `basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>`: `wchar_t` is imported as `CWideChar`, which is a typealias for `Scalar` on most platforms including Darwin. Notice that Swift goes through the `CWideChar` typealias on the specific platform. Another instantiation `basic_string<uint32_t, char_traits<uint32_t>, allocator<uint32_t>>` also gets imported as `basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>`: `uint32_t` is also imported as `Scalar`. This is problematic because we have two distinct C++ types that have the same name in Swift.

This change makes sure Swift doesn't go through typealiases when emitting names of template parameters, so `wchar_t` would now get printed as `CWideChar`, `int` would get printed as `CInt`, etc.

This also encourages clients to use the correct type (`CInt`, `CWideChar`, etc) instead of relying on platform-specific typealiases.

rdar://115673622
2023-10-09 14:57:10 +01:00
zoecarver
5c99afcd9b [tests] Fix platform specific tests and reverse interop tests. 2023-02-20 17:58:10 -08:00
Egor Zhdan
ee6b9b2a67 [cxx-interop] Disallow import std, require import CxxStdlib
`CxxStdlib` will now be the only accepted module name for the C++ standard library module in Swift.
2023-01-26 14:15:56 +00:00
Egor Zhdan
168ef490af [cxx-interop] Disambiguate const and non-const methods consistently
When importing a C++ struct that contains two methods that only differ in const-ness, we append `Mutating` to the name of the non-const method to make it possible to call from Swift unambiguously.

Unfortunately that logic was dependent on the order in which we import methods of a class: the `Mutating` suffix was added when another method with the same name was already imported.

This caused lookup failures, and the behavior was incorrect when the pair of methods return instances of an unsafe type: the const overload was renamed as `Unsafe` properly, but the non-const overload was not renamed.
2022-12-19 15:03:04 +00:00
Egor Zhdan
e3c58386b7 [cxx-interop] Recognize CxxStdlib as an alias for std
C++ standard library module is called `std`. To make it more clear to a Swift developer that this module is a C++ stdlib, and not a Swift stdlib, let's rename it to `CxxStdlib`.

This is the first step in the module rename. We don't ban `std` in this patch to be able to build SwiftCompilerSources with hosttools until a new Swift compiler is shipped.
2022-09-15 14:37:38 +01:00
Saleem Abdulrasool
8fa2019db4 test: add a C++ interop test for the msvcprt module
Add a test to verify that the C++ module is importable and expected
functions are visible.  This was requested in #59767 by @egorzhdan.
2022-08-12 11:26:31 -07:00