Skip to content

Commit 26ff7fd

Browse files
committed
[cxx-interop] Do not emit C++ interop flag in textual interfaces
This makes sure that the compiler does not emit `-enable-experimental-cxx-interop`/`-cxx-interoperability-mode` flags in `.swiftinterface` files. Those flags were breaking explicit module builds. The module can still be rebuilt from its textual interface if C++ interop was enabled in the current compilation. rdar://140203932
1 parent c690fef commit 26ff7fd

File tree

5 files changed

+32
-11
lines changed

5 files changed

+32
-11
lines changed

include/swift/Option/Options.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -794,12 +794,12 @@ def enable_experimental_concise_pound_file : Flag<["-"],
794794

795795
def enable_experimental_cxx_interop :
796796
Flag<["-"], "enable-experimental-cxx-interop">,
797-
Flags<[NoDriverOption, FrontendOption, HelpHidden, ModuleInterfaceOption]>,
797+
Flags<[NoDriverOption, FrontendOption, HelpHidden]>,
798798
HelpText<"Enable experimental C++ interop code generation and config directives">;
799799

800800
def cxx_interoperability_mode :
801801
Joined<["-"], "cxx-interoperability-mode=">,
802-
Flags<[FrontendOption, ModuleInterfaceOption, SwiftSymbolGraphExtractOption,
802+
Flags<[FrontendOption, SwiftSymbolGraphExtractOption,
803803
SwiftSynthesizeInterfaceOption]>,
804804
HelpText<"Enables C++ interoperability; pass 'default' to enable or 'off' to disable">;
805805

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,10 +2016,7 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
20162016

20172017
// For now, we only inherit the C++ interoperability mode in
20182018
// Explicit Module Builds.
2019-
if (langOpts.EnableCXXInterop &&
2020-
(frontendOpts.DisableImplicitModules ||
2021-
LoaderOpts.requestedAction ==
2022-
FrontendOptions::ActionType::ScanDependencies)) {
2019+
if (langOpts.EnableCXXInterop) {
20232020
// Modelled after a reverse of validateCxxInteropCompatibilityMode
20242021
genericSubInvocation.getLangOptions().EnableCXXInterop = true;
20252022
genericSubInvocation.getLangOptions().cxxInteropCompatVersion =
@@ -2208,6 +2205,16 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
22082205
BuildArgs.push_back("-module-name");
22092206
BuildArgs.push_back(moduleName);
22102207

2208+
// FIXME: Hack for Darwin.swiftmodule, which cannot be rebuilt with C++
2209+
// interop enabled.
2210+
if (moduleName == "Darwin") {
2211+
subInvocation.getLangOptions().EnableCXXInterop = false;
2212+
subInvocation.getLangOptions().cxxInteropCompatVersion = {};
2213+
llvm::remove_if(BuildArgs, [](StringRef arg) -> bool {
2214+
return arg.starts_with("-cxx-interoperability-mode=");
2215+
});
2216+
}
2217+
22112218
// Calculate output path of the module.
22122219
llvm::SmallString<256> buffer;
22132220
StringRef CacheHash;

lib/Sema/TypeCheckAccess.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "swift/AST/Pattern.h"
2929
#include "swift/AST/TypeCheckRequests.h"
3030
#include "swift/Basic/Assertions.h"
31+
#include "clang/Basic/Module.h"
3132
#include "clang/AST/DeclCXX.h"
3233
#include "clang/AST/DeclObjC.h"
3334

@@ -1849,6 +1850,9 @@ bool isFragileClangNode(const ClangNode &node) {
18491850
auto *decl = node.getAsDecl();
18501851
if (!decl)
18511852
return false;
1853+
// Types in the Darwin module are not always guarded by `extern "C"`.
1854+
if (decl->getOwningModule()->getTopLevelModuleName() == "Darwin")
1855+
return false;
18521856
// Namespaces by themselves don't impact ABI.
18531857
if (isa<clang::NamespaceDecl>(decl))
18541858
return false;
@@ -1882,9 +1886,15 @@ bool isFragileClangNode(const ClangNode &node) {
18821886
// with library evolution if its type is compatible.
18831887
if (auto *pd = dyn_cast<clang::ObjCPropertyDecl>(decl))
18841888
return isFragileClangType(pd->getType());
1889+
if (auto *fieldDecl = dyn_cast<clang::FieldDecl>(decl))
1890+
return isFragileClangType(fieldDecl->getType());
18851891
if (auto *typedefDecl = dyn_cast<clang::TypedefNameDecl>(decl))
18861892
return isFragileClangType(typedefDecl->getUnderlyingType());
1887-
if (auto *rd = dyn_cast<clang::RecordDecl>(decl)) {
1893+
if (auto *rd = dyn_cast<clang::TagDecl>(decl)) {
1894+
if (auto *enumDecl = dyn_cast<clang::EnumDecl>(rd))
1895+
// Scoped enums only exist in C++ and therefore are always fragile.
1896+
if (enumDecl->isScoped())
1897+
return true;
18881898
if (!isa<clang::CXXRecordDecl>(rd))
18891899
return false;
18901900
return !rd->getDeclContext()->isExternCContext();

test/Interop/Cxx/modules/emit-module-interface.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33
// Check if fragile Swift interface with struct
44
// extensions can be reparsed:
55
// RUN: %target-swift-frontend -swift-version 5 -typecheck -emit-module-interface-path %t/UsesCxxStruct.swiftinterface %s -I %S/Inputs -swift-version 5 -enable-experimental-cxx-interop %S/Inputs/namespace-extension-lib.swift
6-
// RUN: %target-swift-frontend -swift-version 5 -typecheck-module-from-interface %t/UsesCxxStruct.swiftinterface -I %S/Inputs
6+
// RUN: %target-swift-frontend -swift-version 5 -typecheck-module-from-interface %t/UsesCxxStruct.swiftinterface -I %S/Inputs -enable-experimental-cxx-interop
77
// RUN: %FileCheck --input-file=%t/UsesCxxStruct.swiftinterface %s
8-
// CHECK: -enable-experimental-cxx-interop
8+
9+
// The textual module interface should not contain the C++ interop flag.
10+
// CHECK-NOT: -enable-experimental-cxx-interop
11+
// CHECK-NOT: -cxx-interoperability-mode
912

1013

1114
// Check if resilient Swift interface with builtin
1215
// type extensions can be reparsed:
1316
// RUN: %target-swift-emit-module-interface(%t/ResilientStruct.swiftinterface) %s -I %S/Inputs -enable-library-evolution -swift-version 5 -enable-experimental-cxx-interop %S/Inputs/namespace-extension-lib.swift -DRESILIENT
14-
// RUN: %target-swift-typecheck-module-from-interface(%t/ResilientStruct.swiftinterface) -I %S/Inputs -DRESILIENT
17+
// RUN: %target-swift-typecheck-module-from-interface(%t/ResilientStruct.swiftinterface) -I %S/Inputs -DRESILIENT -enable-experimental-cxx-interop
1518
// RUN: %FileCheck --input-file=%t/ResilientStruct.swiftinterface %s
1619

1720
import Namespaces

validation-test/ParseableInterface/verify_all_overlays.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
"DifferentiationUnittest",
4747
"Swift",
4848
"SwiftLang",
49-
"std", # swiftstd uses `-module-interface-preserve-types-as-written`
49+
# swiftCxxStdlib uses `-module-interface-preserve-types-as-written`
50+
"CxxStdlib",
5051
]:
5152
continue
5253

0 commit comments

Comments
 (0)