Commit Graph

40 Commits

Author SHA1 Message Date
susmonteiro
848fad0021 [cxx-interop] Support for printing C++ foreign references 2025-06-10 12:15:21 +01:00
susmonteiro
72b13b3b48 [cxx-interop] Fix metadata mismatch regarding fields of structs 2025-05-20 10:15:14 +01:00
John Hui
66c2e2c52b [cxx-interop] Import non-public inherited members (#79348)
This patch is follow-up work from #78942 and imports non-public members,
which were previously not being imported. Those members can be accessed
in a Swift file blessed by the SWIFT_PRIVATE_FILEID annotation.

As a consequence of this patch, we are also now importing inherited members
that are inaccessible from the derived classes, because they were declared
private, or because they were inherited via nested private inheritance. We
import them anyway but mark them unavailable, for better diagnostics and to
(somewhat) simplify the import logic for inheritance.

Because non-public base class members are now imported too, this patch
inflames an existing issue where a 'using' declaration on an inherited member
with a synthesized name (e.g., operators) produces duplicate members, leading
to miscompilation (resulting in a runtime crash). This was not previously noticed
because a 'using' declaration on a public inherited member is not usually
necessary, but is a common way to expose otherwise non-public members.
This patch puts in a workaround to prevent this from affecting the behavior
of MSVC's std::optional implementation, which uses this pattern of 'using'
a private inherited member. That will be fixed in a follow-up patch.

Follow-up work is also needed to correctly diagnose ambiguous overloads
in cases of multiple inheritance, and to account for virtual inheritance.

rdar://137764620
2025-02-25 01:03:16 -08:00
John Hui
be73254cdc [cxx-interop] Import private members (#78942)
This commit removes the guardrails in ImportDecl.cpp:SwiftDeclConverter
that prevent it from importing non-public C++ members. It also
accordingly adjusts all code that assumes generated Swift decls should
be public. This commit does not import non-public inherited members;
that needs its own follow-up patch.

Note that Swift enforces stricter invariants about access levels than C++.
For instance, public typealiases cannot be assigned private underlying types,
and public functions cannot take or return private types. Meanwhile,
both of these patterns are supported in C++, where exposing private types
from a class's public interface is considered feature. As far as I am aware,
Swift was already importing such private-containing public decls from C++
already, but I added a test suite, access inversion, that checks and
documents this scenario, to ensure that it doesn't trip any assertions.
2025-01-30 14:50:15 -08:00
Egor Zhdan
738c8fb6c6 [cxx-interop] Skip type metadata for C++ types that are only used in private C++ fields
This fixes compiler errors for C++ types that use pimpl idiom:
```
invalid application of 'sizeof' to an incomplete type
```

rdar://141960396
2025-01-13 12:03:35 +00:00
Egor Zhdan
6943986c71 [cxx-interop] Import private fields of C++ structs
While private and protected fields coming from C++ cannot be accessed from Swift, they can affect Swift typechecking.

For instance, the Swift typechecker mechanism that adds implicit `Sendable` conformances works by iterating over all of the struct's fields and checking whether all of them are `Sendable`. This logic was broken for C++ types with private fields, since they were never accounted for. This resulted in erroneous implicit `Sendable` confromances being added.

Same applies for `BitwiseCopyable`.

In addition to this, ClangImporter used to mistakenly mark all C++ structs that have private fields as types with unreferenceable storage, which hampered optimizations.

As a side effect of this change, we now also provide a better diagnostic when someone tries to access a private C++ field from Swift.

rdar://134430857
2024-11-12 12:47:26 +00:00
Akira Hatanaka
d76dbb1a64 [SILGen] Fix a bug where the wrong convention was being used for lowering a closure to a C++ function pointer (#73039)
Use the C function pointer convention instead of the block convention.

rdar://122977380
2024-04-16 15:18:50 -07:00
Alex Lorenz
8b7b1347eb [interop] C++ destination record should be destroyed before being copied into during assignWithCopy / assignWithTake 2023-03-15 12:33:31 -07:00
Zoe Carver
9850906570 Merge pull request #62330 from zoecarver/conforms-to-attr
[cxx-interop] Add ability to specify protocol conformance on C++ side.
2022-12-13 16:28:31 -08:00
Alex Lorenz
934183f854 [cxx-interop] Emit IR for std::get in structured bindings declaration 2022-12-07 15:54:11 -08:00
zoecarver
5eb7c7a6cf [cxx-interop] Add ability to specify protocol conformance on C++ side. 2022-11-30 17:26:15 -07:00
Egor Zhdan
c307ccc37f [cxx-interop] Emit IR for custom operator new
Fixes https://github.com/apple/swift/issues/62182
2022-11-23 13:15:50 +00:00
Mike Pinkerton
5c6348c6ce Test various nodiscard return cases. 2022-10-25 11:03:06 -04:00
Egor Zhdan
93e7427ed2 [cxx-interop] Emit IR for destructors of temporary C++ values
This fixes the "undefined reference" linker errors.

rdar://101092732
2022-10-21 15:34:04 +01:00
zoecarver
a353d6f272 [cxx-interop] Fix lazy member lookup for forward-declared structs inside of a namespace. 2022-07-05 11:54:02 -07:00
Egor Zhdan
0e31acb18c [IRGen] Emit missing sret for function arguments
If the IR representation of a C++ function takes an `SRet` parameter instead of a return value, Swift needs to wrap the corresponding argument with `sret(...)` on call site.

This fixes SILOptimizer crashes on arm64.

rdar://92963081
2022-07-01 17:49:33 +01:00
zoecarver
d2e3e0d4e1 [cxx-interop] Work with definition in VisitCXXRecordDecl.
This was previously un-noticed because VisitRecordDecl already handles this, but there are a couple checks that are specific to C++ records.
2022-04-18 11:57:48 -07:00
zoecarver
5db8647911 [cxx-interop] Make sure to use TUScope when looking up clang decls.
When we look up a name directly, make sure we provide a scope, this is required when C++ interop is enabled.

This issue was exposed when we look up if an NSString is hashable. There is a special case for classes that inherit from NSObject, but we didn't see that, because we couldn't find NSObject (because lookup failed).
2022-03-17 16:26:57 -07:00
Daniel Rodríguez Troitiño
746080d6d1 [ClangImporter] Suffix ambiguous protocol names if C++ interop is enabled
The Clang Importer when C++ interop is not enabled, disambigate an Obj-C
class and protocol that are named the same by appending `Protocol` to
the protocol. This was not happening when C++ interop was enabled, but
should also apply to Obj-C++ modules.

The fix is providing an starting scope for the search, which the C++
name lookup need to actually find the similarly named counterpart.

Includes a test to avoid this problem creeping in again, and locally it
did not break any other tests.
2022-03-11 17:18:07 -08:00
Egor Zhdan
06612934e8 C++ Interop: support mutating attribute for C++ methods
This change teaches ClangImporter to import C++ methods marked with `__attribute__((__swift_attr__("mutating")))` as mutating in Swift. This is useful, for example, when a method mutates `this` despite being `const` in C++ (e.g. via `const_cast`).
2021-11-29 21:13:16 +03: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
Egor Zhdan
9adad3202e C++ Interop: add tests for extensions of C++ classes 2021-04-16 20:25:57 +03:00
zoecarver
abab6b3332 [cxx-interop] Bail earlier when importing invalid records.
If we have a C++ record decl that's invalid (because of a deleted
destructor or copy constructor), bail before we import any of its
members or cache the decl. This way, we don't accidentally import any
"nested" decls.
2021-03-17 11:25:07 -07:00
zoecarver
467ff0a796 [nfc][gardening] Add requires cplusplus to LinkedRecords module. 2021-02-15 21:02:37 -08:00
zoecarver
ffa0d1cf93 [cxx-interop] Add support for custom C++ destructors.
This patch adds support for custom C++ destructors. The most notable thing here, I think, is that this is the first place a struct type has a custom destructor. I suspect with more code we will expose a few places where optimization passes need to be fixed to account for this.

One of many patches to fix SR-12797.
2021-01-27 12:54:48 -08:00
zoecarver
ecd1018799 [cxx-interop] Use cached record when possible.
It is not completely uncommon for a record to get imported while
importing it's members (for example, if the member points back to the
parent record). In this case, simply use the already-imported record.
This should improve performance but also prevent an error where a member
accidentally had two parents.

This patch also moves around some of the member import/add logic to
allow for the above "optimization."
2021-01-13 11:19:36 -08:00
Saleem Abdulrasool
df9d1e815f Interop/Cxx: explicitly require C++ for modules
The C++ interop modules require C++ support.  Explicitly require C++ as
a feature when building these modules.  This has no impact on the
changes as all the tests enable C++ already.
2021-01-06 16:59:42 -08:00
zoecarver
222d2fe709 [cxx-interop] Support nested C++ record types.
Simply returns "None" for C++ records in "getSpecialManglingContext"
(same logic as namespaces) to prevent an assertion.
2020-11-13 14:22:22 -08:00
Martin Boehme
faca489c6f Add a test that Objective-C types passed to a C++ constructor are
bridged correctly.
2020-10-09 10:42:52 -07:00
Martin Boehme
3066e16c37 Remove redundant "cxx" from test names. 2020-10-09 10:42:48 -07:00
Martin Boehme
fd00bc1f01 Move tests from CXXInterop to Interop/Cxx.
This is the canonical location that we've agreed on.
2020-10-09 10:42:47 -07:00
zoecarver
5c3ccf5050 [cxx-interop] Temporarily disable emitting debug info for C++ types.
When we try to emit debug info from C++ types we crash because we can't deserialize them. This is a temporary fix to circumnavigate the crash before a real fix can be created.
2020-07-23 12:10:06 -07:00
zoecarver
13632d4c9c [cxx-interop] Mark types with a destructor a non-trivial.
Any C++ type that isn't trivially copyable is now also not a trivial type. This will preserve the destructor (among other things).
2020-07-10 08:51:30 -07:00
zoecarver
4b14487345 [NFC] [cxx-interop] Add SILGen tests for synthesized initializers.
Adds a basic test that the synthesized C++ constructor was generated correctly.
2020-07-02 15:07:42 -07:00
Michael Forster
e69abeba53 Classify C++ structs as loadable or address-only (#31707)
* Classify C++ structs as loadable or address-only

C++ structs are only loadable if they are trivially copyable.

Resolves SR-12472.
2020-05-13 17:16:47 +02:00
Dmitri Gribenko
e355430927 Merge pull request #31619 from MForster/m/memberwise-initializer
Synthesize memberwise initializers despite AccessSpecDecl
2020-05-08 01:07:49 +02:00
Michael Forster
d611b4c4f5 Synthesize memberwise initializers despite AccessSpecDecl
Previously the mere presence of `public:` or `private:` inhibited the
synthesis of memberwise initializers.
2020-05-07 17:44:41 +02:00
Martin Boehme
6224909d37 Add a test that imported C++ classes can conform to protocols.
Currently, trying to do this causes an assertion failure in SILGen, so the
corresponding line in the SILGen test is commented out.

See https://bugs.swift.org/browse/SR-12750
2020-05-07 14:43:21 +02:00
Michael Forster
f609a7cbb4 Unify layout for C++ interop tests
This was discussed here:
https://forums.swift.org/t/reorganize-swift-compiler-tests-for-c-objc-c-interop/34411

Resolves: [SR-12475](https://bugs.swift.org/browse/SR-12475)
2020-04-06 09:38:18 +02:00
Michael Forster
98bbb81f82 [C++] Make const member variables read-only
This imports const members of C++ structs/classes stored properties with
an inaccessible setter.

Note that in C++ there are ways to change the values of const members,
so we don't use `WriteImplKind::Immutable` storage.

Resolves: [SR-12463](https://bugs.swift.org/browse/SR-12463)
2020-04-03 13:15:33 +02:00