-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[6.2] Accept @cdecl
global functions and enums, behind experimental feature flags
#82791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/6.2
Are you sure you want to change the base?
Conversation
This implements basic checks on the validity of the @cdecl attribute and ensures the parameters and result types are representable in C. Many more diagnostics will need to be updated to verify full representability in C.
Apply review comments from swiftlang#80744.
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.
In C mode we still print nullability attributes. Don't let clang warn on them and ignore the attribute if the C compiler doesn't know them.
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.
Begin accepting the attribute in the form of `@cdecl(cName)`, using an identifier instead of a string. For ease of landing this change we still accept the string form. We should stop accepting it before making this feature available in production.
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.
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.
Accept `@cdecl` enums without an explicit C name. The C name defaults to the Swift one. It is printed using the `SWIFT_ENUM` macro instead of `SWIFT_ENUM_NAMED`.
Add related end-to-end test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per discussion with @DougGregor , we've decided to cherry-pick the cdecl implementation to the release/6.2 branch.
@swift-ci Please test |
Linux failure is something I haven't seen before:
|
@swift-ci Please smoke test I missed a commit in the cherry-pick. The use of |
@swift-ci Please test |
Add support for the
@cdecl
attribute on global functions and enums. This is gated on the experimental featureCDecl
.Global functions marked
@cdecl
are type-checked to ensure the parameter and return types are compatible with the C language. The equivalent C functions are printed to the compatibility header in a new section for C clients. In this section we also print the required#include
when the signatures reference types imported from C.@cdecl
enums must declare an integer raw type representable in C. The equivalent C enums are printed to the compatibility header relying on macros to declare the raw type in a way that supports different C language variants.The existing
CImplementation
experimental feature is already compatible with the new attribute@cdecl
attribute. It allows to implement in Swift a C function declared in a C header by marking the implementation with@cdecl @implementation
.Note that using
@objc
on global functions is still not accepted by the parser.@objc
@cdecl
functions #80917, PrintAsClang: Print#include
to import headers used from@cdecl
functions #81481, Sema: Update more diagnostics for@cdecl
and representability in the C language #81519, PrintAsClang: Introduce@cdecl
enums #82039, Parser: Accept@cdecl
with an optional identifier for a custom C name #82194, AST: Misc improvements to@decl
enums: implicit names, code gen fix and more tests #82697, Parser: Reject the old string syntax for@cdecl
and allow the experimental feature in production #82789