Commit Graph

179 Commits

Author SHA1 Message Date
Pavel Yaskevich
77a36f2512 [Tests] NFC: Rename a few Cxx tests to use .cpp extension instead of .swift
These are split-file C++ tests, this is a problem for swift-syntax
because `.swift` tests get parsed for round-trip testing if
swift-syntax is located near swift.

(cherry picked from commit c019b669a1)
2025-06-04 13:16:55 -07:00
John Hui
1459ecafa9 Merge pull request #81214 from j-hui/base-6.2/swift-function-as-template-arg 2025-05-07 02:08:04 -07:00
John Hui
3f8e9cd993 [cxx-interop] Allow C++ function templates to be instantiated with Swift closures
Swift started to explicitly forbid the instantiation of C++ function
templates with arbitrary types in #77430, because many types cause the
Swift compiler to crash. However, those checks prevented them from being
instantiated with Swift closures (which were previously fine), causing
a regression.

This patch relaxes the convertTemplateArgument() function to also allow
converting Swift function types, and adds some tests to make sure doing
so is fine.

This patch also does some cleanup of existing tests checking the
instantiation of various types, and adds testing for C function pointers
and Obj-C blocks.

rdar://148124104
(cherry picked from commit 284de98744)
2025-04-30 13:49:23 -07:00
Meghana Gupta
adb809369f Reland #79707
Revert "Merge pull request #80767 from meg-gupta/reverttransparent"

This reverts commit 198a802719, reversing
changes made to 8eb43af590.
2025-04-21 11:23:00 -07:00
Meghana Gupta
c22acc530e [6.2] Revert #79707
Revert "Merge pull request #79707 from DougGregor/transparent-integer-conversions"

This reverts commit 9c2c4ea07f, reversing
changes made to 829e03c104.
2025-04-11 10:57:14 -07:00
Doug Gregor
9c2c4ea07f Merge pull request #79707 from DougGregor/transparent-integer-conversions
[Stdlib performance] Make integer conversion operations transparent
2025-03-17 16:37:16 -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
Doug Gregor
c2417e0a14 Update tests to account for transparent on integral conversions 2025-03-12 07:40:52 -07:00
John Hui
140552054c [cxx-interop] Fix template parameter printing scheme for const types (#79237)
This patch changes the class template printer to disambiguate const-qualified template arguments by wrapping them with __cxxConst<>, rather than suffixing them with _const.

This is necessary to accommodate template arguments that aren't just identifiers (i.e., Foo<Int_const> is ok, but Foo<Bar<T>_const> and Foo<((Bar) -> Baz)_const> are not syntactically valid). With this patch, we would produce Foo<__cxxConst<Int>>, Foo<__cxxConst<Bar<T>>, and Foo<__cxxConst<((Bar) -> Baz)>> instead.

This patch also disambiguates volatile-qualified template arguments with __cxxVolatile<>, and changes the printing scheme for std::nullptr_t from nil to __cxxNullPtrT (since nil is not a syntactically valid type name).

rdar://143769901
2025-02-28 19:41:55 -08:00
John Hui
5a4ff294c8 [cxx-interop] Forbid C++ function template instantiation with Swift types (#77430)
Instantiating C++ function templates with Swift types is not currently supported, but the Swift compiler attempts to do so. Sometimes this leads to a compiler crash; other times it leads to a runtime crash. This patch turns those crashes into compiler errors.

At the call site of a C++ function template, the Swift compiler must convert Swift types deduced by the Swift type checker back into Clang types, which are then used to instantiate the C++ function template. Prior to this patch, this conversion was performed by ClangTypeConverter::convert(), which converts unsupported Swift types. This patch factors out some reusable parts of convert() and uses them in a new ClangTypeConverter::convertTemplateArgument() method that only converts supported template argument types. In the future, this method can be elaborated to support instantiating C++ templates with more types.

rdar://112692940
2025-01-16 10:05:20 -05:00
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
Erik Eckstein
7cceaff5f3 SIL: don't print operand types in textual SIL
Type annotations for instruction operands are omitted, e.g.

```
  %3 = struct $S(%1, %2)
```

Operand types are redundant anyway and were only used for sanity checking in the SIL parser.

But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:

* if the block with the definition appears after the block where the operand's instruction is located

* if a block or instruction is printed in isolation, e.g. in a debugger

The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
2024-11-21 18:49:52 +01:00
Egor Zhdan
6aa9d439d1 Merge pull request #77591 from swiftlang/egorzhdan/class-template-nullptr
[cxx-interop] Disambiguate template instantiations with nullptr parameters
2024-11-14 10:45:11 +00:00
Egor Zhdan
3d80ab37b2 [cxx-interop] Disambiguate template instantiations with nullptr parameters
This makes sure that different class template instantiations get distinct generated Swift type names.

Similar to aa6804a3.
2024-11-13 19:18:08 +00:00
Allan Shortlidge
17fd27554b stdlib: Adopt internal imports to suppress some warnings in tests. 2024-11-13 09:51:29 -08:00
Egor Zhdan
e345ebd1a1 [cxx-interop] Disambiguate template instantiations with enum parameters
This makes sure that different class template instantiations with enum arguments get distinct generated Swift type names.

Similar to aa6804a3.

rdar://139437761 / resolves https://github.com/swiftlang/swift/issues/77358
2024-11-11 18:03:09 +00:00
Egor Zhdan
d66c8edda2 [cxx-interop] Disambiguate template instantiations with parameter packs
This makes sure that different template instantiations of `std::tuple` get distinct Swift type names.

Similar to aa6804a3.

This also refactors `swift::importer::printClassTemplateSpecializationName` to follow a proper visitor pattern for the C++ template arguments.

rdar://139435937
2024-11-08 16:43:59 +00:00
Egor Zhdan
aa6804a30e [cxx-interop] Disambiguate template instantiations with array type parameters
When Swift imports C++ template class instantiations, it generates a human-readable Swift name for each instantiation.

Having name collisions causes multiple Swift type with the same name, which confuses the compiler.

`MyClass<int[]>` and `MyClass<long[]>` were both being imported as `MyClass<_>` into Swift. This patch fixes that:

* `MyClass<int[]>` is now imported as `MyClass<[CInt]>`
* `MyClass<int[123]>` is now imported as `MyClass<Vector<CInt, 123>>`

rdar://138921102
2024-10-30 17:05:14 +00:00
Egor Zhdan
d19c9eb32b [cxx-interop] Disambiguate template instantiations with SIMD parameters
When converting a C++ class template instantiation name into Swift, we previously didn't account for possible SIMD types. Those types were printed as `_`. This meant that e.g. `std::vector<simd::float3>` and `std::vector<simd::float4>` would get the same Swift name, causing compiler errors down the road.

rdar://134214091
2024-09-04 16:46:23 +01:00
Alexander Cyon
db0b5db54e [test/Interop] Fix typos (#75032) 2024-08-28 09:41:09 -07:00
smonteiro2
24fc755024 Add _const to Swift declaration names of const types
This change is necessary to differentiate between C++ const and non-const types in Swift.
For instance, `const int` and `int` would both be printed as `CInt` in Swift.
After this change, `const int` is stored as `CInt_const`
2024-07-18 14:13:57 +01:00
Egor Zhdan
fe5b0097bc [cxx-interop] Ban ObjCBool from being substituted into C++ templates
This fixes a compiler crash when calling a templated C++ function with a parameter of type `ObjCBool` from Swift. The compiler now emits an error for this.

Previously the following would happen:
1. Swift starts to emit SILGen for a call expression `takeTAsConstRef(ObjCBool(true))`.
2. `takeTAsConstRef` is a templated C++ function, so Swift asks Clang to instantiate a `takeTAsConstRef` with a built-in Obj-C boolean type.
3. Swift gets an instantiated function template back that looks like this: `void takeTAsConstRef(_Bool t) { ... }`.
4. Swift's ClangImporter begins to import that instantiated function.
5. Since the parameter type is not spelled as `BOOL`, the parameter is not imported as `ObjCBool`. Instead, it's imported as regular Swift `Bool`.
6. Swift realizes that the types don't match (`ObjCBool` vs `Bool`), tries to apply any of the known implicit conversions, fails to do so, crashes.

rdar://130424969
2024-06-27 19:48:57 +01:00
Egor Zhdan
5b5ffde79e [cxx-interop] Do not crash when passing Bool as const T& parameter
The type bridging logic assumed that if a value of type `Swift.Bool` is passed to a Clang function as an argument, then the type of the parameter must be a Clang built-in type (usually `_Bool`). This is not always correct. For instance, the type might be a templated const reference.

rdar://125508505
2024-05-09 15:28:33 +01:00
Alex Lorenz
0c7b1cee13 [cxx-interop] serialize x-refs for class template specializations
Fixes https://github.com/apple/swift/issues/70253
2024-03-29 10:08:18 -07:00
Egor Zhdan
78b9de1391 [cxx-interop] Run tests with swift-6 compat mode 2024-02-23 16:24:14 +00:00
Egor Zhdan
74c444d688 [cxx-interop] Emit function types as Swift closures in templated params
This is required to make the compiler distinguish between instantiations of `std::function`.

Previously, when generating a Swift type name for a `std::function` instantiation, we would always emit `_` as the template parameter. If someone referenced two different instantiations of `std::function` in a Swift module, they would get mangled with the same name, triggering linker errors later.

rdar://103979602
2024-01-19 21:02:03 +00:00
Egor Zhdan
a45d03a669 [cxx-interop] Use unique mangling for distinct C++ class template specializations
This makes sure we are printing more than one level of C++ template specializations when emitting a Swift struct name.

For instance, `std::__wrap_iter<char*>` and `std::__wrap_iter<const char*>` are currently imported with the same name in Swift. This means the mangled string will be the same for these specializations, despite them being distinct types. This causes mangling errors.

rdar://117485399
2023-10-26 13:29:41 +01:00
finagolfin
75bfa4422a [android][test] Fix five tests that are failing on the community Android CI (#69189)
Update the Android doc with info about the latest LTS NDK not working.
2023-10-16 10:44:56 -07: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
Finagolfin
30ba49e7fa [android][test] Fix a handful of tests and disable one CxxToSwiftToCxx bridging test
Also, make the analogous change to apple/swift-driver#1372, which gets the
sanitizer tests working on Android again, and remove the lld_lto feature in the
tests, which is now unused.
2023-08-12 16:36:35 +05:30
Alex Lorenz
a49fd68bfd [cxx-interop] re-enable class-template-variadic.swift test 2023-08-09 17:53:37 -07:00
Saleem Abdulrasool
55fcce2b54 tests: enable some tests on Windows
The dependent type C++ interop tests should be possible to enable now.  Do so to get more test coverage parity on Windows.
2023-08-08 09:47:06 -07:00
Alex Lorenz
15a0345857 Merge pull request #67268 from hyp/eng/windows-method-oh-no
[cxx-interop] windows methods fixes
2023-07-21 06:57:01 -07:00
Alex Lorenz
3748b0ff1c Merge pull request #65129 from hyp/eng/no-evo-cxx
[interop] Prohibit use of C++ APIs in public interfaces that opt-in i…
2023-07-19 08:10:23 -07:00
Alex Lorenz
c09135b8f3 [cxx-interop] Fix the windows ABI for returning indirect values out of methods
Fixes https://github.com/apple/swift/issues/66326

This allows us to reneable Windows method tests. Note that Windows still has
a broken convention for non-trivial record with non-trivial destructor but
trivial copy-constructor, so classes in the methods.swift test need an explicit
copy constructor.

Fixes rdar://88391102
2023-07-14 15:56:05 -07:00
Alex Lorenz
8ed840f9c1 [interop] do not warn about a template with too many specializations that can't be imported 2023-07-06 13:45:21 -07:00
Alex Lorenz
be65796b86 [interop] do not import function templates with template parameter not present in signature whose default value is dependent
rdar://107561753
2023-07-05 14:55:58 -07:00
Egor Zhdan
e3621b0420 Merge pull request #67101 from apple/egorzhdan/mangle-numeric-tmpl-args
[cxx-interop] Mangle numeric template arguments
2023-07-05 18:16:40 +01:00
Egor Zhdan
d4e8551281 [cxx-interop] Mangle numeric template arguments
This fixes linker errors when there are multiple instantiations of a templated struct with numeric template parameters.

When mangling the name of a C++ template specialization, we currently ignore non-type templated parameters. This causes two different instantiations of the same templated type to have the same mangled name, triggering linker errors.

rdar://107757051
2023-07-05 15:28:42 +01:00
Arnold Schwaighofer
79894ff461 Fix test/Interop with opaque pointers 2023-07-03 03:36:07 -07:00
Egor Zhdan
4a1afa9bd3 [cxx-interop] Avoid crashing when template substitution fails
This code used to crash the compiler:

    var s = std.string("hi")
    s.append("foo")

`append` in this case resolves to a templated C++ method that accepts `std::string_view`, while we tried passing a Swift String to it as a parameter.

rdar://107018724
2023-06-19 15:58:41 +01:00
Arnold Schwaighofer
c1a93e0bde Move tests over to use the %use_no_opaque_pointers option 2023-06-14 10:49:48 -07:00
Anthony Latsis
7f6d3bcd41 ASTPrinter: Turn on explicit any printing for everything and remove the option to disable it 2023-05-13 02:55:49 +03:00
Alex Lorenz
196c717a3d [interop] do not import function template with templated rvalue / perfect forwarding ref
they can cause compiler crashes
2023-05-04 14:41:28 -07:00
Alex Lorenz
89b1c6391f Revert "[cxx-interop] Treat un-instantiated templated types as unsafe"
This reverts commit c81325461a.

This caused https://github.com/apple/swift/issues/65446
2023-05-01 10:25:47 -07:00
Alex Lorenz
045fcf3ff5 [interop] Prohibit use of C++ APIs in public interfaces that opt-in into library evolution
The CxxStdlib overlay now has to be built without library evolution enabled.
2023-04-13 10:48:09 -07:00
Alex Lorenz
b60d635db7 [interop] make interop diagnostics more consistent with the rest of Swift diagnostics 2023-04-10 16:20:07 -07:00
Egor Zhdan
c81325461a [cxx-interop] Treat un-instantiated templated types as unsafe
When determining whether a C++ method is safe to be imported, we look at its return type to see if it stores any pointers in its fields.

If the type is templated, we might not have its definition available yet. Unfortunately we cannot instantiate it on the spot, since the Clang AST would be read and written at the same time.

Let's stay on the safe side and treat such methods as unsafe.

rdar://107609381
2023-04-04 15:33:09 +01:00
Alex Lorenz
8d7799a324 [interop] do not traverse type locs when IRGening clang decls from Swift 2023-03-14 14:24:28 -07:00
Alex Lorenz
0e7d525234 [interop] do not stop traversal when looking for clang symbols to IRGen when hitting noexcept expression 2023-03-09 20:19:39 -08:00