Skip to content

Commit c1ff14b

Browse files
committed
[Dependency Scanning] Record header dependencies of Binary Swift module dependencies
These are meant to capture paths to the PCH files that a given module was built with.
1 parent 7bbc4d4 commit c1ff14b

File tree

6 files changed

+89
-44
lines changed

6 files changed

+89
-44
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,14 @@ class ModuleDependencyInfoStorageBase {
9898
public:
9999
const ModuleDependencyKind dependencyKind;
100100

101+
ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind)
102+
: dependencyKind(dependencyKind),
103+
resolved(false) { }
104+
101105
ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind,
102-
bool resolved = false)
103-
: dependencyKind(dependencyKind), resolved(resolved) { }
106+
const std::vector<std::string> &moduleImports)
107+
: dependencyKind(dependencyKind), moduleImports(moduleImports),
108+
resolved(false) {}
104109

105110
virtual ModuleDependencyInfoStorageBase *clone() const = 0;
106111

@@ -245,11 +250,13 @@ class SwiftBinaryModuleDependencyStorage : public ModuleDependencyInfoStorageBas
245250
SwiftBinaryModuleDependencyStorage(const std::string &compiledModulePath,
246251
const std::string &moduleDocPath,
247252
const std::string &sourceInfoPath,
253+
const std::vector<std::string> &moduleImports,
254+
const std::vector<std::string> &headerImports,
248255
const bool isFramework)
249-
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftBinary),
250-
compiledModulePath(compiledModulePath),
251-
moduleDocPath(moduleDocPath),
252-
sourceInfoPath(sourceInfoPath),
256+
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftBinary,
257+
moduleImports),
258+
compiledModulePath(compiledModulePath), moduleDocPath(moduleDocPath),
259+
sourceInfoPath(sourceInfoPath), preCompiledBridgingHeaderPaths(headerImports),
253260
isFramework(isFramework) {}
254261

255262
ModuleDependencyInfoStorageBase *clone() const override {
@@ -265,6 +272,9 @@ class SwiftBinaryModuleDependencyStorage : public ModuleDependencyInfoStorageBas
265272
/// The path to the .swiftSourceInfo file.
266273
const std::string sourceInfoPath;
267274

275+
/// The paths of all the .pch dependencies of this module.
276+
const std::vector<std::string> preCompiledBridgingHeaderPaths;
277+
268278
/// A flag that indicates this dependency is a framework
269279
const bool isFramework;
270280

@@ -400,10 +410,13 @@ class ModuleDependencyInfo {
400410
const std::string &compiledModulePath,
401411
const std::string &moduleDocPath,
402412
const std::string &sourceInfoPath,
413+
const std::vector<std::string> &moduleImports,
414+
const std::vector<std::string> &headerImports,
403415
bool isFramework) {
404416
return ModuleDependencyInfo(
405417
std::make_unique<SwiftBinaryModuleDependencyStorage>(
406-
compiledModulePath, moduleDocPath, sourceInfoPath, isFramework));
418+
compiledModulePath, moduleDocPath, sourceInfoPath,
419+
moduleImports, headerImports, isFramework));
407420
}
408421

409422
/// Describe the main Swift module.

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ using SwiftBinaryModuleDetailsLayout =
155155
FileIDField, // compiledModulePath
156156
FileIDField, // moduleDocPath
157157
FileIDField, // moduleSourceInfoPath
158+
ImportArrayIDField, // headerImports
158159
IsFrameworkField // isFramework
159160
>;
160161

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,20 @@ class SerializedModuleLoaderBase : public ModuleLoader {
150150
/// Scan the given serialized module file to determine dependencies.
151151
llvm::ErrorOr<ModuleDependencyInfo> scanModuleFile(Twine modulePath, bool isFramework);
152152

153-
static llvm::ErrorOr<llvm::StringSet<>>
154-
getModuleImportsOfModule(Twine modulePath,
155-
ModuleLoadingBehavior transitiveBehavior,
156-
bool isFramework,
157-
bool isRequiredOSSAModules,
158-
StringRef SDKName,
159-
StringRef packageName,
160-
llvm::vfs::FileSystem *fileSystem,
161-
PathObfuscator &recoverer);
153+
struct BinaryModuleImports {
154+
llvm::StringSet<> moduleImports;
155+
llvm::StringSet<> headerImports;
156+
};
157+
158+
static llvm::ErrorOr<BinaryModuleImports>
159+
getImportsOfModule(Twine modulePath,
160+
ModuleLoadingBehavior transitiveBehavior,
161+
bool isFramework,
162+
bool isRequiredOSSAModules,
163+
StringRef SDKName,
164+
StringRef packageName,
165+
llvm::vfs::FileSystem *fileSystem,
166+
PathObfuscator &recoverer);
162167

163168
/// Load the module file into a buffer and also collect its module name.
164169
static std::unique_ptr<llvm::MemoryBuffer>

lib/DependencyScan/ModuleDependencyCacheSerialization.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -413,10 +413,10 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
413413
"Unexpected SWIFT_BINARY_MODULE_DETAILS_NODE record");
414414
cache.configureForContextHash(getContextHash());
415415
unsigned compiledModulePathID, moduleDocPathID, moduleSourceInfoPathID,
416-
isFramework;
416+
headerImportsArrayID, isFramework;
417417
SwiftBinaryModuleDetailsLayout::readRecord(
418418
Scratch, compiledModulePathID, moduleDocPathID,
419-
moduleSourceInfoPathID, isFramework);
419+
moduleSourceInfoPathID, headerImportsArrayID, isFramework);
420420

421421
auto compiledModulePath = getIdentifier(compiledModulePathID);
422422
if (!compiledModulePath)
@@ -428,13 +428,14 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
428428
if (!moduleSourceInfoPath)
429429
llvm::report_fatal_error("Bad module source info path");
430430

431+
auto headerImports = getStringArray(headerImportsArrayID);
432+
if (!headerImports)
433+
llvm::report_fatal_error("Bad binary direct dependencies: no header imports");
434+
431435
// Form the dependencies storage object
432436
auto moduleDep = ModuleDependencyInfo::forSwiftBinaryModule(
433-
*compiledModulePath, *moduleDocPath, *moduleSourceInfoPath,
434-
isFramework);
435-
// Add dependencies of this module
436-
for (const auto &moduleName : *currentModuleImports)
437-
moduleDep.addModuleImport(moduleName);
437+
*compiledModulePath, *moduleDocPath, *moduleSourceInfoPath,
438+
*currentModuleImports, *headerImports, isFramework);
438439

439440
cache.recordDependency(currentModuleName, std::move(moduleDep),
440441
getContextHash());
@@ -638,6 +639,7 @@ bool swift::dependencies::module_dependency_cache_serialization::
638639
enum ModuleIdentifierArrayKind : uint8_t {
639640
Empty = 0,
640641
DependencyImports,
642+
DependencyHeaders,
641643
QualifiedModuleDependencyIDs,
642644
CompiledModuleCandidates,
643645
BuildCommandLine,
@@ -894,6 +896,7 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo(ModuleDependencyID modul
894896
getIdentifier(swiftBinDeps->compiledModulePath),
895897
getIdentifier(swiftBinDeps->moduleDocPath),
896898
getIdentifier(swiftBinDeps->sourceInfoPath),
899+
getArrayID(moduleID, ModuleIdentifierArrayKind::DependencyHeaders),
897900
swiftBinDeps->isFramework);
898901

899902
break;
@@ -1062,6 +1065,8 @@ void ModuleDependenciesCacheSerializer::collectStringsAndArrays(
10621065
addIdentifier(swiftBinDeps->compiledModulePath);
10631066
addIdentifier(swiftBinDeps->moduleDocPath);
10641067
addIdentifier(swiftBinDeps->sourceInfoPath);
1068+
addStringArray(moduleID, ModuleIdentifierArrayKind::DependencyHeaders,
1069+
swiftBinDeps->preCompiledBridgingHeaderPaths);
10651070
break;
10661071
}
10671072
case swift::ModuleDependencyKind::SwiftPlaceholder: {

lib/Serialization/ModuleDependencyScanner.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,38 +194,41 @@ ErrorOr<ModuleDependencyInfo> ModuleDependencyScanner::scanInterfaceFile(
194194
});
195195
if (adjacentBinaryModule != compiledCandidates.end()) {
196196
// Required modules.
197-
auto adjacentBinaryModuleRequiredImports = getModuleImportsOfModule(
197+
auto adjacentBinaryModuleRequiredImports = getImportsOfModule(
198198
*adjacentBinaryModule, ModuleLoadingBehavior::Required, isFramework,
199199
isRequiredOSSAModules(), Ctx.LangOpts.SDKName,
200200
Ctx.LangOpts.PackageName, Ctx.SourceMgr.getFileSystem().get(),
201201
Ctx.SearchPathOpts.DeserializedPathRecoverer);
202202
if (!adjacentBinaryModuleRequiredImports)
203203
return adjacentBinaryModuleRequiredImports.getError();
204-
204+
auto adjacentBinaryModuleRequiredModuleImports =
205+
(*adjacentBinaryModuleRequiredImports).moduleImports;
205206
#ifndef NDEBUG
206207
// Verify that the set of required modules read out from the binary
207208
// module is a super-set of module imports identified in the
208209
// textual interface.
209210
for (const auto &requiredImport : Result->getModuleImports()) {
210-
assert(adjacentBinaryModuleRequiredImports->contains(requiredImport) &&
211+
assert(adjacentBinaryModuleRequiredModuleImports.contains(requiredImport) &&
211212
"Expected adjacent binary module's import set to contain all "
212213
"textual interface imports.");
213214
}
214215
#endif
215216

216-
for (const auto &requiredImport : *adjacentBinaryModuleRequiredImports)
217+
for (const auto &requiredImport : adjacentBinaryModuleRequiredModuleImports)
217218
Result->addModuleImport(requiredImport.getKey(),
218219
&alreadyAddedModules);
219220

220221
// Optional modules. Will be looked-up on a best-effort basis
221-
auto adjacentBinaryModuleOptionalImports = getModuleImportsOfModule(
222+
auto adjacentBinaryModuleOptionalImports = getImportsOfModule(
222223
*adjacentBinaryModule, ModuleLoadingBehavior::Optional, isFramework,
223224
isRequiredOSSAModules(), Ctx.LangOpts.SDKName,
224225
Ctx.LangOpts.PackageName, Ctx.SourceMgr.getFileSystem().get(),
225226
Ctx.SearchPathOpts.DeserializedPathRecoverer);
226227
if (!adjacentBinaryModuleOptionalImports)
227228
return adjacentBinaryModuleOptionalImports.getError();
228-
for (const auto &optionalImport : *adjacentBinaryModuleOptionalImports)
229+
auto adjacentBinaryModuleOptionalModuleImports =
230+
(*adjacentBinaryModuleOptionalImports).moduleImports;
231+
for (const auto &optionalImport : adjacentBinaryModuleOptionalModuleImports)
229232
Result->addOptionalModuleImport(optionalImport.getKey(),
230233
&alreadyAddedModules);
231234
}

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@ std::error_code SerializedModuleLoaderBase::openModuleFile(
391391
return std::error_code();
392392
}
393393

394-
llvm::ErrorOr<llvm::StringSet<>>
395-
SerializedModuleLoaderBase::getModuleImportsOfModule(
394+
llvm::ErrorOr<SerializedModuleLoaderBase::BinaryModuleImports>
395+
SerializedModuleLoaderBase::getImportsOfModule(
396396
Twine modulePath, ModuleLoadingBehavior transitiveBehavior,
397397
bool isFramework, bool isRequiredOSSAModules, StringRef SDKName,
398398
StringRef packageName, llvm::vfs::FileSystem *fileSystem,
@@ -402,16 +402,18 @@ SerializedModuleLoaderBase::getModuleImportsOfModule(
402402
return moduleBuf.getError();
403403

404404
llvm::StringSet<> importedModuleNames;
405+
llvm::StringSet<> importedHeaders;
405406
// Load the module file without validation.
406407
std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile;
407408
serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load(
408409
"", "", std::move(moduleBuf.get()), nullptr, nullptr, isFramework,
409410
isRequiredOSSAModules, SDKName, recoverer, loadedModuleFile);
410411

411412
for (const auto &dependency : loadedModuleFile->getDependencies()) {
412-
// FIXME: Record header dependency?
413-
if (dependency.isHeader())
413+
if (dependency.isHeader()) {
414+
importedHeaders.insert(dependency.RawPath);
414415
continue;
416+
}
415417

416418
ModuleLoadingBehavior dependencyTransitiveBehavior =
417419
loadedModuleFile->getTransitiveLoadingBehavior(
@@ -432,16 +434,13 @@ SerializedModuleLoaderBase::getModuleImportsOfModule(
432434
importedModuleNames.insert(moduleName);
433435
}
434436

435-
return importedModuleNames;
437+
return SerializedModuleLoaderBase::BinaryModuleImports{importedModuleNames, importedHeaders};
436438
}
437439

438440
llvm::ErrorOr<ModuleDependencyInfo>
439441
SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework) {
440442
const std::string moduleDocPath;
441443
const std::string sourceInfoPath;
442-
// Map the set of dependencies over to the "module dependencies".
443-
auto dependencies = ModuleDependencyInfo::forSwiftBinaryModule(
444-
modulePath.str(), moduleDocPath, sourceInfoPath, isFramework);
445444
// Some transitive dependencies of binary modules are not required to be
446445
// imported during normal builds.
447446
// TODO: This is worth revisiting for debugger purposes where
@@ -450,18 +449,37 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework) {
450449
// optional.
451450
ModuleLoadingBehavior transitiveLoadingBehavior =
452451
ModuleLoadingBehavior::Required;
453-
auto importedModuleNames = getModuleImportsOfModule(
452+
auto binaryModuleImports = getImportsOfModule(
454453
modulePath, transitiveLoadingBehavior, isFramework,
455454
isRequiredOSSAModules(), Ctx.LangOpts.SDKName, Ctx.LangOpts.PackageName,
456455
Ctx.SourceMgr.getFileSystem().get(),
457456
Ctx.SearchPathOpts.DeserializedPathRecoverer);
458-
if (!importedModuleNames)
459-
return importedModuleNames.getError();
457+
if (!binaryModuleImports)
458+
return binaryModuleImports.getError();
459+
460+
auto importedModuleSet = binaryModuleImports.get().moduleImports;
461+
std::vector<std::string> importedModuleNames;
462+
importedModuleNames.reserve(importedModuleSet.size());
463+
llvm::transform(importedModuleSet.keys(),
464+
std::back_inserter(importedModuleNames),
465+
[](llvm::StringRef N) {
466+
return N.str();
467+
});
468+
469+
auto importedHeaderSet = binaryModuleImports.get().headerImports;
470+
std::vector<std::string> importedHeaders;
471+
importedHeaders.reserve(importedHeaderSet.size());
472+
llvm::transform(importedHeaderSet.keys(),
473+
std::back_inserter(importedHeaders),
474+
[](llvm::StringRef N) {
475+
return N.str();
476+
});
460477

461-
llvm::StringSet<> addedModuleNames;
462-
for (const auto &importedModuleName : *importedModuleNames)
463-
dependencies.addModuleImport(importedModuleName.getKey(),
464-
&addedModuleNames);
478+
// Map the set of dependencies over to the "module dependencies".
479+
auto dependencies = ModuleDependencyInfo::forSwiftBinaryModule(
480+
modulePath.str(), moduleDocPath, sourceInfoPath,
481+
importedModuleNames, importedHeaders, isFramework,
482+
/*module-cache-key*/ "");
465483

466484
return std::move(dependencies);
467485
}

0 commit comments

Comments
 (0)