Skip to content

Commit b91842b

Browse files
Merge pull request #79175 from cachemeifyoucan/eng/PR-144261730
2 parents 3637e69 + 0e8d794 commit b91842b

File tree

2 files changed

+126
-6
lines changed

2 files changed

+126
-6
lines changed

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "llvm/CAS/CachingOnDiskFileSystem.h"
3737
#include "llvm/Support/Error.h"
3838
#include "llvm/Support/MemoryBuffer.h"
39+
#include "llvm/Support/MemoryBufferRef.h"
3940
#include "llvm/Support/Path.h"
4041
#include "llvm/Support/Threading.h"
4142
#include "llvm/Support/VersionTuple.h"
@@ -1063,6 +1064,42 @@ void ModuleDependencyScanner::resolveHeaderDependenciesForModule(
10631064
if (!isTextualModuleWithABridgingHeader && !isBinaryModuleWithHeaderInput)
10641065
return;
10651066

1067+
1068+
std::optional<std::string> headerPath;
1069+
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer;
1070+
std::optional<llvm::MemoryBufferRef> sourceBufferRef;
1071+
1072+
auto extractHeaderContent =
1073+
[&](const SwiftBinaryModuleDependencyStorage &binaryMod)
1074+
-> std::unique_ptr<llvm::MemoryBuffer> {
1075+
auto header = binaryMod.headerImport;
1076+
// Check to see if the header input exists on disk.
1077+
auto FS = ScanASTContext.SourceMgr.getFileSystem();
1078+
if (FS->exists(header))
1079+
return nullptr;
1080+
1081+
auto moduleBuf = FS->getBufferForFile(binaryMod.compiledModulePath);
1082+
if (!moduleBuf)
1083+
return nullptr;
1084+
1085+
auto content = extractEmbeddedBridgingHeaderContent(std::move(*moduleBuf),
1086+
ScanASTContext);
1087+
if (content.empty())
1088+
return nullptr;
1089+
1090+
return llvm::MemoryBuffer::getMemBufferCopy(content, header);
1091+
};
1092+
1093+
if (isBinaryModuleWithHeaderInput) {
1094+
auto &binaryMod = *moduleDependencyInfo.getAsSwiftBinaryModule();
1095+
if (auto embeddedHeader = extractHeaderContent(binaryMod)) {
1096+
sourceBuffer = std::move(embeddedHeader);
1097+
sourceBufferRef = sourceBuffer->getMemBufferRef();
1098+
} else
1099+
headerPath = binaryMod.headerImport;
1100+
} else
1101+
headerPath = *moduleDependencyInfo.getBridgingHeader();
1102+
10661103
withDependencyScanningWorker(
10671104
[&](ModuleDependencyScanningWorker *ScanningWorker) {
10681105
auto clangImporter = static_cast<ClangImporter *>(
@@ -1072,12 +1109,9 @@ void ModuleDependencyScanner::resolveHeaderDependenciesForModule(
10721109
std::optional<std::string> includeTreeID;
10731110
std::vector<std::string> bridgingHeaderCommandLine;
10741111
auto headerScan = clangImporter->getHeaderDependencies(
1075-
moduleID,
1076-
isTextualModuleWithABridgingHeader
1077-
? *moduleDependencyInfo.getBridgingHeader()
1078-
: moduleDependencyInfo.getAsSwiftBinaryModule()->headerImport,
1079-
/*sourceBuffer=*/std::nullopt, ScanningWorker->clangScanningTool,
1080-
cache, headerClangModuleDependencies, headerFileInputs,
1112+
moduleID, headerPath, sourceBufferRef,
1113+
ScanningWorker->clangScanningTool, cache,
1114+
headerClangModuleDependencies, headerFileInputs,
10811115
bridgingHeaderCommandLine, includeTreeID);
10821116
if (!headerScan) {
10831117
// Record direct header Clang dependencies
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// REQUIRES: objc_interop
2+
// RUN: %empty-directory(%t)
3+
// RUN: split-file %s %t
4+
5+
// RUN: %target-swift-frontend -emit-module -module-name Test -module-cache-path %t/clang-module-cache -O \
6+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
7+
// RUN: %t/test.swift -o %t/Test.swiftmodule \
8+
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -import-objc-header %t/Bridging.h
9+
10+
// RUN: %target-swift-frontend -scan-dependencies -module-name User -module-cache-path %t/clang-module-cache -O \
11+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
12+
// RUN: %t/user.swift -o %t/deps.json \
13+
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t
14+
15+
/// Remove bridging header from disk and rescan
16+
// RUN: rm -rf %t/Bridging.h %t/Foo.h %t/Foo2.h
17+
// RUN: %target-swift-frontend -scan-dependencies -module-name User -module-cache-path %t/clang-module-cache -O \
18+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
19+
// RUN: %t/user.swift -o %t/deps2.json \
20+
// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t
21+
22+
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps.json swiftPrebuiltExternal:Test headerModuleDependencies | %FileCheck %s --check-prefix=MODULE
23+
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps.json swiftPrebuiltExternal:Test headerDependenciesSourceFiles | %FileCheck %s --check-prefix=FILE
24+
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps2.json swiftPrebuiltExternal:Test headerModuleDependencies | %FileCheck %s --check-prefix=MODULE
25+
// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps2.json swiftPrebuiltExternal:Test headerDependenciesSourceFiles | %FileCheck %s --check-prefix=FILE
26+
27+
// MODULE: "A"
28+
// FILE: Bridging.h
29+
30+
//--- test.swift
31+
public func test() {
32+
b()
33+
}
34+
public class TestB: B {}
35+
36+
//--- user.swift
37+
import Test
38+
39+
func user() {
40+
var b: TestB
41+
test()
42+
}
43+
44+
extension A {
45+
public func testA() {}
46+
}
47+
48+
//--- Bridging.h
49+
#include "Foo.h"
50+
#include "Foo2.h"
51+
52+
//--- Foo.h
53+
#import "a.h"
54+
#ifndef IMPORT_FOO
55+
#define IMPORT_FOO
56+
int Foo = 0;
57+
#endif
58+
59+
//--- Foo2.h
60+
#ifndef IMPORT_FOO2
61+
#define IMPORT_FOO2
62+
int Foo2 = 0;
63+
#endif
64+
65+
//--- a.h
66+
#include "b.h"
67+
struct A {
68+
int a;
69+
};
70+
71+
//--- b.h
72+
void b(void);
73+
@interface B
74+
@end
75+
76+
//--- a.modulemap
77+
module A {
78+
header "a.h"
79+
export *
80+
}
81+
82+
//--- b.modulemap
83+
module B {
84+
header "b.h"
85+
export *
86+
}

0 commit comments

Comments
 (0)