Skip to content

Commit 88b719d

Browse files
[Caching] Adjust the bridging header chaining rule
Adjust the rule for how bridging header chaining is performed to increase compatibilities with existing project configuration. Previously in #84442, bridging header chaining was done via content concatenation, rather than `#include` via absolute path, to enable prefix mapping to drop references to absolute path. This triggers an incompatibility since the directory of the header file is also considered as part of the search path when resolve the include directives in the file. Simple concatenation will result in some `#include` can no longer be resolved. Now relax the rule to do header content concatenation only when prefix map is used. This will keep the breakage minimal, and the breakage can always be fixed by additional include paths when turning on prefix mapping. In the future, we should move towards internal bridging header implementation to avoid the need of chaining completely. rdar://161854282
1 parent 94de642 commit 88b719d

File tree

3 files changed

+65
-39
lines changed

3 files changed

+65
-39
lines changed

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,16 +1644,6 @@ void ModuleDependencyScanner::resolveCrossImportOverlayDependencies(
16441644
allModules.end(), action);
16451645
}
16461646

1647-
static void appendHeaderContent(llvm::raw_ostream &OS,
1648-
llvm::MemoryBufferRef buffer,
1649-
ModuleDependencyID fromModule) {
1650-
// Use preprocessor directives to add some clues for where the content is
1651-
// coming from.
1652-
OS << "# 1 \"<module-" << fromModule.ModuleName << ">/"
1653-
<< llvm::sys::path::filename(buffer.getBufferIdentifier()) << "\" 1\n";
1654-
OS << buffer.getBuffer();
1655-
}
1656-
16571647
llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
16581648
const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
16591649
ModuleDependencyIDSetVector &allModules) {
@@ -1663,35 +1653,60 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
16631653
llvm::SmallString<256> chainedHeaderBuffer;
16641654
llvm::raw_svector_ostream outOS(chainedHeaderBuffer);
16651655

1656+
// If prefix mapping is used, don't try to import header since that will add
1657+
// a path-relative component into dependency scanning and defeat the purpose
1658+
// of prefix mapping. Additionally, if everything is prefix mapped, the
1659+
// embedded header path is also prefix mapped, thus it can't be found anyway.
1660+
bool useImportHeader = !hasPathMapping();
1661+
auto FS = ScanASTContext.SourceMgr.getFileSystem();
1662+
1663+
auto chainBridgingHeader = [&](StringRef moduleName, StringRef headerPath,
1664+
StringRef binaryModulePath) -> llvm::Error {
1665+
if (useImportHeader) {
1666+
if (auto buffer = FS->getBufferForFile(headerPath)) {
1667+
outOS << "#include \"" << headerPath << "\"\n";
1668+
return llvm::Error::success();
1669+
}
1670+
}
1671+
1672+
if (binaryModulePath.empty())
1673+
return llvm::createStringError("failed to load bridging header " +
1674+
headerPath);
1675+
1676+
// Extract the embedded bridging header
1677+
auto moduleBuf = FS->getBufferForFile(binaryModulePath);
1678+
if (!moduleBuf)
1679+
return llvm::errorCodeToError(moduleBuf.getError());
1680+
1681+
auto content = extractEmbeddedBridgingHeaderContent(
1682+
std::move(*moduleBuf), /*headerPath=*/"", ScanASTContext);
1683+
if (!content)
1684+
return llvm::createStringError("can't load embedded header from " +
1685+
binaryModulePath);
1686+
1687+
outOS << "# 1 \"<module-" << moduleName
1688+
<< "-embedded-bridging-header>\" 1\n";
1689+
outOS << content->getBuffer() << "\n";
1690+
return llvm::Error::success();
1691+
};
1692+
16661693
// Iterate through all the modules and collect all the bridging header
16671694
// and chain them into a single file. The allModules list is in the order of
16681695
// discover, thus providing stable ordering for a deterministic generated
16691696
// buffer.
1670-
auto FS = ScanASTContext.SourceMgr.getFileSystem();
16711697
for (const auto &moduleID : allModules) {
16721698
if (moduleID.Kind != ModuleDependencyKind::SwiftBinary)
16731699
continue;
16741700

16751701
auto moduleDependencyInfo = cache.findKnownDependency(moduleID);
16761702
if (auto *binaryMod = moduleDependencyInfo.getAsSwiftBinaryModule()) {
1677-
if (!binaryMod->headerImport.empty()) {
1678-
if (auto buffer= FS->getBufferForFile(binaryMod->headerImport)) {
1679-
appendHeaderContent(outOS, (*buffer)->getMemBufferRef(), moduleID);
1680-
} else {
1681-
// Extract the embedded bridging header
1682-
auto moduleBuf = FS->getBufferForFile(binaryMod->compiledModulePath);
1683-
if (!moduleBuf)
1684-
return llvm::errorCodeToError(moduleBuf.getError());
1685-
1686-
auto content = extractEmbeddedBridgingHeaderContent(
1687-
std::move(*moduleBuf), /*headerPath=*/"", ScanASTContext);
1688-
if (!content)
1689-
return llvm::createStringError("can't load embedded header from " +
1690-
binaryMod->compiledModulePath);
1691-
1692-
outOS << content->getBuffer() << "\n";
1693-
}
1694-
}
1703+
if (binaryMod->headerImport.empty())
1704+
continue;
1705+
1706+
if (auto E =
1707+
chainBridgingHeader(moduleID.ModuleName, binaryMod->headerImport,
1708+
binaryMod->compiledModulePath))
1709+
return E;
16951710
}
16961711
}
16971712

@@ -1718,11 +1733,10 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
17181733
// There are bridging header needed to be chained. Append the bridging
17191734
// header from main module if needed and create use a new source buffer.
17201735
if (mainModule->textualModuleDetails.bridgingHeaderFile) {
1721-
auto srcBuf = FS->getBufferForFile(
1722-
*mainModule->textualModuleDetails.bridgingHeaderFile);
1723-
if (!srcBuf)
1724-
return llvm::errorCodeToError(srcBuf.getError());
1725-
appendHeaderContent(outOS, (*srcBuf)->getMemBufferRef(), rootModuleID);
1736+
if (auto E = chainBridgingHeader(
1737+
rootModuleID.ModuleName,
1738+
*mainModule->textualModuleDetails.bridgingHeaderFile, ""))
1739+
return E;
17261740
}
17271741

17281742
SmallString<256> outputPath(

test/CAS/bridging-header-prefix-map.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@
5757
// RUN: -scanner-prefix-map-paths %t/header-1 /^header \
5858
// RUN: -scanner-output-dir %t/header-1 -I %t
5959

60+
// RUN: %swift-scan-test -action get_chained_bridging_header -- %target-swift-frontend -scan-dependencies\
61+
// RUN: -module-name User -module-cache-path %t/clang-module-cache -O \
62+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
63+
// RUN: %t/user.swift -o %t/deps-3.json -auto-bridging-header-chaining -cache-compile-job -cas-path %t/cas \
64+
// RUN: -scanner-prefix-map-paths %swift_src_root /^src -scanner-prefix-map-paths %t /^tmp \
65+
// RUN: -scanner-prefix-map-paths %t/header-1 /^header \
66+
// RUN: -scanner-output-dir %t/header-1 -I %t > %t/bridging-header1.h
67+
// RUN: %FileCheck %s --input-file=%t/bridging-header1.h --check-prefix=HEADER
68+
69+
// HEADER: # 1 "<module-Test-embedded-bridging-header>" 1
70+
6071
// RUN: %target-swift-frontend -scan-dependencies -module-name User -module-cache-path %t/clang-module-cache -O \
6172
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
6273
// RUN: %t/user.swift -o %t/deps-4.json -auto-bridging-header-chaining -cache-compile-job -cas-path %t/cas \

test/ScanDependencies/bridging-header-autochaining.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,8 @@
6060
// RUN: %t/user.swift -auto-bridging-header-chaining -o %t/User.swiftmodule \
6161
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t > %t/header1.h
6262
// RUN: %FileCheck %s --check-prefix=HEADER1 --input-file=%t/header1.h
63-
// HEADER1: # 1 "<module-Test>/Bridging.h" 1
64-
// HEADER1: #include "Foo.h"
65-
// HEADER1: #include "Foo2.h"
63+
// HEADER1: #include
64+
// HEADER1-SAME: Bridging.h
6665

6766
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps2.json bridgingHeader > %t/header1.cmd
6867
// RUN: %target-swift-frontend @%t/header1.cmd -disable-implicit-swift-modules -O -o %t/bridging1.pch
@@ -94,8 +93,10 @@
9493
// RUN: %t/user.swift -auto-bridging-header-chaining -o %t/User.swiftmodule -import-objc-header %t/Bridging2.h \
9594
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t > %t/header2.h
9695
// RUN: %FileCheck %s --check-prefix=HEADER2 --input-file=%t/header2.h
97-
// HEADER2: # 1 "<module-Test>/Bridging.h" 1
98-
// HEADER2: # 1 "<module-User>/Bridging2.h" 1
96+
// HEADER2: #include
97+
// HEADER2-SAME: Bridging.h
98+
// HEADER2: #include
99+
// HEADER2-SAME: Bridging2.h
99100

100101
// RUN: %FileCheck %s --check-prefix DEPS_JSON --input-file=%t/deps3.json
101102
// DEPS_JSON: "chainedBridgingHeaderPath":

0 commit comments

Comments
 (0)