Skip to content

PrintAsClang: Introduce @cdecl enums #82039

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

Conversation

xymus
Copy link
Contributor

@xymus xymus commented Jun 5, 2025

Introduce @cdecl enums, enums declared in Swift and representable in C. These enums must have an integer raw type and can be referenced from @cdecl functions and @objc methods.

@cdecl enums are printed in the compatibility header using a macro that ensures compatibility with different C language modes. They can also be forward declared when referenced from the compatibility header of a client.

@cdecl and @objc enums mostly have the same restrictions on their declarations. There are differences on how they are printed in the compatibility header, each are in the corresponding language section and only @objc enums supports error domains.

This is guarded behind the CDecl feature flag.

@xymus
Copy link
Contributor Author

xymus commented Jun 5, 2025

@swift-ci Please smoke test

@xymus xymus force-pushed the cdecl-enum branch 3 times, most recently from a92e68a to 00890cb Compare June 6, 2025 23:32
@xymus
Copy link
Contributor Author

xymus commented Jun 6, 2025

@swift-ci Please smoke test

xymus added 3 commits June 9, 2025 11:54
@cdecl enums are Swift enums representable in C. These enums must have
an integer raw type. They can be referenced from @cdecl functions and
@objc methods. @objc enums are still rejected from @cdecl functions.
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.
@xymus
Copy link
Contributor Author

xymus commented Jun 9, 2025

@swift-ci Please smoke test

@xymus
Copy link
Contributor Author

xymus commented Jun 10, 2025

@swift-ci Please smoke test Linux

@xymus xymus marked this pull request as ready for review June 11, 2025 20:31
@xymus xymus requested review from beccadax and artemcm June 11, 2025 20:31
@@ -457,6 +457,14 @@ class ModuleWriter {
}
}

if (isa<EnumDecl>(D) && !D->hasClangNode() &&
outputLangMode != OutputLanguageMode::Cxx) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I follow from the code, could you explain why outputLangMode != OutputLanguageMode::Cxx?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants