This can help work around problems when the names of a C++ declaration
and a Swift declaration would collide, or to temporarily work around
compiler bugs.
rdar://152838988&140802127&158843666
Reverse interop has logic that avoids emitting ambiguous overloads into the generated header. That logic did not apply for functions declared within Swift extensions. This meant that the generated C++ header would sometimes not compile.
rdar://158252800
These are the minimal changes to make the reverse interop header compile
when embedded Swift is used. Previously, the _SwiftStdlibCxxOverlay.h
and the generated interop header disagreed on the mangling of a symbol.
This is not sufficient yet to use the embedded Swift standard library from
reverse interop, there are some missing symbols while linking. But this
PR enables doing reverse interop without using the stdlib types like
swift::String in C++. Follow-up PRs will fix the rest of the issues.
rdar://154740225
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
There was a hard to see misalignment between types accepted as
representable in C languages defined in `BuiltinMappedTypes.def` and
those with an associated C type name defined in `PrimitiveTypeMapping`.
While `BuiltinMappedTypes` looked through typealiases,
`PrimitiveTypeMapping` didn't and instead referred only to types by
their identifier. So even when both files defined the same types by
name, their underlying type were only partially handled. An affected
type was `Unicode.Scalar` which is the underlying type of `CWideChar`
and `CChar32`. `Unicode.Scalar` was accepted as a C representable type
but was not printed using a corresponding C type name, breaking the
generated compatibility header.
Another issue with the use of identifiers in the PrimitiveTypeMapping
logic was a limited support for nested types. It would track
`Unicode.Scalar` only as `Scalar`.
This change updates `PrimitiveTypeMapping` to keep track of TypeDecls
instead of identifiers and look through typealiases. This fixes the
issue with `Unicode.Scalar`, allowing it to be printed using the type
defined by an alias and avoid matching an unrelated Scalar. It should
also prevent future types behind typealiases to trigger this same kind
of misalignment.
rdar://157332446
Fix crash when printing references to Unicode.Scalar in the
compatibility header.
Unicode.Scalar should not be printed in the first place, it's a Swift
struct. It should either be considered non-representable or printed as a
C / Objective-C type if that's the intent.
rdar://157120538
We sometimes don't have the information in the modulemaps whether a
module requires ObjC or not. This info is useful for reverse interop.
This PR introduces a frontend flag to have a comma separated list of
modules that we should import as if they had "requires ObjC" in their
modulemaps.
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
In the reverse interop header we generated move constructors that call
abort at runtime. This is problematic for several reasons:
* In C++14 and below some of our own generated functions like _make
ended up calling the move constructor. Those are calling abort and
also trigger unreachable code warning in newer versions of Clang.
In C++17 and up it is fine due to the guaranteed copy elision.
* Type traits are fooled and think these types are movable. As a result,
libraries could generate calls to the aborting move ctor.
This PR removes the generation of move operations. As we generate copy
operations, the compiler will not declare or define the move operations
implicitly. Whenever the user goes out of their way and try to move an
object they will get a copy instead.
rdar://150793518
The generated header did not compile due to a bug that prevented us from
referencing the correct namespaces derived from the nominal type's name
(an extension does not have a name). Moreover, we did not generate
forward declarations for the members of the extensions for classes and
enums (but we did for structs). This change also removes a workaround
that emitted String::Index as _String_Index.
rdar://153221450
There are two main scenarios when printing a compatibility header that
references a @cdecl enum defined in Swift code. (1) When defined in the
same module as it's used we can print the definition normally and then
reference it. (2) When used in a different mode we need to print a
forward declaration before we can reference it.
This change adds printing the forward declaration and fix an issue where
the compiler would instead print an @include of the Swift module. The
import of the Swift module would work only in a local scenario where a
compatibility header and module would be generated under the same name.
However for a distributed frameworks we do not distribute the
compatibility header so this strategy doesn't work. Relying on a forward
declaration should be more reliable in all cases but clients may need to
import the other compatibility header explicitly.
Print @cdecl enums in the C section of the compatibility header. Use and
extend the macros to support C compiler clients.
The macro is adapted to the features supported by the client compiler.
It uses an Objective-C style macro with raw type when available and
fallbacks to a simple typedef for C compatibility.
Start printing `#include` for headers referenced from `@cdecl` function
signatures. This adds on top of the existing tiered imports. We already
print each module referenced from decls printed in the compatibility
header. Previously we printed mostly `@import` with an option to
fallback on a `#import`. This change adds a third fallback to `#include`
when the module is referenced from a `@cdecl` function signature. The
bridging header can also be imported in a similar way.
Add a block for C clients in the compatibility header. This block
contains only the `@cdecl` functions that are printed using only C
types.
This C block is printed above the Objective-C and C++ blocks as if we
add support for `@cdecl` types other languages should be able to
reference them in function signatures. Other languages block don't
duplicate printing the `@cdecl` functions either as they are already
accessible to them.
To trigger this error one needs to import a nested type from C++, use it
in a generic context in Swift, and export it back to C++. We were
inconsisent in what namespace did we declare the functions to get the
type metadata for types. It was in the swift namespace for foreign types
and in the module namespace for Swift types. This PR standardizes on how
the metadata function is declared and called to fix the issue.
Fixes#80538.
rdar://148597079
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
The Error enum synthesized declarations, e.g. the struct and its static accessors, should generally appear to be identical to the underlying Clang definitions. There are some specific use cases where the synthesized declarations are necessary though.
I've added an option for USR generation to override the Clang node and emit the USR of the synthesized Swift declaration. This is used by SwiftDocSupport so that the USRs of the synthesized declarations are emitted.
Fixes 79912
These types are OK to by copied using memcpy. Previously, the generated
code assumed these types are exported swift types with all the value witness
functions.
rdar://111812577
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