Skip to content

Commit 5b501ad

Browse files
committed
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'.
1 parent 5577df7 commit 5b501ad

File tree

7 files changed

+68
-8
lines changed

7 files changed

+68
-8
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace swift {
4545

4646
struct DiagnosticBehavior;
4747
class DiagnosticEngine;
48+
class FrontendOptions;
4849

4950
/// Kind of implicit platform conditions.
5051
enum class PlatformConditionKind {
@@ -339,7 +340,8 @@ namespace swift {
339340
std::optional<version::Version> FormalCxxInteropMode;
340341

341342
void setCxxInteropFromArgs(llvm::opt::ArgList &Args,
342-
swift::DiagnosticEngine &Diags);
343+
swift::DiagnosticEngine &Diags,
344+
const FrontendOptions &FrontendOpts);
343345

344346
/// The C++ standard library used for the current build. This can differ
345347
/// from the default C++ stdlib on a particular platform when `-Xcc

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1478,7 +1478,13 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule(
14781478

14791479
// If the textual interface was built without C++ interop, do not query
14801480
// the C++ Standard Library Swift overlay for its compilation.
1481-
if (llvm::find(commandLine, "-formal-cxx-interoperability-mode=off") ==
1481+
//
1482+
// FIXME: We always declare the 'Darwin' module as formally having been built
1483+
// without C++Interop, for compatibility with prior versions. Once we are certain
1484+
// that we are only building against modules built with support of
1485+
// '-formal-cxx-interoperability-mode', this hard-coded check should be removed.
1486+
if (moduleID.ModuleName != "Darwin" &&
1487+
llvm::find(commandLine, "-formal-cxx-interoperability-mode=off") ==
14821488
commandLine.end()) {
14831489
for (const auto &clangDepName : allClangDependencies) {
14841490
// If this Clang module is a part of the C++ stdlib, and we haven't

lib/DriverTool/swift_symbolgraph_extract_main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args,
214214
Options.AvailabilityIsBlockList = A->getOption().matches(OPT_block_availability_platforms);
215215
}
216216

217-
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags);
217+
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags,
218+
Invocation.getFrontendOptions());
218219

219220
std::string InstanceSetupError;
220221
if (CI.setup(Invocation, InstanceSetupError)) {

lib/DriverTool/swift_synthesize_interface_main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ int swift_synthesize_interface_main(ArrayRef<const char *> Args,
133133
Invocation.setImportSearchPaths(ImportSearchPaths);
134134

135135
Invocation.getLangOptions().EnableObjCInterop = Target.isOSDarwin();
136-
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags);
136+
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags,
137+
Invocation.getFrontendOptions());
137138

138139
std::string ModuleCachePath = "";
139140
if (auto *A = ParsedArgs.getLastArg(OPT_module_cache_path)) {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,8 @@ static void diagnoseCxxInteropCompatMode(Arg *verArg, ArgList &Args,
682682
}
683683

684684
void LangOptions::setCxxInteropFromArgs(ArgList &Args,
685-
swift::DiagnosticEngine &Diags) {
685+
swift::DiagnosticEngine &Diags,
686+
const FrontendOptions &FrontendOpts) {
686687
if (Arg *A = Args.getLastArg(options::OPT_cxx_interoperability_mode)) {
687688
if (Args.hasArg(options::OPT_enable_experimental_cxx_interop)) {
688689
Diags.diagnose(SourceLoc(), diag::dont_enable_interop_and_compat);
@@ -737,7 +738,12 @@ void LangOptions::setCxxInteropFromArgs(ArgList &Args,
737738
// version, and is either 4, 5, 6, or 7 (even though only 5.9 and 6.* make
738739
// any sense). For now, we don't actually care about the version, so we'll
739740
// just use version 6 (i.e., 'swift-6') to mean that C++ interop mode is on.
740-
if (EnableCXXInterop)
741+
//
742+
// FIXME: We always declare the 'Darwin' module as formally having been built
743+
// without C++Interop, for compatibility with prior versions. Once we are certain
744+
// that we are only building against modules built with support of
745+
// '-formal-cxx-interoperability-mode', this hard-coded check should be removed.
746+
if (EnableCXXInterop && (FrontendOpts.ModuleName.compare("Darwin") != 0))
741747
FormalCxxInteropMode = {6};
742748
else
743749
FormalCxxInteropMode = std::nullopt;
@@ -1560,7 +1566,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
15601566
if (const Arg *A = Args.getLastArg(OPT_clang_target_variant))
15611567
Opts.ClangTargetVariant = llvm::Triple(A->getValue());
15621568

1563-
Opts.setCxxInteropFromArgs(Args, Diags);
1569+
Opts.setCxxInteropFromArgs(Args, Diags, FrontendOpts);
15641570
if (!Args.hasArg(options::OPT_formal_cxx_interoperability_mode))
15651571
ModuleInterfaceOpts.PublicFlags.IgnorableFlags +=
15661572
" " + printFormalCxxInteropVersion(Opts);

test/Interop/Cxx/modules/no-cxx-overlay-for-non-interop-interface.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
// 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
77
// RUN: cat %t/interop_dep.txt | %FileCheck %s -check-prefix=ENABLE-CHECK
88

9-
// 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
9+
// RUN: %empty-directory(%t/module-cache)
10+
// 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
1011
// RUN: cat %t/no_interop_dep.txt | %FileCheck %s -check-prefix=DISABLE-CHECK
1112

13+
// RUN: %empty-directory(%t/module-cache)
14+
// 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
15+
// RUN: cat %t/darwin_dep.txt | %FileCheck %s -check-prefix=DISABLE-CHECK
16+
1217
// ENABLE-CHECK: remark: loaded module 'CxxStdlib' (overlay for a clang dependency)
1318
// DISABLE-CHECK-NOT: remark: loaded module 'CxxStdlib' (overlay for a clang dependency)
1419

@@ -43,9 +48,19 @@ public struct Foo1 {}
4348
import Bar
4449
public struct Foo2 {}
4550

51+
//--- deps/Darwin.swiftinterface
52+
// swift-interface-format-version: 1.0
53+
// swift-module-flags: -module-name Darwin -enable-library-evolution
54+
// swift-module-flags-ignorable: -Rmodule-loading
55+
import Bar
56+
public struct Foo2 {}
57+
4658
//--- clientWithInteropDep.swift
4759
import Foo
4860

4961
//--- clientNoInteropDep.swift
5062
import FooNoInterop
5163

64+
//--- clientDarwin.swift
65+
import Darwin
66+

test/ScanDependencies/no-cxx-overlay-for-non-interop-interface.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
// 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
99
// RUN: cat %t/deps_no_interop_dep.json | %FileCheck %s -check-prefix=DISABLE-CHECK
1010

11+
// 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
12+
// RUN: cat %t/deps_darwin_dep.json | %FileCheck %s -check-prefix=DARWIN-CHECK
13+
1114
//--- deps/bar.h
1215
void bar(void);
1316

@@ -30,12 +33,21 @@ public struct Foo1 {}
3033
import std_Bar
3134
public struct Foo2 {}
3235

36+
//--- deps/Darwin.swiftinterface
37+
// swift-interface-format-version: 1.0
38+
// swift-module-flags: -module-name Darwin -enable-library-evolution
39+
import std_Bar
40+
public struct Foo3 {}
41+
3342
//--- clientWithInteropDep.swift
3443
import Foo
3544

3645
//--- clientNoInteropDep.swift
3746
import FooNoInterop
3847

48+
//--- clientDarwin.swift
49+
import Darwin
50+
3951
// Ensure that when the 'Foo' dependency was built with C++ interop enabled,
4052
// it gets the C++ standard library overlay for its 'std_*' dependency
4153
//
@@ -75,4 +87,21 @@ import FooNoInterop
7587
// DISABLE-CHECK: }
7688
// DISABLE-CHECK: ],
7789

90+
// Ensure that the the 'Darwin' dependency does not get the C++ standard library overlay for its 'std_*' dependencies
91+
//
92+
// 'Darwin' as it appears in direct deps
93+
// DARWIN-CHECK: "swift": "Darwin"
94+
// 'Darwin' as it appears in source-import deps
95+
// DARWIN-CHECK: "swift": "Darwin"
96+
// Actual dependency info node
97+
// DARWIN-CHECK: "swift": "Darwin"
98+
// DARWIN-CHECK: "directDependencies": [
99+
// DARWIN-CHECK: {
100+
// DARWIN-CHECK: "swift": "SwiftOnoneSupport"
101+
// DARWIN-CHECK: },
102+
// DARWIN-CHECK: {
103+
// DARWIN-CHECK: "clang": "std_Bar"
104+
// DARWIN-CHECK: }
105+
// DARWIN-CHECK: ],
106+
78107

0 commit comments

Comments
 (0)