Skip to content

Commit 0816167

Browse files
authored
Merge pull request #32564 from nkcsgexi/scanner-report-prebuilt-module
ModuleLoader: refactor computePrebuiltModulePath to facilitate dependencies scanner's invocation, NFC
2 parents c4b3727 + a536947 commit 0816167

File tree

3 files changed

+121
-83
lines changed

3 files changed

+121
-83
lines changed

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,12 @@ class SerializedASTFile final : public LoadedFile {
445445
}
446446
};
447447

448-
448+
Optional<StringRef>
449+
computePrebuiltModulePath(ASTContext &ctx,
450+
StringRef interfacePath,
451+
StringRef prebuiltCacheDir,
452+
StringRef moduleName,
453+
llvm::SmallString<256> &scratch);
449454
} // end namespace swift
450455

451456
#endif

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 6 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -508,82 +508,6 @@ class ModuleInterfaceLoaderImpl {
508508
return true;
509509
}
510510

511-
Optional<StringRef>
512-
computePrebuiltModulePath(llvm::SmallString<256> &scratch) {
513-
namespace path = llvm::sys::path;
514-
StringRef sdkPath = ctx.SearchPathOpts.SDKPath;
515-
516-
// Check if the interface file comes from the SDK
517-
if (sdkPath.empty() || !hasPrefix(path::begin(interfacePath),
518-
path::end(interfacePath),
519-
path::begin(sdkPath),
520-
path::end(sdkPath)))
521-
return None;
522-
523-
// Assemble the expected path: $PREBUILT_CACHE/Foo.swiftmodule or
524-
// $PREBUILT_CACHE/Foo.swiftmodule/arch.swiftmodule. Note that there's no
525-
// cache key here.
526-
scratch = prebuiltCacheDir;
527-
528-
// FIXME: Would it be possible to only have architecture-specific names
529-
// here? Then we could skip this check.
530-
StringRef inParentDirName =
531-
path::filename(path::parent_path(interfacePath));
532-
if (path::extension(inParentDirName) == ".swiftmodule") {
533-
assert(path::stem(inParentDirName) == moduleName);
534-
path::append(scratch, inParentDirName);
535-
}
536-
path::append(scratch, path::filename(modulePath));
537-
538-
// If there isn't a file at this location, skip returning a path.
539-
if (!fs.exists(scratch))
540-
return None;
541-
542-
return scratch.str();
543-
}
544-
545-
/// Hack to deal with build systems (including the Swift standard library, at
546-
/// the time of this comment) that aren't yet using target-specific names for
547-
/// multi-target swiftmodules, in case the prebuilt cache is.
548-
Optional<StringRef>
549-
computeFallbackPrebuiltModulePath(llvm::SmallString<256> &scratch) {
550-
namespace path = llvm::sys::path;
551-
StringRef sdkPath = ctx.SearchPathOpts.SDKPath;
552-
553-
// Check if the interface file comes from the SDK
554-
if (sdkPath.empty() || !hasPrefix(path::begin(interfacePath),
555-
path::end(interfacePath),
556-
path::begin(sdkPath),
557-
path::end(sdkPath)))
558-
return None;
559-
560-
// If the module isn't target-specific, there's no fallback path.
561-
StringRef inParentDirName =
562-
path::filename(path::parent_path(interfacePath));
563-
if (path::extension(inParentDirName) != ".swiftmodule")
564-
return None;
565-
566-
// If the interface is already using the target-specific name, there's
567-
// nothing else to try.
568-
auto normalizedTarget = getTargetSpecificModuleTriple(ctx.LangOpts.Target);
569-
if (path::stem(modulePath) == normalizedTarget.str())
570-
return None;
571-
572-
// Assemble the expected path:
573-
// $PREBUILT_CACHE/Foo.swiftmodule/target.swiftmodule. Note that there's no
574-
// cache key here.
575-
scratch = prebuiltCacheDir;
576-
path::append(scratch, inParentDirName);
577-
path::append(scratch, normalizedTarget.str());
578-
scratch += ".swiftmodule";
579-
580-
// If there isn't a file at this location, skip returning a path.
581-
if (!fs.exists(scratch))
582-
return None;
583-
584-
return scratch.str();
585-
}
586-
587511
bool isInResourceDir(StringRef path) {
588512
StringRef resourceDir = ctx.SearchPathOpts.RuntimeResourcePath;
589513
if (resourceDir.empty()) return false;
@@ -715,12 +639,12 @@ class ModuleInterfaceLoaderImpl {
715639
if (!prebuiltCacheDir.empty()) {
716640
llvm::SmallString<256> scratch;
717641
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
718-
Optional<StringRef> path = computePrebuiltModulePath(scratch);
719-
if (!path) {
720-
// Hack: deal with prebuilds of modules that still use the target-based
721-
// names.
722-
path = computeFallbackPrebuiltModulePath(scratch);
723-
}
642+
Optional<StringRef> path = computePrebuiltModulePath(ctx,
643+
interfacePath,
644+
prebuiltCacheDir,
645+
moduleName,
646+
scratch);
647+
724648
if (path) {
725649
if (swiftModuleIsUpToDate(*path, deps, moduleBuffer)) {
726650
LLVM_DEBUG(llvm::dbgs() << "Found up-to-date prebuilt module at "

lib/Serialization/ModuleDependencyScanner.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "swift/Basic/Platform.h"
1314
#include "swift/Serialization/SerializedModuleLoader.h"
1415
#include "swift/AST/ASTContext.h"
1516
#include "swift/AST/DiagnosticSuppression.h"
@@ -21,6 +22,92 @@ using namespace swift;
2122
using llvm::ErrorOr;
2223

2324
namespace {
25+
static Optional<StringRef>
26+
computePrebuiltModulePathDefault(ASTContext &ctx,
27+
StringRef interfacePath,
28+
StringRef prebuiltCacheDir,
29+
StringRef moduleName,
30+
StringRef modulePath,
31+
llvm::SmallString<256> &scratch) {
32+
namespace path = llvm::sys::path;
33+
StringRef sdkPath = ctx.SearchPathOpts.SDKPath;
34+
auto &fs = *ctx.SourceMgr.getFileSystem();
35+
// Check if the interface file comes from the SDK
36+
if (sdkPath.empty() || !hasPrefix(path::begin(interfacePath),
37+
path::end(interfacePath),
38+
path::begin(sdkPath),
39+
path::end(sdkPath)))
40+
return None;
41+
42+
// Assemble the expected path: $PREBUILT_CACHE/Foo.swiftmodule or
43+
// $PREBUILT_CACHE/Foo.swiftmodule/arch.swiftmodule. Note that there's no
44+
// cache key here.
45+
scratch = prebuiltCacheDir;
46+
47+
// FIXME: Would it be possible to only have architecture-specific names
48+
// here? Then we could skip this check.
49+
StringRef inParentDirName =
50+
path::filename(path::parent_path(interfacePath));
51+
if (path::extension(inParentDirName) == ".swiftmodule") {
52+
assert(path::stem(inParentDirName) == moduleName);
53+
path::append(scratch, inParentDirName);
54+
}
55+
path::append(scratch, path::filename(modulePath));
56+
57+
// If there isn't a file at this location, skip returning a path.
58+
if (!fs.exists(scratch))
59+
return None;
60+
61+
return scratch.str();
62+
}
63+
64+
/// Hack to deal with build systems (including the Swift standard library, at
65+
/// the time of this comment) that aren't yet using target-specific names for
66+
/// multi-target swiftmodules, in case the prebuilt cache is.
67+
static Optional<StringRef>
68+
computeFallbackPrebuiltModulePath(ASTContext &ctx,
69+
StringRef interfacePath,
70+
StringRef prebuiltCacheDir,
71+
StringRef moduleName,
72+
StringRef modulePath,
73+
llvm::SmallString<256> &scratch) {
74+
namespace path = llvm::sys::path;
75+
StringRef sdkPath = ctx.SearchPathOpts.SDKPath;
76+
auto &fs = *ctx.SourceMgr.getFileSystem();
77+
78+
// Check if the interface file comes from the SDK
79+
if (sdkPath.empty() || !hasPrefix(path::begin(interfacePath),
80+
path::end(interfacePath),
81+
path::begin(sdkPath),
82+
path::end(sdkPath)))
83+
return None;
84+
85+
// If the module isn't target-specific, there's no fallback path.
86+
StringRef inParentDirName =
87+
path::filename(path::parent_path(interfacePath));
88+
if (path::extension(inParentDirName) != ".swiftmodule")
89+
return None;
90+
91+
// If the interface is already using the target-specific name, there's
92+
// nothing else to try.
93+
auto normalizedTarget = getTargetSpecificModuleTriple(ctx.LangOpts.Target);
94+
if (path::stem(modulePath) == normalizedTarget.str())
95+
return None;
96+
97+
// Assemble the expected path:
98+
// $PREBUILT_CACHE/Foo.swiftmodule/target.swiftmodule. Note that there's no
99+
// cache key here.
100+
scratch = prebuiltCacheDir;
101+
path::append(scratch, inParentDirName);
102+
path::append(scratch, normalizedTarget.str());
103+
scratch += ".swiftmodule";
104+
105+
// If there isn't a file at this location, skip returning a path.
106+
if (!fs.exists(scratch))
107+
return None;
108+
109+
return scratch.str();
110+
}
24111

25112
/// A module "loader" that looks for .swiftinterface and .swiftmodule files
26113
/// for the purpose of determining dependencies, but does not attempt to
@@ -94,6 +181,28 @@ class ModuleDependencyScanner : public SerializedModuleLoaderBase {
94181
};
95182
}
96183

184+
Optional<StringRef>
185+
swift::computePrebuiltModulePath(ASTContext &ctx,
186+
StringRef interfacePath,
187+
StringRef prebuiltCacheDir,
188+
StringRef moduleName,
189+
llvm::SmallString<256> &scratch) {
190+
llvm::SmallString<64> modulePath = llvm::sys::path::filename(interfacePath);
191+
llvm::sys::path::replace_extension(modulePath,
192+
file_types::getExtension(file_types::TY_SwiftModuleFile));
193+
auto defaultPath =
194+
computePrebuiltModulePathDefault(ctx, interfacePath, prebuiltCacheDir,
195+
moduleName, modulePath, scratch);
196+
if (defaultPath.hasValue())
197+
return defaultPath;
198+
else
199+
return computeFallbackPrebuiltModulePath(ctx, interfacePath,
200+
prebuiltCacheDir,
201+
moduleName,
202+
modulePath,
203+
scratch);
204+
}
205+
97206
ErrorOr<ModuleDependencies> ModuleDependencyScanner::scanInterfaceFile(
98207
Twine moduleInterfacePath) {
99208
// Create a module filename.

0 commit comments

Comments
 (0)