Commit Graph

15 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
985db63e2b [tests] Update tests based on new template name importing rules. 2023-02-20 17:58:10 -08:00
Egor Zhdan
44f3478289 [cxx-interop] Do not try to import uninstantiatable templates
Calling `clangSema.isCompleteType` tries to instantiate a template, and if that is impossible, returns `true`. This caused Swift to try to import invalid C++ template instantiations.

This was discovered during C++ interop adoption in SwiftCompilerSources:
Several LLVM headers declare a field with a type `DenseMap<int, ForwardDeclared>` where `ForwardDeclared` is defined in an implementation file (`.cpp`) and is not visible to ClangImporter. That is valid in C++ but caused an error when importing into Swift.
2022-07-27 23:12:32 +01:00
Egor Zhdan
900ca68560 [cxx-interop] Make sure to print template instantiations in the module interface
#60246
2022-07-26 20:30:15 +01:00
zoecarver
839839f924 [cxx-interop] Rename enable-cxx-interop -> enable-experimental-cxx-interop.
Also removes the driver flag, this will now also always be guarded on `-Xfrontend`.
2022-04-07 19:15:25 -07:00
Alex Lorenz
ebb21d7ec1 [cxx-interop] Import const T& parameters as T.
This change allows Swift code to pass immutable values to const references in C++.
2022-03-03 14:42:27 -08:00
zoecarver
283fc782ec Revert "Revert "[cxx-interop] A few cleanups and fixes for function templates.""
This reverts commit 5de09631ff.
2022-02-15 13:30:10 -08:00
Zoe Carver
5de09631ff Revert "[cxx-interop] A few cleanups and fixes for function templates." 2022-02-13 09:54:39 -08:00
zoecarver
04d4e9dec3 [cxx-interop] Correctly map T& -> inout T.
This is important because the specialized template will be imported as `inout int` (for example) and we must make sure to match the signature.

Updates tests based on this and fixes a few tests that started failing after daceecfc75.
2022-02-04 16:58:31 -08:00
zoecarver
eeeb27d66e [cxx-interop] Add members to the LookupTable where possible.
If possible, add imported members to the StructDecl's LookupTable rather than adding them directly as members. This will fix the issues with ordering that #39436 poorly attempted to solve during IRGen.

This also allows us to break out most of the test changes from #39436.
2021-10-13 11:53:58 -07:00
Egor Zhdan
a8f126f7cd C++ Interop: import const methods as non-mutating
This change makes ClangImporter import some C++ member functions as non-mutating, given that they satisfy two requirements:
* the function itself is marked as `const`
* the parent struct doesn't contain any `mutable` members

`get` accessors of subscript operators are now also imported as non-mutating if the C++ `operator[]` satisfies the requirements above.

Fixes SR-12795.
2021-07-25 15:18:33 +03:00
zoecarver
02b5118199 [cxx-interop] Correctly import static function templates.
Handle static members the same way we handle other member function
templates. Also, set the "static"ness of the new (specialized) function decl.
2021-01-31 15:49:33 -08:00
zoecarver
c4da4975ed [NFC] Cleanup function templates implementation. Address post-commmit review comments from #33053.
Addresses the post-commit review comments from #33053. Just re-naming,
commenting, and some other small cleanups, nothing functionally
different.
2021-01-19 12:02:15 -08:00
zoecarver
24aa9ac75e [cxx-interop] Add support for templated member functions.
Essentially applying the same change as for supporting templated
constructors.
2020-12-04 13:07:22 -08:00