PrintAsClang is supposed to emit declarations in the same order regardless of the compiler’s internal state, but we have repeatedly found that our current criteria are inadequate, resulting in non-functionality-affecting changes to generated header content. Add a diagnostic that’s emitted when this happens soliciting a bug report.
Since there *should* be no cases where the compiler fails to order declarations, this diagnostic is never actually emitted. Instead, we test this change by enabling `-verify` on nearly all PrintAsClang tests to make sure they are unaffected.
This did demonstrate a missing criterion that only mattered in C++ mode: extensions that varied only in their generic signature were not sorted stably. Add a sort criterion for this.
Eliminates extraneous newlines between top-level Objective-C declarations in `-emit-objc-header` headers. Specifically, there should now always be exactly one—no more, no less—empty line between `@end` and whatever follows it.
Besides being more aesthetically pleasing, this eliminates ordering-dependent behavior where PrintAsClang would print an extra newline when visiting an empty extension, which meant that the order in which empty and non-empty extensions were visited during printing could result in whitespace differences in the compiler output. Printing the blank line is now conditional on whether `tell()` indicates that characters were actually written to the output.
Fixes rdar://143533893.
We're using C++ 14+ at least now across the project so these should not be necessary. It's also kind of wild that the definitions we had across different subsystems had different definitions.
To support nested structs, we emit type aliases in the outer class.
Unfortunately, we emitted these type aliases unconditionally, even if
the actualy nested struct was not emitted to the reverse interop header
(due to visibility or the construct being unsupported). This PR fixed
this issue by checking first if the nested entity should be included in
the reverse interop header.
rdar://141688074
Find all the usages of `--enable-experimental-feature` or
`--enable-upcoming-feature` in the tests and replace some of the
`REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which
should correctly apply to depending on the asserts/noasserts mode of the
toolchain for each feature.
Remove some comments that talked about enabling asserts since they don't
apply anymore (but I might had miss some).
All this was done with an automated script, so some formatting weirdness
might happen, but I hope I fixed most of those.
There might be some tests that were `REQUIRES: asserts` that might run
in `noasserts` toolchains now. This will normally be because their
feature went from experimental to upcoming/base and the tests were not
updated.
Currently, we do not support exporting zero-sized value types from Swift
to C++. It needs some work on our end as these types are not part of the
lowered signature. In the meantime, this PR makes sure that common (but
not all) zero sized types are properly marked as unavailable. This is
important as the proper diagnostic will give users a hint how to work
around this problem. Moreover, it is really easy to hit this when
someone is experimenting with interop, so it is important to not have a
cryptic failure mode.
rdar://138122545
Use the `%target-swift-5.1-abi-triple` substitution to compile the tests for
deployment to the minimum OS versions required for use of _Concurrency APIs,
instead of disabling availability checking.
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
We do not support any sort of indirect enums yet, the code gets into an
infinite recursion. Let's skip exporting these types to C++ for now
until proper support is implemented.
rdar://134852756
This fixes a number of test failures in reverse C++ interop.
Clang's behavior was changed in https://github.com/llvm/llvm-project/pull/93873, and it no longer accepts the C++ headers that Swift generates.
rdar://132283247
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
Embedded Swift has a minimal runtime, some type metadata is not
available. This patch works around a crash that tries to emit C++
briding to this non-existent Swift metadata. It is very likely that
there will be more fallout in reverse interop, but this patch should fix
the most glaring issue, crashing on an empty Embedded Swift project.
rdar://129030521
In some circumstances the missing trait resulted in picking the wrong
branch of some compile time conditionals resulting in code that would
not compile.
rdar://126709253
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
The code already forward declared strutcs and enums. This patch extends
the logic to also forward declare classes. Unfortunately, there was some
fallout because some traits ended up defined multiple times for some
classes, so the code is now extended to only conditionally emit these
traits if no forward declaration was emitted for the type yet.
rdar://124022242
The code wants to avoid exporting certain synthesized operators but it
inadvertently also prevented exporting accessors to static properties.
rdar://115564118
This is a fallout from emitting Swift StdLib dependencies when all
public decls are emitted. This was not found before because the test was
not executed by the CI.
rdar://131556373
This PR implements proper support for optional generic associated values
in enum cases. Most of the code changes are supporting generic types in
more contexts in the printer, the rest are making sure we handle the
null pointer case when we try to get the declaration from the type that
represents a generic parameter.
rdar://131112273
Unfortunately, we cannot generate the C++ code for them just yet. There
will be a follow-up PR to actually fix the underlying issue and expose
such enums correctly.
rdar://129250756
The generated header would not compile without these dependencies. Moreover
users probably expect all-public option to be the most permissive filter
including the maximal amount of declarations.
We export cdecl function declarations twice: for Objective-C and for
C++. When the code is compiled in Objective-C++ both of the declarations
are visible to the compiler. The generated header did not compile,
because only one of the declarations were noexcept. There are multiple
possible ways to fix this issue, one of them would make only C++
declarations visible in Objective-C++ mode. However, for this particular
problem I decided to also make the Objective-C functions SWIFT_NOEXCEPT.
This approach resolves the inconsistency that broke the code when
compiled in Objective-C++ mode. Moreover, Swift guarantees that those
cdecl declarations cannot raise errors, so in case we only generate the
C declarations and consume them from C++ or Objective-C++, those are the
correct declarations.
rdar://129550313
The generated thunks for functions can refer to some internal methods of
their arguments. As a result, those generated thunks should always be
after the definitions of the corresponding argument types. The printer
ordered the declarations by name, and Swift had the convention starting
types with upper case letters and functions with lower case letters.
This naming convention together with the ordering resulted in the
correct ordering in most of the cases. There were a couple of exceptions
when people diverged from the naming conventions or wanted to export
operators. This patch fixes this problem by always ordering type decls
before function decls.
rdar://129276354
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
In some cases, the reverse interop generated both a forward declaration and a
definition with unavailable attribute in the C++ header. Unfortunately, the
kinds of these symbol did not match. The forward declaration was templated
while the definition was not. The forward declaration has the correct kind,
so this patch extends the printing of unavailable definitions to include the
generic arguments.
rdar://119835933
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
This fixes a compiler crash that happened when emitting a Clang header for a Swift module that declares multiple macros with the same base name and different argument names.
Swift macros are not currently designed to be exposed to C++. This teaches the compiler to explicitly mark them as unavailable in C++.
rdar://117969472 / resolves https://github.com/apple/swift/issues/69656