mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Hard-code the 'Darwin' module as having been built without C++ interop
Textual interfaces for 'Darwin' built with recent compilers specify that it is built witout C++ interop enabled. However, to ensure compatibility with versions of the 'Darwin' module built with older compilers, we hard-code this fact. This is required to break the module cycle that occurs when building the 'Darwin' module with C++ interop enabled, where the underlying 'Darwin' clang module depends on C++ standard library for which the compiler brings in the 'CxxStdlib' Swift overlay, which depends on 'Darwin'.
This commit is contained in:
@@ -45,6 +45,7 @@ namespace swift {
|
||||
|
||||
struct DiagnosticBehavior;
|
||||
class DiagnosticEngine;
|
||||
class FrontendOptions;
|
||||
|
||||
/// Kind of implicit platform conditions.
|
||||
enum class PlatformConditionKind {
|
||||
@@ -339,7 +340,8 @@ namespace swift {
|
||||
std::optional<version::Version> FormalCxxInteropMode;
|
||||
|
||||
void setCxxInteropFromArgs(llvm::opt::ArgList &Args,
|
||||
swift::DiagnosticEngine &Diags);
|
||||
swift::DiagnosticEngine &Diags,
|
||||
const FrontendOptions &FrontendOpts);
|
||||
|
||||
/// The C++ standard library used for the current build. This can differ
|
||||
/// from the default C++ stdlib on a particular platform when `-Xcc
|
||||
|
||||
@@ -1479,7 +1479,13 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule(
|
||||
|
||||
// If the textual interface was built without C++ interop, do not query
|
||||
// the C++ Standard Library Swift overlay for its compilation.
|
||||
if (llvm::find(commandLine, "-formal-cxx-interoperability-mode=off") ==
|
||||
//
|
||||
// FIXME: We always declare the 'Darwin' module as formally having been built
|
||||
// without C++Interop, for compatibility with prior versions. Once we are certain
|
||||
// that we are only building against modules built with support of
|
||||
// '-formal-cxx-interoperability-mode', this hard-coded check should be removed.
|
||||
if (moduleID.ModuleName != "Darwin" &&
|
||||
llvm::find(commandLine, "-formal-cxx-interoperability-mode=off") ==
|
||||
commandLine.end()) {
|
||||
for (const auto &clangDepName : allClangDependencies) {
|
||||
// If this Clang module is a part of the C++ stdlib, and we haven't
|
||||
|
||||
@@ -214,7 +214,8 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args,
|
||||
Options.AvailabilityIsBlockList = A->getOption().matches(OPT_block_availability_platforms);
|
||||
}
|
||||
|
||||
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags);
|
||||
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags,
|
||||
Invocation.getFrontendOptions());
|
||||
|
||||
std::string InstanceSetupError;
|
||||
if (CI.setup(Invocation, InstanceSetupError)) {
|
||||
|
||||
@@ -133,7 +133,8 @@ int swift_synthesize_interface_main(ArrayRef<const char *> Args,
|
||||
Invocation.setImportSearchPaths(ImportSearchPaths);
|
||||
|
||||
Invocation.getLangOptions().EnableObjCInterop = Target.isOSDarwin();
|
||||
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags);
|
||||
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags,
|
||||
Invocation.getFrontendOptions());
|
||||
|
||||
std::string ModuleCachePath = "";
|
||||
if (auto *A = ParsedArgs.getLastArg(OPT_module_cache_path)) {
|
||||
|
||||
@@ -680,7 +680,8 @@ static void diagnoseCxxInteropCompatMode(Arg *verArg, ArgList &Args,
|
||||
}
|
||||
|
||||
void LangOptions::setCxxInteropFromArgs(ArgList &Args,
|
||||
swift::DiagnosticEngine &Diags) {
|
||||
swift::DiagnosticEngine &Diags,
|
||||
const FrontendOptions &FrontendOpts) {
|
||||
if (Arg *A = Args.getLastArg(options::OPT_cxx_interoperability_mode)) {
|
||||
if (Args.hasArg(options::OPT_enable_experimental_cxx_interop)) {
|
||||
Diags.diagnose(SourceLoc(), diag::dont_enable_interop_and_compat);
|
||||
@@ -735,7 +736,12 @@ void LangOptions::setCxxInteropFromArgs(ArgList &Args,
|
||||
// version, and is either 4, 5, 6, or 7 (even though only 5.9 and 6.* make
|
||||
// any sense). For now, we don't actually care about the version, so we'll
|
||||
// just use version 6 (i.e., 'swift-6') to mean that C++ interop mode is on.
|
||||
if (EnableCXXInterop)
|
||||
//
|
||||
// FIXME: We always declare the 'Darwin' module as formally having been built
|
||||
// without C++Interop, for compatibility with prior versions. Once we are certain
|
||||
// that we are only building against modules built with support of
|
||||
// '-formal-cxx-interoperability-mode', this hard-coded check should be removed.
|
||||
if (EnableCXXInterop && (FrontendOpts.ModuleName.compare("Darwin") != 0))
|
||||
FormalCxxInteropMode = {6};
|
||||
else
|
||||
FormalCxxInteropMode = std::nullopt;
|
||||
@@ -1558,7 +1564,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
if (const Arg *A = Args.getLastArg(OPT_clang_target_variant))
|
||||
Opts.ClangTargetVariant = llvm::Triple(A->getValue());
|
||||
|
||||
Opts.setCxxInteropFromArgs(Args, Diags);
|
||||
Opts.setCxxInteropFromArgs(Args, Diags, FrontendOpts);
|
||||
if (!Args.hasArg(options::OPT_formal_cxx_interoperability_mode))
|
||||
ModuleInterfaceOpts.PublicFlags.IgnorableFlags +=
|
||||
" " + printFormalCxxInteropVersion(Opts);
|
||||
|
||||
@@ -6,9 +6,14 @@
|
||||
// RUN: %target-swift-frontend -typecheck %t/clientWithInteropDep.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -module-cache-path %t/module-cache &> %t/interop_dep.txt
|
||||
// RUN: cat %t/interop_dep.txt | %FileCheck %s -check-prefix=ENABLE-CHECK
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck -o %t/deps_no_interop_dep.json %t/clientNoInteropDep.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -module-cache-path %t/module-cache &> %t/no_interop_dep.txt
|
||||
// RUN: %empty-directory(%t/module-cache)
|
||||
// RUN: %target-swift-frontend -typecheck %t/clientNoInteropDep.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -module-cache-path %t/module-cache &> %t/no_interop_dep.txt
|
||||
// RUN: cat %t/no_interop_dep.txt | %FileCheck %s -check-prefix=DISABLE-CHECK
|
||||
|
||||
// RUN: %empty-directory(%t/module-cache)
|
||||
// RUN: %target-swift-frontend -typecheck %t/clientDarwin.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -module-cache-path %t/module-cache &> %t/darwin_dep.txt
|
||||
// RUN: cat %t/darwin_dep.txt | %FileCheck %s -check-prefix=DISABLE-CHECK
|
||||
|
||||
// ENABLE-CHECK: remark: loaded module 'CxxStdlib' (overlay for a clang dependency)
|
||||
// DISABLE-CHECK-NOT: remark: loaded module 'CxxStdlib' (overlay for a clang dependency)
|
||||
|
||||
@@ -43,9 +48,19 @@ public struct Foo1 {}
|
||||
import Bar
|
||||
public struct Foo2 {}
|
||||
|
||||
//--- deps/Darwin.swiftinterface
|
||||
// swift-interface-format-version: 1.0
|
||||
// swift-module-flags: -module-name Darwin -enable-library-evolution
|
||||
// swift-module-flags-ignorable: -Rmodule-loading
|
||||
import Bar
|
||||
public struct Foo2 {}
|
||||
|
||||
//--- clientWithInteropDep.swift
|
||||
import Foo
|
||||
|
||||
//--- clientNoInteropDep.swift
|
||||
import FooNoInterop
|
||||
|
||||
//--- clientDarwin.swift
|
||||
import Darwin
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
// RUN: %target-swift-frontend -scan-dependencies -o %t/deps_no_interop_dep.json %t/clientNoInteropDep.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -verify
|
||||
// RUN: cat %t/deps_no_interop_dep.json | %FileCheck %s -check-prefix=DISABLE-CHECK
|
||||
|
||||
// RUN: %target-swift-frontend -scan-dependencies -o %t/deps_darwin_dep.json %t/clientDarwin.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -verify
|
||||
// RUN: cat %t/deps_darwin_dep.json | %FileCheck %s -check-prefix=DARWIN-CHECK
|
||||
|
||||
//--- deps/bar.h
|
||||
void bar(void);
|
||||
|
||||
@@ -30,12 +33,21 @@ public struct Foo1 {}
|
||||
import std_Bar
|
||||
public struct Foo2 {}
|
||||
|
||||
//--- deps/Darwin.swiftinterface
|
||||
// swift-interface-format-version: 1.0
|
||||
// swift-module-flags: -module-name Darwin -enable-library-evolution
|
||||
import std_Bar
|
||||
public struct Foo3 {}
|
||||
|
||||
//--- clientWithInteropDep.swift
|
||||
import Foo
|
||||
|
||||
//--- clientNoInteropDep.swift
|
||||
import FooNoInterop
|
||||
|
||||
//--- clientDarwin.swift
|
||||
import Darwin
|
||||
|
||||
// Ensure that when the 'Foo' dependency was built with C++ interop enabled,
|
||||
// it gets the C++ standard library overlay for its 'std_*' dependency
|
||||
//
|
||||
@@ -75,4 +87,21 @@ import FooNoInterop
|
||||
// DISABLE-CHECK: }
|
||||
// DISABLE-CHECK: ],
|
||||
|
||||
// Ensure that the the 'Darwin' dependency does not get the C++ standard library overlay for its 'std_*' dependencies
|
||||
//
|
||||
// 'Darwin' as it appears in direct deps
|
||||
// DARWIN-CHECK: "swift": "Darwin"
|
||||
// 'Darwin' as it appears in source-import deps
|
||||
// DARWIN-CHECK: "swift": "Darwin"
|
||||
// Actual dependency info node
|
||||
// DARWIN-CHECK: "swift": "Darwin"
|
||||
// DARWIN-CHECK: "directDependencies": [
|
||||
// DARWIN-CHECK: {
|
||||
// DARWIN-CHECK: "swift": "SwiftOnoneSupport"
|
||||
// DARWIN-CHECK: },
|
||||
// DARWIN-CHECK: {
|
||||
// DARWIN-CHECK: "clang": "std_Bar"
|
||||
// DARWIN-CHECK: }
|
||||
// DARWIN-CHECK: ],
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user