Commit Graph

180 Commits

Author SHA1 Message Date
Patryk Stefanski 54d06487c6 Merge pull request #88597 from patrykstefanski/add_returns_retained_annotations_to_cxx_thunks
[cxx-interop] Add RETURNS_RETAINED annotations to C++ thunks
2026-05-05 16:27:38 -07:00
Gábor Horváth 4bb59986f5 Merge pull request #88565 from Xazax-hun/move-only-reverse-interop 2026-04-25 07:02:48 +01:00
Patryk Stefanski ad022559fc [cxx-interop] Add RETURNS_RETAINED annotations to C++ thunks
Swift functions exposed to C++ return +1 (retained) values, but the
generated C++ thunks in the -Swift.h header lacked ownership
annotations. This prevented Clang's static analyzer from verifying
reference counts when C++ code calls into Swift.

Add NS_RETURNS_RETAINED, CF_RETURNS_RETAINED, and SWIFT_RETURNS_RETAINED
annotations to thunk signatures based on the return type:
- NS_RETURNS_RETAINED for ObjC classes (NSString, etc.) and existentials (id)
- CF_RETURNS_RETAINED for CF types (CFString, etc.)
- SWIFT_RETURNS_RETAINED for foreign reference types

rdar://165231653
2026-04-24 22:25:32 -07:00
Gabor Horvath 7182a9f2f7 [cxx-interop] Basic support for move-only clang types in reverse interop
Currently, move only types are never exposed in reverse interop because
the generated interop header does not support Swift's move semantics. On
the other hand, Clang types work out of the box with borrowing. This PR
enables exporting Swift functions that are borrowing or returning
move-only Clang types.

The consuming specifier does not work yet, that needs some changes to
the generated function bodies and can be done in a follow-up PR.

rdar://162361370
2026-04-20 17:19:38 +01:00
Gabor Horvath 32ac94f76a [cxx-interop] Prevent emitting conflicting decls for properties
Instead of having a property-specific mechanism to detect duplicates,
let's use the generic facilities we have to detect problems with method
overloading. This both fixes an issue where we generated reverse interop
headers that would not compile when a user written method has the sanem
name as the getter we generate on the C++ side. But it also makes the
detection more flexible allowing for overloading when the parameter
types differ.

rdar://164465903
2026-04-17 12:19:19 +01:00
Gabor Horvath 84411d0794 [cxx-interop] Support pointers to C types in reverse interop
Previously, we never exported Swift functions that have pointers to C or
C++ structs in their signature. These pointers are always safe to pass,
we have declarations on the C/C++ side and we have no ABI issues.

rdar://172205792
2026-03-16 11:17:41 +00:00
Gabor Horvath 9ebb656b27 [cxx-interop] Fix crash trying to expose Swift existentials to C++
Confusingly, isObjC on an existential does not check if the super class
is actually ObjC. Make the check stricter to avoid a crash down the
line.

rdar://169210092
2026-02-02 16:07:52 +00:00
Slava Pestov 4282bb1746 ASTMangler: Use ASTContext stored in the mangler instance instead of fishing it out of random places 2026-01-02 15:15:15 -05:00
Gabor Horvath 181122edf9 [cxx-interop] Fix crashing on recursive enums
Introduce a cache that helps cutting the recursion when we process a
type that we already visited before but did not finish processing yet.

Fixes #85361

rdar://164153038
2025-12-11 15:24:03 +00:00
Egor Zhdan 2db0e8aea8 Merge pull request #85439 from egorzhdan/egorzhdan/endif-objc
[cxx-interop] Emit `#endif // defined(__OBJC__)` with the comment consistently
2025-11-13 03:59:17 +00:00
Egor Zhdan 8cafef09c3 [cxx-interop] Emit #endif // defined(__OBJC__) with the comment consistently
This makes sure that whenever we emit `#if defined(__OBJC__)`, the matching `#endif` has a comment `// defined(__OBJC__)`.

This makes both testing and reading the header file easier.
2025-11-12 11:51:10 +00:00
Anthony Latsis bda6edb85c AST: Rename GenericContext::isGeneric to hasGenericParamList
`isGeneric` is a misleading name because this method checks for the
existence of a `GenericParamList`, which is not implied by genericity.
2025-11-11 15:55:16 +00:00
Gabor Horvath 98078817d0 [cxx-interop] Support SIMD types in reverse interop
This supports both built-in vector types and the SIMDX<T> Swift types
that are used through type aliases like float3. These SIMD types are
passed via compatibility structs (with their valued memcpy-d into the
ABI compatible struct) as they have special ABI rules. E.g., a float3 is
not passed as float3, but as float4 on the ABI level.

Previously, we did not expose simd types from Swift to C++ (unless the
SIMD types were impoted from clang).

rdar://153218744
2025-09-09 14:50:54 +01:00
Gabor Horvath 45f0be2dd4 [cxx-interop] Properly support OS objects in reverse interop
These objects are behind typedefs and user code supposed to use the
typedef names. We already have some logic in place for Obj-C interop.
Reuse the same logic for C++ to use the correct names.

rdar://150453489
2025-08-12 18:06:08 +01:00
Gabor Horvath a8a4f8af19 [cxx-interop] Fix passing optional CoreFoundation types from Swift to C++
These types are passed around as reference counted pointers, so the
optional representation of them are nullable pointers. Previously, we
tried to wrap them in swift::Optional.

rdar://157667946
2025-08-08 14:00:12 +01:00
Gabor Horvath 9b1b9b774b [cxx-interop] Types exposed from ObjC modules should be behind a macro
Functions or template instantiations with Obj-C types should always be
behind a macro to make sure the interop header compiles cleanly in C++.

rdar://152836730
2025-07-11 18:22:39 +01:00
Gabor Horvath 616de41526 [cxx-interop] Fix nested structs for non-opaque types
The test for nested constructs used library evolution forcing all types
to be opaque. As a result some code paths for non-opaque types were not
updated to support nested types. This patch updates the rest of the code
making sure we use fully qualified names (so they also work in the
context of the nested classes), and generate correct names for the C
compatibility structs that cannot contain "::".

Fixes #80291

rdar://147882976
2025-04-03 15:30:01 +01:00
Gabor Horvath d631b9a3d2 [cxx-interop] Support foreing reference types in generic context
Print the type traits in reverse interop to enable the use of foreign
reference type in generics like Swift arrays. Also make sure optional
foreign reference types can be passed around as raw pointers.

rdar://108139769
2025-03-25 13:55:33 +00:00
Gabor Horvath fa229469a8 [cxx-interop] Do not create copies of optionals of nullable pointers
In reverse interop, we create copies of values that will be consumed by
the Swift function. This is not necessary for pointers that are passed
as swift::Optional to Swift. These are layout compatible, and consuming
a pointer should not require us to do anything extra, hopefully ARC
would take care of all the details.

rdar://146855233
2025-03-14 13:23:46 +00:00
Gabor Horvath 8603dfe53a [cxx-interop] Support nested classes in reverse interop
Turns out we already had most of the building blocks given we already
support nested structs.

rdar://143343490
2025-02-03 14:56:31 +00:00
Gabor Horvath e340773dcb [cxx-interop] Fix assert failure exporting C++ types to Obj-C
This is not supported, of course. But now, instead of an assertion
failure we properly mark the declaration as unavailable.

Fixes #78190.

rdar://141492654
2024-12-16 21:08:21 +00:00
Kuba Mracek 6f4ae28520 [ASTMangler] Pass ASTContext to all instantiations of ASTMangler 2024-12-02 15:01:04 -08:00
Gabor Horvath 0e03d342fe [cxx-interop] Support ObjC protocols in C++ interop
This patch introduces handling of ObjC protocols similar to how ObjC
classes work. Since this only works in ObjC++, all declarations
containing ObjC protocols will be protected by the __OBJC__ macro.

This patch results in some `_bridgeObjC` methods being exposed, we might
end up hiding those in the future, but there is no harm having them in
the interop header for the interim period.

rdar://136757913
2024-10-16 18:51:35 +01:00
Gabor Horvath 94b466656e [cxx-interop] Support nested structs
It is really involved to change how methods and classes are emitted into
the header so this patch introduces the impression of nested structs
through using statements and still emits the structs themselves as top
level structs. It emits them in their own namespace to avoid name
collisions. This patch also had to change some names to be fully
qualified to avoid some name lookup errors in case of nested structs.
Moreover, nesting level of 3 and above requires C++17 because it relies
on nested namespaces. Only nested structs are supported, not nested
classes.

Since this patch is already started to grow quite big, I decided to put
it out for reviews and plan to address some of the shortcomings in a
follow-up PR.

rdar://118793469
2024-09-10 13:22:17 +01:00
Gabor Horvath 57e00e4ecf [cxx-interop] Support operator[] with multiple parameters
C++ only support multiparameter operator[] in C++23 and up. Change the
code to protect such overloaded operators with a C++ language mode
check.

rdar://133539699
2024-08-09 15:33:47 +01:00
Gabor Horvath c4649edc2c [cxx-interop] Support reexposing C structs from Swift to C++
Previously, when a Swift API referenced a C struct (that is not a C++
struct), we did not expose said API to C++. The reason was that we do
not have support yet for non-trivial structs (structs with ARC fields).
This patch introduces logic to determine if a C struct is trivial and
lets us expose trivial C structs from Swift to C++.

rdar://111812577
2024-08-05 17:44:00 +01:00
Gabor Horvath e195093aee [cxx-interop] Fix the printing of types with generic arguments
Previously the code got the declaration for types with generic
arguments and the printer used the declaration. This was a lossy
operation, we printed the type with generic parameters instead of the
arguments. This patch makes sure we print the type with the arguments.
Unfortunately, the code structure is not the most clear, type printing
is currently inherently part of the function signature printing. This
code path needs to be factored out in the future to make the code easier
to understand.

rdar://130679337
2024-07-22 13:42:24 +02:00
Gábor Horváth 78b0fd75bf Merge pull request #74654 from swiftlang/gaborh/reenable-exposing-frts
[cxx-interop] Reenable exporting Foreign Reference Types to C++
2024-06-26 13:38:53 +01:00
Becca Royal-Gordon 9f18481dc8 Merge pull request #74637 from beccadax/enum-my
[PrintAsCxx] Fix printing of C++ enum args
2024-06-24 13:51:58 -07:00
Gabor Horvath 7b72e8f6d7 [cxx-interop] Reenable exporting Foreign Reference Types to C++
This feature worked prior 5.10 but the semantics was undefined. This PR
restores the behavior with the old semantics, and a separate PR will
update the documentation to describe the behavior.
2024-06-24 17:59:49 +01:00
Becca Royal-Gordon 7fa35d4d6a [PrintAsCxx] Fix printing of C++ enum args
Because imported enums are @objc, they were treated as unsupported in C++ and therefore ineligible to be printed in a C++ generated header. Narrow this logic so that only @objc *classes* are excluded, and update related printing logic to support enums correctly.

Fixes rdar://124262637.
2024-06-21 16:01:55 -07:00
Tim Kientzle 1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Akira Hatanaka d92f181ace Create two versions (for caller and callee) of the functions that answer questions about parameter convention (#74124)
Create two versions of the following functions:

isConsumedParameter
isGuaranteedParameter
SILParameterInfo::isConsumed
SILParameterInfo::isGuaranteed
SILArgumentConvention::isOwnedConvention
SILArgumentConvention::isGuaranteedConvention

These changes will be needed when we add a new convention for
non-trivial C++ types as the functions will return different answers
depending on whether they are called for the caller or the callee. This
commit doesn't change any functionality.
2024-06-18 09:06:09 -07:00
Gábor Horváth b810077a48 Merge pull request #74339 from apple/gaborh/print-function-sig-transactional
[cxx-interop] Make function signature printing transactional
2024-06-18 13:04:53 +01:00
Gábor Horváth de9aefc842 Merge pull request #74330 from apple/gaborh/core-foundation-types
[cxx-interop] Fix extra indirection when exporting CFData arguments
2024-06-13 08:29:34 +01:00
Gabor Horvath ae1f8042c0 [cxx-interop] Fix extra indirection when exporting CFData arguments/return values
The clang nodes associated with Swift's Core Foundation types can already be
represented by a pointer. The interop code does not need to add an extra
layer of indirection in those cases.

rdar://119840281
2024-06-12 16:39:20 +01:00
Gabor Horvath cee81a4c48 [cxx-interop] Make function signature printing transactional
The function responsible for printing signatures can return in the middle
of the printing process whenever it discovers an unsupported scenario.
To avoid creating a header that cannot be compiler, this function should
be transactional. It either has to succeed and write the signature to the
stream, or in case it failed, the stream should be untouched. This patch
introduces a temporary buffer that is flushed to the stream as the last
step for a successful execution. This should make the user experience
better whenever the user stumbles upon something that is unsupported.
2024-06-12 16:26:17 +01:00
Gabor Horvath 064a7dd9a0 Address review comments. 2024-06-10 14:18:54 +01:00
Gabor Horvath 53861a4e00 [cxx-interop] Avoid emitting methods that cause name clash
In Swift, we can have enum elements and methods with the same name, they are overloaded.
Unfortunately, this feature is not supported by C++ interop at the moment. This patch
avoids emitting the methods with name collisions to make sure the resulting header
can be compiler. A proper fix should follow in a later PR.

rdar://128162252
2024-06-10 12:35:44 +01:00
Tim Kientzle 1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Ben Barham 1fdda023b3 Rename StringRef::endswith references to StringRef::ends_with
Missed this when doing the `startswith` renaming. `endswith` has also
been deprecated upstream (and presumably soon to be removed).
2024-04-01 10:59:16 -07:00
Becca Royal-Gordon a02698ba06 [PrintAsClang] Fix thunks for throwing Never funcs
Extend the previous commit’s support for functions that return Never to also properly generate code for *throwing* Never functions. This is a little subtle because:

• At the SWIFT_CALL level, throwing Never functions are *not* noreturn
• At the thunk level, throwing Never functions are noreturn *only* if you’re using exceptions; if you’re using swift::Expected, they should throw
• In either case, the compiler cannot statically prove that thunks are noreturn except on the error path, so we need to add an abort() call on the success path
2024-03-29 22:12:20 -07:00
Becca Royal-Gordon 80f38be3b8 [PrintAsClang] Fix thunks for Never funcs
Swift-to-C++ thunk printing for functions didn’t really take into account Swift’s `Never` type. This type maps to `SWIFT_NORETURN`, but it also requires other tweaks to code generation, such as omitting the `return` keyword. (Removing that requires minor changes to many tests.)

Fixes rdar://124137073.
2024-03-29 22:12:19 -07:00
Ben Barham 9779c18da3 Rename startswith to starts_with
LLVM is presumably moving towards `std::string_view` -
`StringRef::startswith` is deprecated on tip. `SmallString::startswith`
was just renamed there (maybe with some small deprecation inbetween, but
if so, we've missed it).

The `SmallString::startswith` references were moved to
`.str().starts_with()`, rather than adding the `starts_with` on
`stable/20230725` as we only had a few of them. Open to switching that
over if anyone feels strongly though.
2024-03-13 22:25:47 -07:00
Doug Gregor 19c08ee569 [Clang printing] Loosen assertion on noncopyable & nonescaping requirements
Noncopyable and nonescaping APIs in Swift can be expressed in C++ with
some downsides. Teach the AST printer to be more lenient, allowing
Swift APIs involving noncopyable and nonescapable types to be printed.
2024-03-05 14:01:21 -08:00
Slava Pestov 6cc4738506 C++Interop: Relax some noncopyable generics assertions 2024-02-26 13:08:11 -05:00
Akira Hatanaka fe88a00c81 [interop][SwiftToCxx] Skip emitting an accessor method if its name collides with an accessor method of another property
Resolves rdar://119835520 and rdar://119835571.
2024-02-21 17:29:14 -08:00
Ben Barham ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Slava Pestov 57b768db8c ClangImporter: Missed a few more places where they check for requirements 2024-02-01 17:17:43 -05:00
Alex Lorenz bcdfb8da28 [interop][SwiftToCxx] dispatch 'class' methods directly to avoid broken header generation
rdar://102393950
2023-11-07 14:33:54 -08:00