1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
# Swift and C++ interop: Guide for Swift contributors
This document describes how to contribute changes to Swift
and C++ interoperability support in the Swift compiler.
The recommended way to contribute touches on topics
like source stability of C++ interop, making breaking
changes, and compatibility testing.
Here's a short summary of how you should contribute
to Swift and C++ interop:
- Treat every change as potentially source breaking, unless proven otherwise.
- Guard any potentially source breaking change with appropriate interop compat version checks.
- Explicitly specify the interop compat version in your test when adding breaking changes.
- Ensure that your GitHub PR is approved by one of the code owners before merging.
## Changing Swift and C++ interop
The initial support for Swift and C++ interop in Swift 5.9
is considered to be source stable, as in a future compiler
like Swift 5.10
must build any Swift code that uses C++ interop
and was previously built with Swift 5.9 compiler without
forcing the user to make **any** changes to their code.
Because of that promise that we're making to our users,
we need to be very diligent when it comes to making
changes to how Swift and C++ interop work, as they could
potentially violate this promise. Thus it's recommended
that you treat every
change as source breaking, unless proven otherwise.
### What is C++ Interop Compat Version
C++ interop compat version is the Swift version
value given to the `-cxx-interoperability-mode=` Swift
command line option.
It supports values like:
- `default`. Corresponds to the currently used Swift language version.
For instance, by default for Swift 5 compiler the C++ interop compat version
will be 5 when `-cxx-interoperability-mode=default` is passed. However,
if you pass `-cxx-interoperability-mode=default` and `-swift-version 6`,
then the C++ interop compat version becomes 6.
- `swift-X.Y`. A specific version like Swift 5.9.
- `upcoming-swift`. Corresponds to the C++ interop compat version that
represents the development *unreleased* version of Swift and C++ interoperability.
All new source breaking changes must be guarded by this version first
before they migrate to a specific *released* version of Swift and C++ interoperability.
### Guarding Source Breaking Changes in Compiler Implementation
Any source breaking change must be guarded with an appropriate
interop compat version check. Swift's `LangOptions` have
a `cxxInteropCompatVersion` member that is the interop compat version.
You can use the `isCxxInteropCompatVersionAtLeast` check to validate that
you're building for the upcoming version of C++ and Swift interop.
For example, in the clang importer, you can call this check method on
the `Impl`:
```
// Inside of Clang Importer (Impl is `ClangImporter::Impl`)
if (Impl.isCxxInteropCompatVersionAtLeast(version::getUpcomingCxxInteropCompatVersion())) {
// ... breaking change ...
}
```
Elsewhere, this method can be called on the `LangOptions` themselves:
```
if (SwiftContext.LangOpts.isCxxInteropCompatVersionAtLeast(version::getUpcomingCxxInteropCompatVersion())) {
// ... breaking change ...
}
```
### Testing the change
Please add new tests under `test/Interop/Cxx`, or
modify existing tests there.
Any tests for source breaking changes
should invoke the Swift compiler with
the `-cxx-interoperability-mode=upcoming-swift`
option.
## Submitting the Change as PR on GitHub
GitHub PR checklist for C++ interop related changes:
- Please tag your PR with 'C++ Interop' tag.
- Code owners should be added for review automatically.
- Please ensure that one of the current code owners reviews and approves the PR before merging.
## Releasing a new Swift and C++ Interop Compat Version
You need to update all Swift
sources to migrate these checks `isCxxInteropCompatVersionAtLeast(version::getUpcomingCxxInteropCompatVersion())`
to the concrete version you're now releasing, for instance `isCxxInteropCompatVersionAtLeast(5, 10)`.
There are more things we'll need to do but we haven't released a new interop compat version yet,
so this document will be updated once we do so.
|