-
Notifications
You must be signed in to change notification settings - Fork 10.5k
ClangImporter: enhance the importer to alias declarations #81840
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
Conversation
@swift-ci please smoke 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.
This is exciting, thanks!
@swift-ci please smoke 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.
Nice; this will be a huge quality of life improvement for Windows development.
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.
LGTM modulo Alastair's question
@swift-ci please smoke test Linux platform |
@swift-ci please test Windows platform |
@swift-ci please test Windows platform |
@swift-ci please smoke test |
@swift-ci please smoke test |
@swift-ci please smoke test |
Looking at
Looking at
With this change we would now synthesize the following: var CLOCK_MONOTONIC: CInt {
_CLOCK_MONOTONIC
} But due to the APINotes, we would import |
:-( It would be much easier if we could fix the compiler to tolerate that somehow, rather than having to change the API notes file. Would |
@swift-ci please smoke test Linux platform |
The APINotes have already been applied by clang before we import the nodes, right? It seems to me like we should be able to inspect the aliased clang decl and check for |
@swift-ci please smoke test |
@swift-ci please smoke test |
@swift-ci please test windows platform |
@swift-ci please smoke test macOS platform |
3 similar comments
@swift-ci please smoke test macOS platform |
@swift-ci please smoke test macOS platform |
@swift-ci please smoke test macOS platform |
When building on non-Darwin targets, we are not guaranteed that there is no ICU library on the system (Windows ships an ICU since Windows 1703 (RedStone 2), SDK 10.0.15063. This now is implicitly pulled in OneCore.lib which vends the memory API contract; Linux normally ships a copy of ICU; android ships a copy of ICU since Android 6.0 (API Level 23) but is not part of the supported APIs). The availability of ICU on the system and in Swift causes a conflict. As there is no stable ABI for ICU, this is a problem and can cause spurious failures. Such a failure has been observed on Windows when statically linking Foundation. Unfortunately, the symbol renaming support in ICU relies on the `U_ICU_ENTRY_POINT_RENAME` macro which is defined thusly: ``` #define U_DEF_ICU_ENTRY_POINT_RENAME(x, y, z) x ## y ## z #define U_DEF2_ICU_ENTRY_POINT_RENAME(x, y, z) U_DEF_ICU_ENTRY_POINT_RENAME(x, y, z) #define U_ICU_ENTRY_POINT_RENAME(name) U_DEF2_ICU_ENTRY_POINT_RENAME(name, ICU_VERSION_SUFFIX, U_LIB_SUFFIX_C_NAME) ``` This macro is too complex for the clang importer to import into Swift, making this not possible to use directly. Instead, we manually perform the expansion of the CPP macros, using the `swift_` prefix instead to isolate and namespace our implementation. Unfortunately, even the aliasing macro is too complex for the clang importer to import directly. Because changing all the call sites would not be tractable (nor maintainable), this will require an additional change (swiftlang/swift#81840) to support aliasing macros to be imported into Swift. Although this change currently only enables the symbol renaming on static builds, once everything is merged and tested, it should be safe to control this behaviour on all non-Darwin targets. The change to the static linking targets solves the immediate problem on Windows where the early swift-driver implicitly will pick up the system ICU and fault at runtime. Although in theory only the dynamically linked version should be susceptible to the interpositioning issue, if any of the system libraries causes ICU to be included (e.g. a linker script on Unix or an import library pulling in another version), we can also hit this issue in the statically linked scenario. When dynamically linking, on Windows at least, it would not be a problem if the symbol is bound properly at link time as the symbolic resolution involves two-level namespacing, which is not available on ELF hosts. On Darwin, we cannot perform the renaming as the library is vended by the system and this would constitute an ABI break.
When building on non-Darwin targets, we are not guaranteed that there is no ICU library on the system (Windows ships an ICU since Windows 1703 (RedStone 2), SDK 10.0.15063. This now is implicitly pulled in OneCore.lib which vends the memory API contract; Linux normally ships a copy of ICU; android ships a copy of ICU since Android 6.0 (API Level 23) but is not part of the supported APIs). The availability of ICU on the system and in Swift causes a conflict. As there is no stable ABI for ICU, this is a problem and can cause spurious failures. Such a failure has been observed on Windows when statically linking Foundation. Unfortunately, the symbol renaming support in ICU relies on the `U_ICU_ENTRY_POINT_RENAME` macro which is defined thusly: ``` #define U_DEF_ICU_ENTRY_POINT_RENAME(x, y, z) x ## y ## z #define U_DEF2_ICU_ENTRY_POINT_RENAME(x, y, z) U_DEF_ICU_ENTRY_POINT_RENAME(x, y, z) #define U_ICU_ENTRY_POINT_RENAME(name) U_DEF2_ICU_ENTRY_POINT_RENAME(name, ICU_VERSION_SUFFIX, U_LIB_SUFFIX_C_NAME) ``` This macro is too complex for the clang importer to import into Swift, making this not possible to use directly. Instead, we manually perform the expansion of the CPP macros, using the `swift_` prefix instead to isolate and namespace our implementation. Unfortunately, even the aliasing macro is too complex for the clang importer to import directly. Because changing all the call sites would not be tractable (nor maintainable), this will require an additional change (swiftlang/swift#81840) to support aliasing macros to be imported into Swift. Although in theory only the dynamically linked version should be susceptible to the interpositioning issue, if any of the system libraries causes ICU to be included (e.g. a linker script on Unix or an import library pulling in another version), we can also hit this issue in the statically linked scenario. When dynamically linking, on Windows at least, it would not be a problem if the symbol is bound properly at link time as the symbolic resolution involves two-level namespacing, which is not available on ELF hosts. On Darwin, we cannot perform the renaming as the library is vended by the system and this would constitute an ABI break.
@swift-ci please smoke test |
@swift-ci please smoke test |
Import simple CPP macro aliases as aliases in Swift. Extend the macro importer to import the following construct: ``` #define alias aliasee ``` as the following Swift construct: ``` @_transparent @inline(__always) var alias: type(of: aliasee) { aliasee } ``` This improves the QoI for Windows where there is a universal define (`UNICODE`) which normally is used for translating APIs between ANSI and Unicode variants, e.g.: ``` #if defined(UNICODE) #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif ``` Global variables which are non-const also have a setter synthesized: ``` @_transparent @inline(__always) var alias: type(of: aliasee) { get { return aliasee } set { aliasee = newValue } } ```
@swift-ci please smoke test |
@compnerd I noticed that the latest nightly toolchain seems to have introduced an issue with
|
This reverts commit 33a324e, reversing changes made to 0afeafa due to a regression: ``` $ printf "import var Darwin.stderr\n" | /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2025-06-09-a.xctoolchain/usr/bin/swiftc -typecheck - -sdk $(xcrun --show-sdk-path) <stdin>:1:12: error: ambiguous name 'stderr' in module 'Darwin' 1 | import var Darwin.stderr | `- error: ambiguous name 'stderr' in module 'Darwin' 2 | _stdio.stderr:2:12: note: found this candidate 1 | @available(macOS 10.9, iOS 7.0, watchOS 2.0, tvOS 9.0, visionOS 1.0, *) 2 | public var stderr: UnsafeMutablePointer<FILE> { get set } | `- note: found this candidate _stdio.stderr:1:12: note: found this candidate 1 | public var stderr: UnsafeMutablePointer<FILE> { get set } | `- note: found this candidate ``` # Conflicts: # test/ClangImporter/Inputs/custom-modules/module.modulemap
Import simple CPP macro aliases as aliases in Swift. Extend the macro importer to import the following construct:
as the following Swift construct:
This improves the QoI for Windows where there is a universal define (
UNICODE
) which normally is used for translating APIs between ANSI and Unicode variants, e.g.: