Commit Graph

172 Commits

Author SHA1 Message Date
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
Alex Lorenz
645073de55 [interop][SwiftToCxx] do not expose Swift APIs with shared FRTs as their ownership is not yet managed at the language boundary 2023-10-30 10:54:25 -07:00
Alex Lorenz
4e519a8d8b [interop][SwiftToCxx] consuming parameters should be passed using an additional copy
Fixes https://github.com/apple/swift/issues/69372
2023-10-27 17:29:52 -07:00
Alex Lorenz
f623683185 [interop][SwiftToCxx] do not emit direct returns/passes when Swift's value type ABI is not yet supported 2023-08-01 18:43:13 -07:00
Evan Wilde
250082df25 [NFC] Reformat all the LLVMs
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
2023-06-27 09:03:52 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Alex Lorenz
c7836e3a8e [interop][SwiftToCxx] avoid emitting ambiguous C++ overloads
Just do an arity check for now
2023-05-05 17:07:43 -07:00
Alex Lorenz
7efae9a74c [interop][SwiftToCxx] add additional type representation emission check for associated enum element types
This ensures that we do not try to emit enums whose associated values come from dependent modules that don't have a C++ representation
2023-04-24 12:31:30 -07:00
John McCall
0e932329c3 Fix fulfillments for type metadata and witness table packs
A lot of the fixes here are adjustments to compensate in the
fulfillment and metadata-path subsystems for the recent pack
substitutions representation change.  I think these adjustments
really make the case for why the change was the right one to make:
the code was clearly not considering the possibility of packs
in these positions, and the need to handle packs makes everything
work out much more cleanly.

There's still some work that needs to happen around type packs;
in particular, we're not caching them or fulfilling them as a
whole, and we do have the setup to do that properly now.
2023-03-10 12:52:37 -05:00