Commit Graph

127 Commits

Author SHA1 Message Date
zoecarver
a6a0f637ab [nfc][cxx-interop] Fix a few tests. 2023-07-18 17:42:54 -07:00
Egor Zhdan
6e7fb3263b [cxx-interop] Tweak C++ type semantics detection
`CxxRecordSemanticsKind::ExplicitlyUnsafe` and `CxxRecordSemanticsKind::UnsafePointerMember` were never directly used, and those do not indicate semantics: they indicate safety of the type when used from Swift, which should be handled by another request `IsSafeUseOfCxxDecl` instead of `CxxRecordSemantics`.

Having `ExplicitlyUnsafe` and `UnsafePointerMember` as semantics indicators was problematic, for instance, for types that are move-only and store a pointer at the same time. Swift allowed the usage of these types (under the rules for `UnsafePointerMember` types) when move-only types are disabled, and did not apply the move-only attribute on such types when move-only types are enabled.

rdar://110644300
2023-07-04 20:12:06 +01:00
Egor Zhdan
b459fb5fc2 [cxx-interop] Avoid linker errors when calling a defaulted constructor
When a default constructor is declared, but does not have a body because it is defaulted (`= default;`), Swift did not emit the IR for it. This was causing linker error for types such as `std::map` in libstdc++ when someone tried to initialize such types from Swift.

rdar://110638499 / resolves https://github.com/apple/swift/issues/61412
2023-06-12 20:06:49 +01:00
Alex Lorenz
b25dec58ba [cxx-interop] add a SWIFT_MUTATING customization macro
Fixes https://github.com/apple/swift/issues/66322
2023-06-06 10:54:40 -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
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
e26109f71e Merge pull request #64459 from hyp/eng/conforms_to++
[interop] 'conforms_to' attribute should be qualified with module name
2023-03-17 20:18:37 -07:00
Alex Lorenz
90d1c24674 [interop] 'conforms_to' attribute should be qualified with module name
Also, improve the diagnostics for 'conforms_to'
2023-03-17 15:09:27 -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
Egor Zhdan
fc5215f0f8 [cxx-interop] Treat C++ structs that store iterators as unsafe
C++ types that store pointers as fields are treated as unsafe in Swift. Types that store other types that in turn store pointers are also treated as unsafe.

Types that store raw C++ iterators are also treated as unsafe in Swift. However, a type that stores another type that stores a raw iterator was previously imported as safe. This change fixes that.

rdar://105493479
2023-02-15 13:50:35 +00:00
Egor Zhdan
745d92d9cb [cxx-interop] Allow instantiated operator methods to serve as protocol conformance witnesses
If a templated C++ class declares an operator as a member function, and is instantiated using a typedef or a using-decl on the C++ side, it previously could not be conformed to a Swift protocol that requires the operator function despite matching signatures.

This was due to a Swift name lookup issue: operators, unlike regular member functions, are found by doing an unqualified lookup. Since C++ class template specializations and their members are not added to `SwiftLookupTable`, when doing qualified lookup members are searched by looking at all of the members of the specialization and choosing the ones with matching names. With unqualified lookup, we cannot rely on knowing the right specialization and need to search for all the operators in a given module.

This change adds synthesized operator thunks to `SwiftLookupTable` to make them discoverable by unqualified lookup.
2023-01-03 13:57:08 +00: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
Saleem Abdulrasool
ad1bd8e685 Update mutability-annotations.h 2022-10-08 20:33:17 -07:00
Anthony Latsis
a65f1a161e Gardening: Migrate test suite to GH issues: Interop 2022-08-31 05:20:25 +03:00
Egor Zhdan
6fa2daf496 [cxx-interop] Do not crash when importing anonymous classes
This was discovered during interop adoption in SwiftCompilerSources.
```
/Volumes/Projects/swift/swift/include/swift/SIL/SILNode.h:180:5 <Spelling=/Volumes/Projects/swift/swift/include/swift/SIL/SILNode.h:171:3>: while adding SwiftName lookup table entries for clang declaration 'swift::SILNode::SharedUInt8Fields::(anonymous)'
```
2022-07-25 11:43:31 +01:00
zoecarver
6acffbbee6 [cxx-interop] Flip the switch: only import safe APIs. 2022-07-18 17:15:15 -04:00
Egor Zhdan
44c35a2971 [cxx-interop] Fix lookup of member operators
Calling `StructDecl::lookupDirect` with an operator identifier (e.g. `==`) previously returned no results. This happened because the underlying C++ operator function was added to the lookup table with an underscored name (e.g. `__operatorEqualEqual`), and the synthesized function was not added to the lookup table at all. Lookup should find the synthesized decl, since that is what Swift code will call.

This fixes a typechecker error when trying to conform a C++ struct that defines an operator to a Swift protocol with an operator requirement (e.g. `Equatable`).
2022-07-15 16:53:39 +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
Egor Zhdan
d04675aa46 Merge pull request #59613 from apple/egorzhdan/cxx-typecheck-iuo
[cxx-interop] Allow conforming C++ APIs that return IUO to Swift protocols
2022-06-27 20:34:31 +01:00
Saleem Abdulrasool
fc070c6167 platform: restructure visualc module
Restructure the `visualc` module into `vcruntime` in order to help
expose the various components (SAL, vcruntime, ucrt, corecrt, STL) for C++
modularization.  Include the `stdint.h` textually to deal with
redefinition of types in clang resources and MSVC.
2022-06-26 14:06:59 -07:00
Egor Zhdan
546accbcf9 [cxx-interop] Allow conforming C++ APIs that return IUO to Swift protocols
If a C++ method returns a pointer and is not annotated with `returns_nonnull`, ClangImporter imports its return type as implicitly unwrapped optional `UnsafePointer<T>!`. This happens, for example, for `begin()`/`end()` methods of C++ collection types.

We would like to be able to conform C++ collections to `Swift.Sequence`/`Swift.Collection`/... To make this work, we create Swift protocols that require `func begin() -> RawIterator` and `func end() -> RawIterator` where `RawIterator` is an associated type.

The problem is that currently if `RawIterator` is `UnsafePointer<T>?`, `begin()`/`end()` methods that return an implicitly unwrapped optional `UnsafePointer<T>!` won't satisfy the requirements. This change fixes that.
2022-06-21 19:41:15 +01:00
Sam Kortekaas
91bc7534ea [cxx-interop] Add diagnostics for nonmutating attr that has no effect 2022-04-28 15:42:56 +02:00
Sam Kortekaas
23b2fa9753 [cxx-interop] Add diagnostic for contradicting mutability annotations 2022-04-28 15:42:56 +02:00
Sam Kortekaas
60fe6aae95 [cxx-interop] Add a "nonmutating" swift_attr attribute
Previously, the clang importer marked all const methods as mutating whenever a C++ record had mutable fields. This change allows overriding this behavior by using the "nonmutating" swift_attr attribute.

Fixes SR-15907.
2022-04-28 15:42:56 +02: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
zoecarver
036361d1e4 [cxx-interop] Add SIL function representation cxx_method; Support extending C++ types.
There are three major changes here:
    1. The addition of "SILFunctionTypeRepresentation::CXXMethod".
    2. C++ methods are imported with their members *last*. Then the arguments are switched when emitting the IR for an application of the function.
    3. Clang decls are now marked as foreign witnesses.

These are all steps towards being able to have C++ protocol conformance.
2022-01-06 14:26:47 -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
655c381b32 [cxx-interop] Using shadow with class template.
Fail correctly if we can't import a shadow decl properly. We can
probably support this in the future, but right now, it's more important
that we don't crash while importing.
2021-03-07 10:55:38 -08:00
Zoe Carver
43c7ad7f46 Merge pull request #34864 from zoecarver/cxx/fix/friends
[cxx-interop] Support forward declared records inside other records.
2021-02-22 22:06:34 -08:00
zoecarver
f6a31e0483 [cxx-interop][nfc] Support forward declared records inside other records.
The pattern:

    struct X { friend struct Y; }; struct Y {};

is fairly common. But before this commit we would crash while attempting
to add "Y" as a child of "X". This commit simply checks if the child
record is a declaration or definition. If the former, it bails (and the
"child" record will be imported where it's defined).
2021-02-22 13:02:02 -08:00
zoecarver
467ff0a796 [nfc][gardening] Add requires cplusplus to LinkedRecords module. 2021-02-15 21:02:37 -08:00
zoecarver
fc33728613 [cxx-interop] Skip already-imported sub decls.
Rather than skipping non-definitions, we should just check whether we've
already seen this decl. This not only fixes the specific problem with
class templates but also is a more general fix for other sub decls.
2021-02-12 16:32:41 -08:00
zoecarver
b2b7f7b853 [cxx-interop] Use user defined copy constructor to copy C++ objects.
If a user-defined copy constructor exists, use that to copy imported C++
types.
2021-02-03 14:34:07 -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
7ac1b8121e [cxx-interop] Skip forward-declared nested structs.
This prevents us from accidentially adding the same sub-type twice.
2020-12-22 13:23:12 -08:00
Marcel Hlopko
bde9c3b683 [cxx-interop] Fix header guards in test/Interop (#35039) 2020-12-15 09:20:19 +01:00
Zoe Carver
d048e0554a Merge pull request #34649 from zoecarver/cxx/no-import-no-destructor
[cxx-interop] Don't import C++ objects that we can't destroy.
2020-11-14 12:42:13 -08:00