Skip to content

Commit 3af2d83

Browse files
[BridgingHeader] Fix auto-chaining when only dependency has bridging header
When enable bridging header auto chaining, it is possible for the compilation to have a PCH file input for the bridging header from a binary swift module dependency. In this case, we should not report a bridging header for current module as bridging header can be leaking out through swiftinterface file. To fully distinguish the PCH files passed in through different situation, here are the situations: * If no chaining is used, only `-import-objc-header` option is used and it can be used to pass either a header file or a PCH file depending if GeneratePCH job is requested or not. * If chaining is enabled, `-import-objc-header` is only used to pass the header file and `-import-pch` is used to pass PCH file. Chaining mode requires PCH generation if bridging header is used. rdar://144623388
1 parent a86743e commit 3af2d83

File tree

4 files changed

+17
-12
lines changed

4 files changed

+17
-12
lines changed

include/swift/Frontend/FrontendOptions.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ class FrontendOptions {
286286

287287
/// If set, the header provided in ImplicitObjCHeaderPath will be rewritten
288288
/// by the Clang importer as part of semantic analysis.
289-
bool SerializeBridgingHeader = false;
289+
bool ModuleHasBridgingHeader = false;
290290

291291
/// Indicates whether or not the frontend should print statistics upon
292292
/// termination.

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ void ArgsToFrontendOptionsConverter::computeImportObjCHeaderOptions() {
901901
Opts.ImplicitObjCHeaderPath = A->getValue();
902902
// If `-import-object-header` is used, it means the module has a direct
903903
// bridging header dependency and it can be serialized into binary module.
904-
Opts.SerializeBridgingHeader |= true;
904+
Opts.ModuleHasBridgingHeader |= true;
905905
}
906906
if (const Arg *A = Args.getLastArgNoClaim(OPT_import_pch))
907907
Opts.ImplicitObjCPCHPath = A->getValue();

lib/Frontend/Frontend.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
196196
serializationOpts.DocOutputPath = outs.ModuleDocOutputPath;
197197
serializationOpts.SourceInfoOutputPath = outs.ModuleSourceInfoOutputPath;
198198
serializationOpts.GroupInfoPath = opts.GroupInfoPath.c_str();
199-
if (opts.SerializeBridgingHeader && !outs.ModuleOutputPath.empty())
199+
if (opts.ModuleHasBridgingHeader && !outs.ModuleOutputPath.empty())
200200
serializationOpts.SerializeBridgingHeader = true;
201201
// For batch mode, emit empty header path as placeholder.
202202
if (serializationOpts.SerializeBridgingHeader &&
@@ -1302,10 +1302,12 @@ ImplicitImportInfo CompilerInstance::getImplicitImportInfo() const {
13021302
}
13031303

13041304
imports.ShouldImportUnderlyingModule = frontendOpts.ImportUnderlyingModule;
1305-
if (frontendOpts.ImplicitObjCPCHPath.empty())
1306-
imports.BridgingHeaderPath = frontendOpts.ImplicitObjCHeaderPath;
1307-
else
1308-
imports.BridgingHeaderPath = frontendOpts.ImplicitObjCPCHPath;
1305+
if (frontendOpts.ModuleHasBridgingHeader) {
1306+
if (frontendOpts.ImplicitObjCPCHPath.empty())
1307+
imports.BridgingHeaderPath = frontendOpts.ImplicitObjCHeaderPath;
1308+
else
1309+
imports.BridgingHeaderPath = frontendOpts.ImplicitObjCPCHPath;
1310+
}
13091311
return imports;
13101312
}
13111313

test/ScanDependencies/bridging-header-autochaining.swift

+8-5
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@
4343
// RUN: %target-swift-frontend -module-name Test -O @%t/MyApp.cmd %t/test.swift \
4444
// RUN: -emit-module -o %t/Test.swiftmodule
4545

46-
/// Importing binary module with bridging header built from CAS from a regluar build.
46+
/// Importing binary module with bridging header from a module that also has bridging header using implicit build method.
4747
/// This should succeed even it is also importing a bridging header that shares same header dependencies (with proper header guard).
4848
// RUN: %target-swift-frontend -typecheck -module-name User \
4949
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
5050
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap \
5151
// RUN: -I %t %t/user2.swift -import-objc-header %t/Bridging2.h
5252

53-
/// Importing binary module with bridging header built from CAS from a cached build. This should work without additional bridging header deps.
53+
/// Importing binary module with bridging header from a module that has no bridging header.
5454
// RUN: %target-swift-frontend -scan-dependencies -module-name User -module-cache-path %t/clang-module-cache -O \
5555
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
5656
// RUN: %t/user.swift -o %t/deps2.json -auto-bridging-header-chaining -scanner-output-dir %t -scanner-debug-write-output \
57-
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t
57+
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t -enable-library-evolution
5858

5959
// RUN: %swift-scan-test -action get_chained_bridging_header -- %target-swift-frontend -emit-module \
6060
// RUN: -module-name User -module-cache-path %t/clang-module-cache -O \
@@ -74,12 +74,15 @@
7474
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -disable-implicit-swift-modules \
7575
// RUN: -import-pch %t/bridging1.pch \
7676
// RUN: -explicit-swift-module-map-file %t/map2.json @%t/User.cmd %t/user.swift \
77-
// RUN: -emit-module -o %t/User.swiftmodule
77+
// RUN: -emit-module -o %t/User.swiftmodule -emit-module-interface-path %t/User.swiftinterface -enable-library-evolution
7878

79+
/// Make sure the emitted content is compatible with original. The embedded header path needs to be original header and no bridging header module leaking into interface.
7980
// RUN: llvm-bcanalyzer -dump %t/User.swiftmodule | %FileCheck %s --check-prefix CHECK-NO-HEADER
8081
// CHECK-NO-HEADER-NOT: <IMPORTED_HEADER
82+
// RUN: %FileCheck %s --check-prefix NO-OBJC-LEAKING --input-file=%t/User.swiftinterface
83+
// NO-OBJC-LEAKING-NOT: import __ObjC
8184

82-
/// Importing binary module with bridging header for a cached build while also importing a bridging header.
85+
/// Importing binary module with bridging header from a module with bridging header using explicit build method with header chaining.
8386
// RUN: %target-swift-frontend -scan-dependencies -module-name User -O \
8487
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
8588
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap \

0 commit comments

Comments
 (0)