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.
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
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
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
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
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
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
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
This is not supported, of course. But now, instead of an assertion
failure we properly mark the declaration as unavailable.
Fixes#78190.
rdar://141492654
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
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
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
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
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
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.
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.
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.
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
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.
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
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)
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
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.
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.
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.
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.
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.
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.