Merge pull request #69109 from artemcm/EBM_BridgingHeader_Fix

[Explicit Module Builds] Restore prior behavior of consuming `.h` dependencies of binary module dependencies directly, instead of attempting to load their PCH
This commit is contained in:
Artem Chikin
2023-10-13 09:04:37 -07:00
committed by GitHub
5 changed files with 47 additions and 14 deletions

View File

@@ -158,6 +158,7 @@ namespace swift {
bool EmbeddedSwiftModule = false;
bool IsOSSA = false;
bool SkipNonExportableDecls = false;
bool ExplicitModuleBuild = false;
};
} // end namespace swift

View File

@@ -240,6 +240,8 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
serializationOpts.SkipNonExportableDecls = opts.SkipNonExportableDecls;
serializationOpts.ExplicitModuleBuild = FrontendOpts.DisableImplicitModules;
return serializationOpts;
}

View File

@@ -53,6 +53,8 @@
#include "swift/Serialization/SerializationOptions.h"
#include "swift/Strings.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@@ -1297,15 +1299,28 @@ void Serializer::writeInputBlock() {
off_t importedHeaderSize = 0;
time_t importedHeaderModTime = 0;
std::string contents;
if (!Options.ImportedHeader.empty()) {
auto importedHeaderPath = Options.ImportedHeader;
// We do not want to serialize the explicitly-specified .pch path if one was
// provided. Instead we write out the path to the original header source so
// that clients can consume it.
if (Options.ExplicitModuleBuild &&
llvm::sys::path::extension(importedHeaderPath)
.endswith(file_types::getExtension(file_types::TY_PCH)))
importedHeaderPath = clangImporter->getClangInstance()
.getASTReader()
->getModuleManager()
.lookupByFileName(importedHeaderPath)
->OriginalSourceFileName;
if (!importedHeaderPath.empty()) {
contents = clangImporter->getBridgingHeaderContents(
Options.ImportedHeader, importedHeaderSize, importedHeaderModTime);
importedHeaderPath, importedHeaderSize, importedHeaderModTime);
}
assert(publicImportSet.count(bridgingHeaderImport));
ImportedHeader.emit(ScratchRecord,
publicImportSet.count(bridgingHeaderImport),
importedHeaderSize, importedHeaderModTime,
Options.ImportedHeader);
importedHeaderPath);
if (!contents.empty()) {
contents.push_back('\0');
ImportedHeaderContents.emit(ScratchRecord, contents);

View File

@@ -477,12 +477,19 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework) {
auto importedHeaderSet = binaryModuleImports.get().headerImports;
std::vector<std::string> importedHeaders;
// FIXME: We only record these dependencies in CAS mode, because
// we require explicit PCH tasks to be produced for imported header
// of binary module dependencies. In the meantime, in non-CAS mode
// loading clients will consume the `.h` files encoded in the `.swiftmodules`
// directly.
if (Ctx.ClangImporterOpts.CASOpts) {
importedHeaders.reserve(importedHeaderSet.size());
llvm::transform(importedHeaderSet.keys(),
std::back_inserter(importedHeaders),
[](llvm::StringRef N) {
return N.str();
});
}
auto &importedOptionalModuleSet = binaryModuleOptionalImports.get().moduleImports;
std::vector<std::string> importedOptionalModuleNames;

View File

@@ -2,7 +2,9 @@
// RUN: %empty-directory(%t)
// RUN: %empty-directory(%t/clang-module-cache)
// RUN: %empty-directory(%t/PCH)
// RUN: %empty-directory(%t/HEADER)
// RUN: %empty-directory(%t/SwiftModules)
// RUN: %empty-directory(%t/CAS)
// - Set up Foo Swift dependency
// RUN: echo "extension Profiler {" >> %t/foo.swift
@@ -10,10 +12,10 @@
// RUN: echo "}" >> %t/foo.swift
// - Set up Foo bridging header
// RUN: echo "struct Profiler { void* ptr; };" >> %t/foo.h
// RUN: echo "struct Profiler { void* ptr; };" >> %t/HEADER/foo.h
// - Compile bridging header
// RUN: %target-swift-frontend -enable-objc-interop -emit-pch %t/foo.h -o %t/PCH/foo.pch -disable-implicit-swift-modules
// RUN: %target-swift-frontend -enable-objc-interop -emit-pch %t/HEADER/foo.h -o %t/PCH/foo.pch -disable-implicit-swift-modules
// - Set up explicit dependencies for Foo
// RUN: %target-swift-emit-pcm -module-name SwiftShims %swift-lib-dir/swift/shims/module.modulemap -o %t/inputs/SwiftShims.pcm
@@ -50,21 +52,27 @@
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/SwiftModules/Foo.swiftmodule %t/foo.swift -module-name Foo -import-objc-header %t/PCH/foo.pch -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -disable-implicit-swift-modules -explicit-swift-module-map-file %t/foo_inputs_map.json
// - Scan main module
// RUN: %target-swift-frontend -scan-dependencies %s -I %t/SwiftModules -I %S/Inputs/Swift -o %t/deps.json
// RUN: %target-swift-frontend -scan-dependencies %s -I %t/SwiftModules -I %S/Inputs/Swift -o %t/deps.json -cache-compile-job -cas-path %t/cas
// RUN: %validate-json %t/deps.json | %FileCheck %s
// - Scan main module without a CAS and ensure no headerDependencies are emitted
// RUN: %target-swift-frontend -scan-dependencies %s -I %t/SwiftModules -I %S/Inputs/Swift -o %t/deps_nocas.json
// RUN: %validate-json %t/deps_nocas.json | %FileCheck %s --check-prefix=CHECK-NO-HEADERS
// CHECK: "swift": "FooClient"
// CHECK: "swift": "FooClient"
// CHECK: "swiftPrebuiltExternal": "Foo"
// CHECK: "commandLine": [
// CHECK: "-include-pch",
// CHECK-NEXT: "-Xcc",
// CHECK-NEXT: "{{.*}}{{/|\\}}PCH{{/|\\}}foo.pch"
// CHECK-NEXT: "{{.*}}{{/|\\}}HEADER{{/|\\}}foo.h"
// CHECK: "swiftPrebuiltExternal": "Foo"
// CHECK: "headerDependencies": [
// CHECK: "{{.*}}{{/|\\}}PCH{{/|\\}}foo.pch"
// CHECK: "{{.*}}{{/|\\}}HEADER{{/|\\}}foo.h"
// CHECK: ],
// CHECK-NO-HEADERS-NOT: "headerDependencies"
import FooClient