Skip to content

[interop] support 'default' mode for '-cxx-interoperability-mode' option #64924

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

Merged
merged 1 commit into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/CppInteroperability/GettingStartedWithC++Interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module CxxTest {
Add the C++ module to the include path and enable C++ interop:
- Navigate to your project directory
- In `Project` navigate to `Build Settings` -> `Swift Compiler`
- Under `Custom Flags` -> `Other Swift Flags` add `-cxx-interoperability-mode=swift-5.9`
- Under `Custom Flags` -> `Other Swift Flags` add `-cxx-interoperability-mode=default`
- Under `Search Paths` -> `Import Paths` add your search path to the C++ module (i.e, `./ProjectName/CxxTest`).

- This should now allow your to import your C++ Module into any `.swift` file.
Expand Down Expand Up @@ -81,7 +81,7 @@ After creating your Swift package project, follow the steps [Creating a Module t
- Swift code will be in `Sources/CxxInterop` called `main.swift`
- C++ source code follows the example shown in [Creating a Module to contain your C++ source code](#creating-a-module-to-contain-your-c-source-code)
- Under targets, add the name of your C++ module and the directory containing the Swift code as a target.
- In the target defining your Swift target, add a`dependencies` to the C++ Module, the `path`, `source`, and `swiftSettings` with `unsafeFlags` with the source to the C++ Module, and enable `-cxx-interoperability-mode=swift-5.9`
- In the target defining your Swift target, add a`dependencies` to the C++ Module, the `path`, `source`, and `swiftSettings` with `unsafeFlags` with the source to the C++ Module, and enable `-cxx-interoperability-mode=default`

```
//In Package Manifest
Expand Down Expand Up @@ -111,7 +111,7 @@ let package = Package(
sources: [ "main.swift" ],
swiftSettings: [.unsafeFlags([
"-I", "Sources/CxxTest",
"-cxx-interoperability-mode=swift-5.9",
"-cxx-interoperability-mode=default",
])]
),
]
Expand Down Expand Up @@ -144,7 +144,7 @@ After creating your project follow the steps [Creating a Module to contain your
- Create a `CMakeLists.txt` file and configure for your project
- In`add_library` invoke `cxx-support` with the path to the C++ implementation file
- Add the `target_include_directories` with `cxx-support` and path to the C++ Module `${CMAKE_SOURCE_DIR}/Sources/CxxTest`
- Add the `add_executable` to the specific files/directory you would like to generate source, with`SHELL:-cxx-interoperability-mode=swift-5.9`.
- Add the `add_executable` to the specific files/directory you would like to generate source, with`SHELL:-cxx-interoperability-mode=default`.
- In the example below we will be following the file structure used in [Creating a Swift Package](#Creating-a-Swift-Package)

```
Expand All @@ -167,7 +167,7 @@ target_include_directories(cxx-support PUBLIC

add_executable(CxxInterop ./Sources/CxxInterop/main.swift)
target_compile_options(CxxInterop PRIVATE
"SHELL:-cxx-interoperability-mode=swift-5.9"
"SHELL:-cxx-interoperability-mode=default"
target_link_libraries(CxxInterop PRIVATE cxx-support)

```
Expand Down
7 changes: 3 additions & 4 deletions include/swift/AST/DiagnosticsFrontend.def
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,9 @@ WARNING(compiler_plugin_not_loaded,none,
ERROR(dont_enable_interop_and_compat,none,
"do not pass both -enable-experimental-cxx-interop and "
"-cxx-interoperability-mode. Remove -enable-experimental-cxx-interop.", ())

ERROR(invalid_interop_compat_mode,none,
"invalid option passed to -cxx-interoperability-mode. Please select either "
"'off' or 'swift-5.9'.", ())

NOTE(valid_cxx_interop_modes,none,
"valid arguments to '-cxx-interoperability-mode=' are %0", (StringRef))
Copy link
Contributor

Choose a reason for hiding this comment

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

This is nice :)

NOTE(swift_will_maintain_compat,none,
"Swift will maintain source compatibility for imported APIs based on the "
"selected compatibility mode, so updating the Swift compiler will not "
Expand Down
21 changes: 17 additions & 4 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,11 +438,26 @@ enum class CxxCompatMode {
static CxxCompatMode validateCxxInteropCompatibilityMode(StringRef mode) {
if (mode == "off")
return CxxCompatMode::off;
if (mode == "default")
return CxxCompatMode::enabled;
// FIXME: Drop swift-5.9.
if (mode == "swift-5.9")
return CxxCompatMode::enabled;
return CxxCompatMode::invalid;
}

static void diagnoseCxxInteropCompatMode(Arg *verArg, ArgList &Args,
DiagnosticEngine &diags) {
// General invalid argument error
diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
verArg->getAsString(Args), verArg->getValue());

// Note valid C++ interoperability modes.
auto validVers = {llvm::StringRef("off"), llvm::StringRef("default")};
auto versStr = "'" + llvm::join(validVers, "', '") + "'";
diags.diagnose(SourceLoc(), diag::valid_cxx_interop_modes, versStr);
}

static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
DiagnosticEngine &Diags,
const FrontendOptions &FrontendOpts) {
Expand Down Expand Up @@ -940,10 +955,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
auto interopCompatMode = validateCxxInteropCompatibilityMode(A->getValue());
Opts.EnableCXXInterop |= (interopCompatMode == CxxCompatMode::enabled);

if (interopCompatMode == CxxCompatMode::invalid) {
Diags.diagnose(SourceLoc(), diag::invalid_interop_compat_mode);
Diags.diagnose(SourceLoc(), diag::swift_will_maintain_compat);
}
if (interopCompatMode == CxxCompatMode::invalid)
diagnoseCxxInteropCompatMode(A, Args, Diags);
}

if (Args.hasArg(OPT_enable_experimental_cxx_interop)) {
Expand Down
2 changes: 1 addition & 1 deletion test/Interop/Cxx/driver/enable-interop-flag-depr.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: rm -rf %t
// RUN: split-file %s %t
// RUN: not %target-swift-frontend -typecheck -I %t/Inputs %t/test.swift -enable-experimental-cxx-interop -cxx-interoperability-mode=swift-5.9 2>&1 | %FileCheck %s
// RUN: not %target-swift-frontend -typecheck -I %t/Inputs %t/test.swift -enable-experimental-cxx-interop -cxx-interoperability-mode=default 2>&1 | %FileCheck %s

//--- Inputs/module.modulemap
module Test {
Expand Down
7 changes: 5 additions & 2 deletions test/Interop/Cxx/driver/invalid-interop-compat-mode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// RUN: split-file %s %t
// RUN: not %target-swift-frontend -typecheck -I %t/Inputs %t/test.swift -cxx-interoperability-mode=swift-5.8 2>&1 | %FileCheck %s

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

//--- Inputs/module.modulemap
module Test {
header "test.h"
Expand All @@ -14,5 +17,5 @@ module Test {

import Test

// CHECK: error: invalid option passed to -cxx-interoperability-mode. Please select either 'off' or 'swift-5.9'.
// CHECK: note: Swift will maintain source compatibility for imported APIs based on the selected compatibility mode, so updating the Swift compiler will not change how APIs are imported.
// CHECK: error: invalid value 'swift-5.8' in '-cxx-interoperability-mode=swift-5.8'
// CHECK: note: valid arguments to '-cxx-interoperability-mode=' are 'off', 'default'
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// RUN: %FileCheck %s < %t/uses-structs.h
// RUN: %check-interop-cxx-header-in-clang(-I %t %t/uses-structs.h)

// RUN: %target-swift-frontend %s -typecheck -module-name UsesStructs -I %t -cxx-interoperability-mode=swift-5.9 -emit-clang-header-path %t/uses-structs-default.h -clang-header-expose-module Structs=structs.h
// RUN: %target-swift-frontend %s -typecheck -module-name UsesStructs -I %t -cxx-interoperability-mode=default -emit-clang-header-path %t/uses-structs-default.h -clang-header-expose-module Structs=structs.h
// RUN: %check-interop-cxx-header-in-clang(-I %t %t/uses-structs-default.h)

import Structs
Expand Down
2 changes: 1 addition & 1 deletion test/SourceKit/InterfaceGen/gen_clang_cxx_module.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// RUN: split-file %s %t

// RUN: %sourcekitd-test -req=interface-gen -module CxxModule -- -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -I %t/Inputs -target %target-triple %clang-importer-sdk-nosource | %FileCheck %s
// RUN: %sourcekitd-test -req=interface-gen -module CxxModule -- -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -cxx-interoperability-mode=swift-5.9 -I %t/Inputs -target %target-triple %clang-importer-sdk-nosource | %FileCheck %s
// RUN: %sourcekitd-test -req=interface-gen -module CxxModule -- -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -cxx-interoperability-mode=default -I %t/Inputs -target %target-triple %clang-importer-sdk-nosource | %FileCheck %s


// RUN: not %sourcekitd-test -req=interface-gen -module CxxModule -- -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -Xcc -DERROR -I %t/Inputs -target %target-triple %clang-importer-sdk-nosource 2>&1 | %FileCheck --check-prefix=NOLOAD %s
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %sourcekitd-test -req=interface-gen -module CxxStdlib -- -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -cxx-interoperability-mode=swift-5.9 -target %target-triple -sdk %sdk | %FileCheck %s
// RUN: %sourcekitd-test -req=interface-gen -module CxxStdlib -- -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -cxx-interoperability-mode=default -target %target-triple -sdk %sdk | %FileCheck %s

// REQUIRES: OS=macosx

Expand Down
6 changes: 3 additions & 3 deletions test/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -744,8 +744,8 @@ elif swift_test_mode == 'with_cxx_interop':
config.available_features.add("nonexecutable_test")
config.available_features.add("executable_test")
config.available_features.add("with_cxx_interop")
config.swift_frontend_test_options += ' -cxx-interoperability-mode=swift-5.9'
config.swift_driver_test_options += ' -cxx-interoperability-mode=swift-5.9'
config.swift_frontend_test_options += ' -cxx-interoperability-mode=default'
config.swift_driver_test_options += ' -cxx-interoperability-mode=default'
else:
lit_config.fatal("Unknown test mode %r" % swift_test_mode)

Expand Down Expand Up @@ -2400,7 +2400,7 @@ config.substitutions.insert(0, ('%check-cxx-header-in-clang',
config.substitutions.append(('%env-', config.target_env_prefix))

config.substitutions.append(('%target-clangxx', '%s -std=c++11' % config.target_clang))
config.substitutions.append(('%target-swiftxx-frontend', '%s -cxx-interoperability-mode=swift-5.9' % config.target_swift_frontend))
config.substitutions.append(('%target-swiftxx-frontend', '%s -cxx-interoperability-mode=default' % config.target_swift_frontend))

config.substitutions.append(('%target-runtime', config.target_runtime))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ void SwiftLangSupport::editorOpenInterface(EditorConsumer &Consumer,
}
if (retryWithCxxEnabled) {
std::vector<const char *> AdjustedArgs(Args.begin(), Args.end());
AdjustedArgs.push_back("-cxx-interoperability-mode=swift-5.9");
AdjustedArgs.push_back("-cxx-interoperability-mode=default");
return editorOpenInterface(Consumer, Name, ModuleName, Group, AdjustedArgs,
SynthesizedExtensions, InterestedUSR);
}
Expand Down