Commit Graph

35 Commits

Author SHA1 Message Date
Egor Zhdan
782f26e726 [cxx-interop] Fix printing of namespaces declared in bridging headers
If a C++ namespace has redeclarations in a bridging header, printing AST for the namespace would crash the compiler. This is because such a redeclaration would not have an owning Clang module, and the AST printer did not account for that.

This change fixes the crash.

rdar://151715540
(cherry picked from commit cc9c51deea)
2025-06-23 18:56:19 +01:00
Gábor Horváth
2327cec99f [6.2][cxx-interop] Fix crash in ASTMangler triggered by UsingShadowDecls
Explanation: We did not handle this declaration kind. This PR makes sure we
mangle it the same way we do for the target declaration.
Issue: rdar://152841420
Risk: Low, the fix is small, localized, and straightforward.
Testing: Regression test added.
Original PR: #82144
Reviewer: @egorzhdan @hnrklssn @j-hui
2025-06-11 11:37:27 +01:00
QuietMisdreavus
ab26b8b9d7 add support to getTopLevelDecls for clang submodules (#76401)
rdar://126031510
2025-01-30 09:39:58 -07:00
Daniel Rodríguez Troitiño
ba68faaed5 [test] Mark tests that use experimental/upcoming features as such
Find all the usages of `--enable-experimental-feature` or
`--enable-upcoming-feature` in the tests and replace some of the
`REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which
should correctly apply to depending on the asserts/noasserts mode of the
toolchain for each feature.

Remove some comments that talked about enabling asserts since they don't
apply anymore (but I might had miss some).

All this was done with an automated script, so some formatting weirdness
might happen, but I hope I fixed most of those.

There might be some tests that were `REQUIRES: asserts` that might run
in `noasserts` toolchains now. This will normally be because their
feature went from experimental to upcoming/base and the tests were not
updated.
2024-11-02 11:46:46 -07:00
Allan Shortlidge
b11bb1ceea SE-0444: Fix interactions with Cxx interop.
With the upcoming `MemberImportVisibility` feature enabled, code built with Cxx
interop also enabled could be rejected by the compiler with cryptic errors
about the `__ObjC` module not being imported. This is the result of a
surprising implementation detail of Cxx interop. When importing C++ namespaces
and their members, the Clang importer puts these declarations in the Clang
header import module (a.k.a. the bridging header module, `__ObjC`). C++
namespaces don't have a logical modular home in the Swift AST because they can
span multiple modules, so it's understandable why this implementation was
chosen. However, the concrete members of namespaces also get placed in the
`__ObjC` module too, and this really confuses things.

To work around this idiosyncrasy of Cxx interop, I've introduced
`Decl::getModuleContextForNameLookup()` which returns the module that a
declaration would ideally belong to if Cxx interop didn't have this behavior.
This alternative to `Decl::getModuleContext()` is now used everywhere that
`MemberImportVisibility` rules are enforced to provide consistency.

Additionally, I found that I also had to further special-case the header import
module for Cxx interop because it turns out that there are some additional
declarations, beyond imported namespaces, that also live there and need to be
implicitly visible in every source file. The `__ObjC` module is not implicitly
imported in source files when Cxx interop is enabled, so these declarations are
not deemed visible under normal name lookup rules. When I tried to add an
implicit import of `__ObjC` when Cxx interop is enabled, it broke a bunch
tests. So for now, when a decl really belongs to the `__ObjC` module in Cxx
interop mode, we just always allow it to be referenced.

This Cxx interop behavior really needs a re-think in my opinion, but that will
require larger discussions.

Resolves rdar://136600598.
2024-09-27 12:16:38 -07:00
Alex Lorenz
358c688cda [cxx-interop] code-complete namespace members
Fixes https://github.com/apple/swift/issues/65736

rdar://109714059
2023-11-03 15:53:14 -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
Arnold Schwaighofer
79894ff461 Fix test/Interop with opaque pointers 2023-07-03 03:36:07 -07:00
Arnold Schwaighofer
c1a93e0bde Move tests over to use the %use_no_opaque_pointers option 2023-06-14 10:49:48 -07:00
Slava Pestov
1957bd6065 Sema: Reword diagnostics to say 'without a type annotation' instead of 'without more context' 2023-06-09 17:44:42 -04:00
Alex Lorenz
fedf86ff76 Merge pull request #63809 from hyp/eng/exception1
[interop] add itanium ABI support for trapping on uncaught exceptions when making a foreign call
2023-02-23 19:41:43 -08:00
Alex Lorenz
9feb76419b [interop] ignore exceptions in existing interop tests 2023-02-22 11:00:51 -08:00
zoecarver
985db63e2b [tests] Update tests based on new template name importing rules. 2023-02-20 17:58:10 -08:00
Alex Lorenz
1c2ba454f6 [interop] namespace printing should only print redecls from one module interface
This ensures that when we're printing multiple module interfaces, we separate out
the namespaces and their members correctly between the produced module interfaces.
2023-01-29 17:31:20 -08:00
Egor Zhdan
2d67ab2b56 [cxx-interop] Import non-member operators as global functions
If a non-member operator is declared in a C++ namespace, we previously imported it as a static member of the enum that represents the C++ namespace.

This is not always correct under Swift rules for operators. In pure Swift, this code is valid:
```
public protocol UnsafeCxxRandomAccessIterator {
  static func +=(lhs: inout Self, rhs: Int)
}

enum std {
  public struct A : UnsafeCxxRandomAccessIterator {
    public static func += (lhs: inout A, rhs: Int) {
    }
  }
}
```
but this is not valid:
```
public protocol UnsafeCxxRandomAccessIterator {
  static func +=(lhs: inout Self, rhs: Int)
}

enum std {
  public struct A : UnsafeCxxRandomAccessIterator {}
  public static func += (lhs: inout A, rhs: Int) {}
}
// error: Member operator '+=' must have at least one argument of type 'std'
```

This caused assertion failures in SILGen when conforming C++ iterator types to `UnsafeCxxRandomAccessIterator`.
2022-12-21 15:20:03 +00:00
zoecarver
b4abb47a65 [cxx-interop] Mark un-specialized class templates as unavailable in Swift.
They don't really work, so let's not "support" them yet.
2022-10-19 17:50:53 -07:00
Anthony Latsis
a65f1a161e Gardening: Migrate test suite to GH issues: Interop 2022-08-31 05:20:25 +03:00
zoecarver
6acffbbee6 [cxx-interop] Flip the switch: only import safe APIs. 2022-07-18 17:15:15 -04:00
Ehud Adler
e7fe6f0fe7 Fix tests and re-enable support for CXX operators 2022-05-21 21:28:03 -04:00
Egor Zhdan
2472dfc32e [cxx-interop] Fix SIL deserialization error
Make sure nested namespaces are added to the SwiftLookupTable when they are declared in a non-canonical redecl of the parent namespace.

This was blocking C++ interop adoption in SwiftCompilerSources.
2022-04-27 01:10:46 +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
zoecarver
f652361af3 [cxx-interop] Remove 'support' for importing C++ operators.
This does not include subscript operators.

Before this is re-enabled operators need to be re-implemented. Right now they are the source of a lot of bugs. They cause frequent crashes and mis compiles. Also, templated operators insert a lot of names into global lookup which causes problems.

They also don't work on Windows.
2022-03-30 15:39:35 -07:00
zoecarver
76e2934c34 [cxx-interop] Re-land part of 6ba7a1e. Fix an issue with extending nested namespaces across modules.
No one should be using C++ interop yet, so this part of the change cannot break anyone.
2022-01-19 12:20:14 -08:00
Xi Ge
c5a715d4ed Revert "[cxx-interop] Fix two issues with extending nested types across modules."
This reverts commit 6ba7a1ec1e.
2021-12-08 20:00:41 -08:00
Zoe Carver
8980b8b6ec Merge pull request #40165 from zoecarver/fix-extensions-across-modules
[cxx-interop] Fix two issues with extending nested types across modules.
2021-11-16 09:08:06 -08:00
zoecarver
6ba7a1ec1e [cxx-interop] Fix two issues with extending nested types across modules.
One fix allows extending nested records in other modules, the other fixes the same issue for namespaces.
2021-11-15 16:20:15 -08:00
Alex Lorenz
1089959b0f [interop] clang name lookup should find declarations in inline namespaces 2021-11-12 17:40:38 -08:00
zoecarver
31239504c7 [cxx-interop] Allow extensions on namespaces.
This used to work and broke with lazy member loading. This commit fixes it again.
2021-11-08 13:49:25 -08:00
zoecarver
b8e52a7ad2 [cxx-interop] Lazily import members of Clang namespaces and records via requests.
Also adds a ClangImporter request zone and move some requests into it.
2021-10-20 14:52:43 -07:00
zoecarver
3454f903bf [cxx-interop] Print decls in the __ObjC module.
This is one change from #38675.
2021-09-23 15:27:32 -07:00
Egor Zhdan
cfc9483f1a C++ Interop: import namespaces redecls as separate extensions
Previously a namespace declaration was imported along with all of its redeclarations, and their members were added to a single Swift extension. This was problematic when a single namespace is declared in multiple modules – the extension belonged to only one of them.
For an example of this, try printing a module interface for `std.string`/`std.iosfwd` – it will be empty, even though the declarations from those modules are actually imported into Swift correctly.

This change makes sure that when we're importing different redeclarations of the same namespace, we're adding them as separate extensions to appropriate modules.
2021-07-23 23:38:46 +03:00
Egor Zhdan
fc2dc6aa17 C++ Interop: improve skipping already imported struct members
This fixes the issue that prevents `std::string::size_type` from being imported into Swift: `size_type` is imported before its parent struct, and  we're skipping it when importing the struct afterwards.

This is caused by an out-of-line decl for `std::string::npos`:
```cpp
template<class _CharT, class _Traits, class _Allocator>
_LIBCPP_FUNC_VIS
const typename basic_string<_CharT, _Traits, _Allocator>::size_type
               basic_string<_CharT, _Traits, _Allocator>::npos;

```
When importing `npos`, we first import `size_type`, which triggers the issue.
2021-07-17 14:45:22 +03:00
Egor Zhdan
36f13b7b91 C++ Interop: NFC: add missing requires cplusplus to the modulemaps in tests 2021-07-04 19:15:04 +03:00
Egor Zhdan
51a8c473ff C++ Interop: import namespace aliases
Previously they weren't imported, now they are imported as typealiases to enums representing namespaces.

Fixes SR-12467.
2021-05-16 17:34:51 +03:00
zoecarver
bd96959d14 [cxx-interop] Re-implement namespaces using enums + extensions.
C++ namespaces are module-independent, but enums are owned by their module's in Swift. So, to prevent declaring two enums with the same name, this patch implements a new approach to namespaces: enums with extensions.

Here's an example:
```
// Module A
namespace N { void test1(); }
// Module B
namespace N { void test2(); }
// __ObjC module
enum N { }
// Swift module A
extension N { func test1() }
// Swift module B
extension N { func test1() }
```

Thanks to @gribozavr for the great idea.
2021-02-14 16:54:24 -08:00