Skip to content

Commit d7b62b3

Browse files
committed
[cxx-interop] add 'upcoming-swift' compat version
This version will be used to gate new source breaking changes for C++ interoperability
1 parent 5abb580 commit d7b62b3

File tree

6 files changed

+59
-10
lines changed

6 files changed

+59
-10
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ namespace swift {
310310
/// disabled because it is not complete.
311311
bool EnableCXXInterop = false;
312312

313+
/// The C++ interoperability source compatibility version. Defaults
314+
/// to the Swift language version.
315+
version::Version cxxInteropCompatVersion;
316+
313317
bool CForeignReferenceTypes = false;
314318

315319
/// Imports getters and setters as computed properties.
@@ -655,6 +659,13 @@ namespace swift {
655659
return EffectiveLanguageVersion.isVersionAtLeast(major, minor);
656660
}
657661

662+
/// Whether the C++ interoperability compatibility version is at least
663+
/// 'major'.
664+
bool isCxxInteropCompatVersionAtLeast(unsigned major,
665+
unsigned minor = 0) const {
666+
return cxxInteropCompatVersion.isVersionAtLeast(major, minor);
667+
}
668+
658669
/// Determine whether the given feature is enabled.
659670
bool hasFeature(Feature feature) const;
660671

include/swift/Basic/Version.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ StringRef getCurrentCompilerTag();
175175
/// depending on the vendor.
176176
StringRef getCurrentCompilerSerializationTag();
177177

178+
/// Retrieves the value of the upcoming C++ interoperability compatibility
179+
/// version that's going to be presented as some new concrete version to the
180+
/// users.
181+
unsigned getUpcomingCxxInteropCompatVersion();
182+
178183
} // end namespace version
179184
} // end namespace swift
180185

lib/Basic/Version.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,5 +306,9 @@ StringRef getCurrentCompilerSerializationTag() {
306306
#endif
307307
}
308308

309+
unsigned getUpcomingCxxInteropCompatVersion() {
310+
return SWIFT_VERSION_MAJOR + 1;
311+
}
312+
309313
} // end namespace version
310314
} // end namespace swift

lib/ClangImporter/ImporterImpl.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,17 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
589589
return Instance.get();
590590
}
591591

592+
/// Whether the C++ interoperability compatibility version is at least
593+
/// 'major'.
594+
///
595+
/// Use the
596+
/// `isCxxInteropCompatVersionAtLeast(version::getUpcomingCxxInteropCompatVersion())`
597+
/// check when making a source breaking C++ interop change.
598+
bool isCxxInteropCompatVersionAtLeast(unsigned major,
599+
unsigned minor = 0) const {
600+
return SwiftContext.LangOpts.isCxxInteropCompatVersionAtLeast(major, minor);
601+
}
602+
592603
private:
593604
/// The Importer may be configured to load modules of a different OS Version
594605
/// than the underlying Swift compilation. This is the `TargetOptions`

lib/Frontend/CompilerInvocation.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -486,15 +486,20 @@ enum class CxxCompatMode {
486486
off
487487
};
488488

489-
static CxxCompatMode validateCxxInteropCompatibilityMode(StringRef mode) {
489+
static std::pair<CxxCompatMode, version::Version>
490+
validateCxxInteropCompatibilityMode(StringRef mode) {
490491
if (mode == "off")
491-
return CxxCompatMode::off;
492+
return {CxxCompatMode::off, {}};
492493
if (mode == "default")
493-
return CxxCompatMode::enabled;
494-
// FIXME: Drop swift-5.9.
494+
return {CxxCompatMode::enabled, {}};
495+
if (mode == "upcoming-swift")
496+
return {CxxCompatMode::enabled,
497+
version::Version({version::getUpcomingCxxInteropCompatVersion()})};
498+
// Swift-5.9 corresponds to the Swift 5 language mode when
499+
// Swift 5 is the default language version.
495500
if (mode == "swift-5.9")
496-
return CxxCompatMode::enabled;
497-
return CxxCompatMode::invalid;
501+
return {CxxCompatMode::enabled, version::Version({5})};
502+
return {CxxCompatMode::invalid, {}};
498503
}
499504

500505
static void diagnoseCxxInteropCompatMode(Arg *verArg, ArgList &Args,
@@ -1066,16 +1071,29 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
10661071
}
10671072

10681073
auto interopCompatMode = validateCxxInteropCompatibilityMode(A->getValue());
1069-
Opts.EnableCXXInterop |= (interopCompatMode == CxxCompatMode::enabled);
1074+
Opts.EnableCXXInterop |=
1075+
(interopCompatMode.first == CxxCompatMode::enabled);
1076+
if (Opts.EnableCXXInterop) {
1077+
Opts.cxxInteropCompatVersion = interopCompatMode.second;
1078+
// The default is tied to the current language version.
1079+
if (Opts.cxxInteropCompatVersion.empty())
1080+
Opts.cxxInteropCompatVersion =
1081+
Opts.EffectiveLanguageVersion.asMajorVersion();
1082+
}
10701083

1071-
if (interopCompatMode == CxxCompatMode::invalid)
1084+
if (interopCompatMode.first == CxxCompatMode::invalid)
10721085
diagnoseCxxInteropCompatMode(A, Args, Diags);
10731086
}
1074-
1087+
10751088
if (Args.hasArg(OPT_enable_experimental_cxx_interop)) {
10761089
Diags.diagnose(SourceLoc(), diag::enable_interop_flag_deprecated);
10771090
Diags.diagnose(SourceLoc(), diag::swift_will_maintain_compat);
10781091
Opts.EnableCXXInterop |= true;
1092+
// Using the deprecated option only forces the 'swift-5.9' compat
1093+
// mode.
1094+
if (Opts.cxxInteropCompatVersion.empty())
1095+
Opts.cxxInteropCompatVersion =
1096+
validateCxxInteropCompatibilityMode("swift-5.9").second;
10791097
}
10801098

10811099
Opts.EnableObjCInterop =

test/Interop/Cxx/driver/invalid-interop-compat-mode.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// RUN: split-file %s %t
33
// RUN: not %target-swift-frontend -typecheck -I %t/Inputs %t/test.swift -cxx-interoperability-mode=swift-5.8 2>&1 | %FileCheck %s
44

5-
// Note: swift-5.9 is still supported, but will be removed.
65
// RUN: %target-swift-frontend -typecheck -I %t/Inputs %t/test.swift -cxx-interoperability-mode=swift-5.9
6+
// RUN: %target-swift-frontend -typecheck -I %t/Inputs %t/test.swift -cxx-interoperability-mode=upcoming-swift
77

88
//--- Inputs/module.modulemap
99
module Test {

0 commit comments

Comments
 (0)