[Caching] Improve diagnostics around swift caching

Improve diagnostics message for swift caching build by trying to emit
the diagnostics early when there is more context to differentiate the
different kind of problems.

After the improvement, CAS Error should be more closer to when there is
functional problem with the CAS, rather than mixing in other kinds of
problem (like scanning dependency failures) when operating with a CAS.

rdar://145676736
(cherry picked from commit 226552bf23)
This commit is contained in:
Steven Wu
2025-04-08 15:57:33 -07:00
parent f6a864a188
commit edb94fb2fb
9 changed files with 178 additions and 127 deletions

View File

@@ -525,7 +525,13 @@ REMARK(replay_output, none, "replay output file '%0': key '%1'", (StringRef, Str
REMARK(output_cache_miss, none, "cache miss for input file '%0': key '%1'", (StringRef, StringRef))
// CAS related diagnostics
ERROR(error_cas, none, "CAS error encountered: %0", (StringRef))
ERROR(error_invalid_cas_id, none, "CAS cannot parse id '%0': %1", (StringRef, StringRef))
ERROR(error_cas, none, "CAS error encountered during %0: %1", (StringRef, StringRef))
ERROR(error_cas_fs_creation, none, "cannot create CAS filesystem: %0", (StringRef))
ERROR(error_cache_key_creation, none, "cannot create cache key for compilation %0: %1", (StringRef, StringRef))
ERROR(error_cas_file_ref, none, "cannot load file %0 from CAS filesystem", (StringRef))
ERROR(error_cas_conflict_options, none, "cannot setup CAS due to conflicting '-cas-*' options", ())
ERROR(error_cas_initialization, none, "CAS cannot be initialized from the specified '-cas-*' options: %0", (StringRef))
WARNING(cache_replay_failed, none, "cache replay failed: %0", (StringRef))
ERROR(error_failed_cached_diag, none, "failed to serialize cached diagnostics: %0", (StringRef))

View File

@@ -680,8 +680,11 @@ SwiftDependencyTracker::createTreeFromDependencies() {
for (auto &file : TrackedFiles) {
auto includeTreeFile = clang::cas::IncludeTree::File::create(
FS->getCAS(), file.first, file.second.FileRef);
if (!includeTreeFile)
return includeTreeFile.takeError();
if (!includeTreeFile) {
return llvm::createStringError("CASFS createTree failed for " +
file.first + ": " +
toString(includeTreeFile.takeError()));
}
Files.push_back(
{includeTreeFile->getRef(),
(clang::cas::IncludeTree::FileList::FileSizeTy)file.second.Size});
@@ -690,7 +693,8 @@ SwiftDependencyTracker::createTreeFromDependencies() {
auto includeTreeList =
clang::cas::IncludeTree::FileList::create(FS->getCAS(), Files, {});
if (!includeTreeList)
return includeTreeList.takeError();
return llvm::createStringError("casfs include-tree filelist error: " +
toString(includeTreeList.takeError()));
return *includeTreeList;
}
@@ -706,9 +710,7 @@ bool SwiftDependencyScanningService::setupCachingDependencyScanningService(
return false;
// CASOption mismatch, return error.
Instance.getDiags().diagnose(
SourceLoc(), diag::error_cas,
"conflicting CAS options used in scanning service");
Instance.getDiags().diagnose(SourceLoc(), diag::error_cas_conflict_options);
return true;
}
@@ -720,7 +722,7 @@ bool SwiftDependencyScanningService::setupCachingDependencyScanningService(
auto CachingFS =
llvm::cas::createCachingOnDiskFileSystem(Instance.getObjectStore());
if (!CachingFS) {
Instance.getDiags().diagnose(SourceLoc(), diag::error_cas,
Instance.getDiags().diagnose(SourceLoc(), diag::error_cas_fs_creation,
toString(CachingFS.takeError()));
return true;
}

View File

@@ -90,16 +90,16 @@ public:
commandline = resolvingDepInfo.getCommandline();
}
llvm::Error
resolve(const std::set<ModuleDependencyID> &dependencies,
std::optional<std::set<ModuleDependencyID>> bridgingHeaderDeps) {
// Resolve the dependencies for the current moduleID. Return true on error.
bool resolve(const std::set<ModuleDependencyID> &dependencies,
std::optional<std::set<ModuleDependencyID>> bridgingHeaderDeps) {
// No need to resolve dependency for placeholder.
if (moduleID.Kind == ModuleDependencyKind::SwiftPlaceholder)
return llvm::Error::success();
return false;
// If the dependency is already finalized, nothing needs to be done.
if (resolvingDepInfo.isFinalized())
return llvm::Error::success();
return false;
if (auto ID = resolvingDepInfo.getClangIncludeTree())
includeTrees.push_back(*ID);
@@ -110,37 +110,34 @@ public:
case swift::ModuleDependencyKind::SwiftInterface: {
auto interfaceDepDetails = depInfo.getAsSwiftInterfaceModule();
assert(interfaceDepDetails && "Expected Swift Interface dependency.");
if (auto err = handleSwiftInterfaceModuleDependency(
depModuleID, *interfaceDepDetails))
return err;
if (handleSwiftInterfaceModuleDependency(depModuleID,
*interfaceDepDetails))
return true;
} break;
case swift::ModuleDependencyKind::SwiftBinary: {
auto binaryDepDetails = depInfo.getAsSwiftBinaryModule();
assert(binaryDepDetails && "Expected Swift Binary Module dependency.");
if (auto err = handleSwiftBinaryModuleDependency(depModuleID,
*binaryDepDetails))
return err;
if (handleSwiftBinaryModuleDependency(depModuleID, *binaryDepDetails))
return true;
} break;
case swift::ModuleDependencyKind::SwiftPlaceholder: {
auto placeholderDetails = depInfo.getAsPlaceholderDependencyModule();
assert(placeholderDetails && "Expected Swift Placeholder dependency.");
if (auto err = handleSwiftPlaceholderModuleDependency(
depModuleID, *placeholderDetails))
return err;
if (handleSwiftPlaceholderModuleDependency(depModuleID,
*placeholderDetails))
return true;
} break;
case swift::ModuleDependencyKind::Clang: {
auto clangDepDetails = depInfo.getAsClangModule();
assert(clangDepDetails && "Expected Clang Module dependency.");
if (auto err =
handleClangModuleDependency(depModuleID, *clangDepDetails))
return err;
if (handleClangModuleDependency(depModuleID, *clangDepDetails))
return true;
} break;
case swift::ModuleDependencyKind::SwiftSource: {
auto sourceDepDetails = depInfo.getAsSwiftSourceModule();
assert(sourceDepDetails && "Expected Swift Source Module dependency.");
if (auto err = handleSwiftSourceModuleDependency(depModuleID,
*sourceDepDetails))
return err;
if (handleSwiftSourceModuleDependency(depModuleID, *sourceDepDetails))
return true;
} break;
default:
llvm_unreachable("Unhandled dependency kind.");
@@ -149,8 +146,9 @@ public:
// Update bridging header build command if there is a bridging header
// dependency.
if (auto E = addBridgingHeaderDeps(resolvingDepInfo))
return E;
if (addBridgingHeaderDeps(resolvingDepInfo))
return true;
if (bridgingHeaderDeps) {
bridgingHeaderBuildCmd =
resolvingDepInfo.getBridgingHeaderCommandline();
@@ -188,21 +186,21 @@ public:
}
auto dependencyInfoCopy = resolvingDepInfo;
if (auto err = finalize(dependencyInfoCopy, swiftInterfaceOutputPath))
return err;
if (finalize(dependencyInfoCopy, swiftInterfaceOutputPath))
return true;
dependencyInfoCopy.setIsFinalized(true);
cache.updateDependency(moduleID, dependencyInfoCopy);
return llvm::Error::success();
return false;
}
private:
// Finalize the resolving dependency info.
llvm::Error finalize(ModuleDependencyInfo &depInfo,
const SwiftInterfaceModuleOutputPathResolution::ResultTy
&swiftInterfaceModuleOutputPath) {
bool finalize(ModuleDependencyInfo &depInfo,
const SwiftInterfaceModuleOutputPathResolution::ResultTy
&swiftInterfaceModuleOutputPath) {
if (resolvingDepInfo.isSwiftPlaceholderModule())
return llvm::Error::success();
return false;
if (resolvingDepInfo.isSwiftInterfaceModule())
depInfo.setOutputPathAndHash(
@@ -243,14 +241,14 @@ private:
depInfo.updateBridgingHeaderCommandLine(bridgingHeaderBuildCmd);
if (!resolvingDepInfo.isSwiftBinaryModule()) {
depInfo.updateCommandLine(commandline);
if (auto err = updateModuleCacheKey(depInfo))
return err;
if (updateModuleCacheKey(depInfo))
return true;
}
return llvm::Error::success();
return false;
}
llvm::Error handleSwiftInterfaceModuleDependency(
bool handleSwiftInterfaceModuleDependency(
ModuleDependencyID depModuleID,
const SwiftInterfaceModuleDependenciesStorage &interfaceDepDetails) {
if (!resolvingDepInfo.isSwiftSourceModule()) {
@@ -261,10 +259,10 @@ private:
"=" + path);
}
addMacroDependencies(depModuleID, interfaceDepDetails);
return llvm::Error::success();
return false;
}
llvm::Error handleSwiftBinaryModuleDependency(
bool handleSwiftBinaryModuleDependency(
ModuleDependencyID depModuleID,
const SwiftBinaryModuleDependencyStorage &binaryDepDetails) {
if (!resolvingDepInfo.isSwiftSourceModule()) {
@@ -290,19 +288,19 @@ private:
}
}
addMacroDependencies(depModuleID, binaryDepDetails);
return llvm::Error::success();
return false;
}
llvm::Error handleSwiftPlaceholderModuleDependency(
bool handleSwiftPlaceholderModuleDependency(
ModuleDependencyID depModuleID,
const SwiftPlaceholderModuleDependencyStorage &placeholderDetails) {
if (!resolvingDepInfo.isSwiftSourceModule())
commandline.push_back("-swift-module-file=" + depModuleID.ModuleName +
"=" + placeholderDetails.compiledModulePath);
return llvm::Error::success();
return false;
}
llvm::Error handleClangModuleDependency(
bool handleClangModuleDependency(
ModuleDependencyID depModuleID,
const ClangModuleDependencyStorage &clangDepDetails) {
if (!resolvingDepInfo.isSwiftSourceModule()) {
@@ -329,25 +327,25 @@ private:
collectUsedVFSOverlay(clangDepDetails);
return llvm::Error::success();
return false;
}
llvm::Error handleSwiftSourceModuleDependency(
bool handleSwiftSourceModuleDependency(
ModuleDependencyID depModuleID,
const SwiftSourceModuleDependenciesStorage &sourceDepDetails) {
addMacroDependencies(depModuleID, sourceDepDetails);
return addBridgingHeaderDeps(sourceDepDetails);
}
llvm::Error addBridgingHeaderDeps(const ModuleDependencyInfo &depInfo) {
bool addBridgingHeaderDeps(const ModuleDependencyInfo &depInfo) {
auto sourceDepDetails = depInfo.getAsSwiftSourceModule();
if (!sourceDepDetails)
return llvm::Error::success();
return false;
return addBridgingHeaderDeps(*sourceDepDetails);
}
llvm::Error addBridgingHeaderDeps(
bool addBridgingHeaderDeps(
const SwiftSourceModuleDependenciesStorage &sourceDepDetails) {
if (sourceDepDetails.textualModuleDetails.CASBridgingHeaderIncludeTreeRootID
.empty()) {
@@ -359,14 +357,14 @@ private:
tracker->trackFile(file);
auto bridgeRoot = tracker->createTreeFromDependencies();
if (!bridgeRoot)
return bridgeRoot.takeError();
return diagnoseCASFSCreationError(bridgeRoot.takeError());
fileListIDs.push_back(bridgeRoot->getID().toString());
}
}
} else
includeTrees.push_back(sourceDepDetails.textualModuleDetails
.CASBridgingHeaderIncludeTreeRootID);
return llvm::Error::success();
return false;
};
void addMacroDependencies(ModuleDependencyID moduleID,
@@ -481,9 +479,9 @@ private:
return;
}
llvm::Error collectCASDependencies(ModuleDependencyInfo &dependencyInfoCopy) {
bool collectCASDependencies(ModuleDependencyInfo &dependencyInfoCopy) {
if (!instance.getInvocation().getCASOptions().EnableCaching)
return llvm::Error::success();
return false;
// Collect CAS info from current resolving module.
if (auto *sourceDep = resolvingDepInfo.getAsSwiftSourceModule()) {
@@ -500,7 +498,7 @@ private:
});
auto root = tracker->createTreeFromDependencies();
if (!root)
return root.takeError();
return diagnoseCASFSCreationError(root.takeError());
auto rootID = root->getID().toString();
dependencyInfoCopy.updateCASFileSystemRootID(rootID);
fileListIDs.push_back(rootID);
@@ -517,7 +515,7 @@ private:
});
auto root = tracker->createTreeFromDependencies();
if (!root)
return root.takeError();
return diagnoseCASFSCreationError(root.takeError());
auto rootID = root->getID().toString();
dependencyInfoCopy.updateCASFileSystemRootID(rootID);
fileListIDs.push_back(rootID);
@@ -545,16 +543,16 @@ private:
// Compute and update module cache key.
if (auto *binaryDep = dependencyInfoCopy.getAsSwiftBinaryModule()) {
if (auto E = setupBinaryCacheKey(binaryDep->compiledModulePath,
dependencyInfoCopy))
return E;
if (setupBinaryCacheKey(binaryDep->compiledModulePath,
dependencyInfoCopy))
return true;
}
return llvm::Error::success();
return false;
}
llvm::Error updateModuleCacheKey(ModuleDependencyInfo &depInfo) {
bool updateModuleCacheKey(ModuleDependencyInfo &depInfo) {
if (!instance.getInvocation().getCASOptions().EnableCaching)
return llvm::Error::success();
return false;
auto &CAS = cache.getScanService().getCAS();
auto commandLine = depInfo.getCommandline();
@@ -564,40 +562,67 @@ private:
Args.push_back(c.c_str());
auto base = createCompileJobBaseCacheKey(CAS, Args);
if (!base)
return base.takeError();
if (!base) {
instance.getDiags().diagnose(SourceLoc(), diag::error_cache_key_creation,
moduleID.ModuleName,
toString(base.takeError()));
return true;
}
// Module compilation commands always have only one input and the input
// index is always 0.
auto key = createCompileJobCacheKeyForOutput(CAS, *base, /*InputIndex=*/0);
if (!key)
return key.takeError();
if (!key) {
instance.getDiags().diagnose(SourceLoc(), diag::error_cache_key_creation,
moduleID.ModuleName,
toString(key.takeError()));
return true;
}
depInfo.updateModuleCacheKey(CAS.getID(*key).toString());
return llvm::Error::success();
return false;
}
llvm::Error setupBinaryCacheKey(StringRef path,
ModuleDependencyInfo &depInfo) {
bool setupBinaryCacheKey(StringRef path, ModuleDependencyInfo &depInfo) {
auto &CASFS = cache.getScanService().getSharedCachingFS();
auto &CAS = cache.getScanService().getCAS();
// For binary module, we need to make sure the lookup key is setup here in
// action cache. We just use the CASID of the binary module itself as key.
auto Ref = CASFS.getObjectRefForFileContent(path);
if (!Ref)
return llvm::errorCodeToError(Ref.getError());
if (!Ref) {
instance.getDiags().diagnose(SourceLoc(), diag::error_cas_file_ref, path);
return true;
}
assert(*Ref && "Binary module should be loaded into CASFS already");
depInfo.updateModuleCacheKey(CAS.getID(**Ref).toString());
swift::cas::CompileJobCacheResult::Builder Builder;
Builder.addOutput(file_types::ID::TY_SwiftModuleFile, **Ref);
auto Result = Builder.build(CAS);
if (!Result)
return Result.takeError();
if (auto E =
instance.getActionCache().put(CAS.getID(**Ref), CAS.getID(*Result)))
return E;
return llvm::Error::success();
if (!Result) {
instance.getDiags().diagnose(SourceLoc(), diag::error_cas,
"adding binary module dependencies",
toString(Result.takeError()));
return true;
}
if (auto E = instance.getActionCache().put(CAS.getID(**Ref),
CAS.getID(*Result))) {
instance.getDiags().diagnose(
SourceLoc(), diag::error_cas,
"adding binary module dependencies cache entry",
toString(std::move(E)));
return true;
}
return false;
}
bool diagnoseCASFSCreationError(llvm::Error err) {
if (!err)
return false;
instance.getDiags().diagnose(SourceLoc(), diag::error_cas_fs_creation,
toString(std::move(err)));
return true;
}
void addDeterministicCheckFlags(std::vector<std::string> &cmd) {
@@ -627,7 +652,7 @@ private:
llvm::StringSet<> usedVFSOverlayPaths;
};
static llvm::Error resolveExplicitModuleInputs(
static bool resolveExplicitModuleInputs(
const ModuleDependencyID &moduleID,
const std::set<ModuleDependencyID> &dependencies,
ModuleDependenciesCache &cache, CompilerInstance &instance,
@@ -1272,7 +1297,7 @@ swift::dependencies::createEncodedModuleKindAndName(ModuleDependencyID id) {
}
}
static void resolveDependencyCommandLineArguments(
static bool resolveDependencyCommandLineArguments(
CompilerInstance &instance, ModuleDependenciesCache &cache,
const std::vector<ModuleDependencyID> &topoSortedModuleList) {
auto moduleTransitiveClosures =
@@ -1291,12 +1316,12 @@ static void resolveDependencyCommandLineArguments(
bridgingHeaderDeps = computeBridgingHeaderTransitiveDependencies(
deps, moduleTransitiveClosures, cache);
if (auto E =
resolveExplicitModuleInputs(modID, dependencyClosure, cache,
instance, bridgingHeaderDeps, tracker))
instance.getDiags().diagnose(SourceLoc(), diag::error_cas,
toString(std::move(E)));
if (resolveExplicitModuleInputs(modID, dependencyClosure, cache, instance,
bridgingHeaderDeps, tracker))
return true;
}
return false;
}
static void

View File

@@ -251,7 +251,8 @@ private:
auto BaseKey = Instance.getCompilerBaseKey();
if (!BaseKey) {
Instance.getDiags().diagnose(SourceLoc(), diag::error_cas,
"Base Key doesn't exist");
"query base cache key",
"base cache key doesn't exist");
return std::nullopt;
}

View File

@@ -868,7 +868,7 @@ CachingDiagnosticsProcessor::CachingDiagnosticsProcessor(
if (Err) {
Instance.getDiags().diagnose(SourceLoc(), diag::error_cas,
toString(std::move(Err)));
"storing outputs", toString(std::move(Err)));
return true;
}

View File

@@ -340,7 +340,7 @@ bool replayCachedCompilerOutputs(
createCompileJobCacheKeyForOutput(CAS, BaseKey, InputIndex);
if (!OutputKey) {
Diag.diagnose(SourceLoc(), diag::error_cas,
Diag.diagnose(SourceLoc(), diag::error_cas, "output cache key creation",
toString(OutputKey.takeError()));
return std::nullopt;
}
@@ -348,7 +348,7 @@ bool replayCachedCompilerOutputs(
auto OutID = CAS.getID(*OutputKey);
auto OutputRef = lookupCacheKey(CAS, Cache, *OutputKey);
if (!OutputRef) {
Diag.diagnose(SourceLoc(), diag::error_cas,
Diag.diagnose(SourceLoc(), diag::error_cas, "cache key lookup",
toString(OutputRef.takeError()));
return std::nullopt;
}
@@ -403,20 +403,24 @@ std::unique_ptr<llvm::MemoryBuffer>
loadCachedCompileResultFromCacheKey(ObjectStore &CAS, ActionCache &Cache,
DiagnosticEngine &Diag, StringRef CacheKey,
file_types::ID Kind, StringRef Filename) {
auto failure = [&](Error Err) {
Diag.diagnose(SourceLoc(), diag::error_cas, toString(std::move(Err)));
auto failure = [&](StringRef Stage, Error Err) {
Diag.diagnose(SourceLoc(), diag::error_cas, Stage,
toString(std::move(Err)));
return nullptr;
};
auto ID = CAS.parseID(CacheKey);
if (!ID)
return failure(ID.takeError());
if (!ID) {
Diag.diagnose(SourceLoc(), diag::error_invalid_cas_id, CacheKey,
toString(ID.takeError()));
return nullptr;
}
auto Ref = CAS.getReference(*ID);
if (!Ref)
return nullptr;
auto OutputRef = lookupCacheKey(CAS, Cache, *Ref);
if (!OutputRef)
return failure(OutputRef.takeError());
return failure("lookup cache key", OutputRef.takeError());
if (!*OutputRef)
return nullptr;
@@ -435,7 +439,7 @@ loadCachedCompileResultFromCacheKey(ObjectStore &CAS, ActionCache &Cache,
Buffer = Proxy->getMemoryBuffer(Filename);
return Error::success();
}))
return failure(std::move(Err));
return failure("loading cached results", std::move(Err));
return Buffer;
}

View File

@@ -456,7 +456,7 @@ bool CompilerInstance::setupCASIfNeeded(ArrayRef<const char *> Args) {
const auto &Opts = getInvocation().getCASOptions();
auto MaybeDB= Opts.CASOpts.getOrCreateDatabases();
if (!MaybeDB) {
Diagnostics.diagnose(SourceLoc(), diag::error_cas,
Diagnostics.diagnose(SourceLoc(), diag::error_cas_initialization,
toString(MaybeDB.takeError()));
return true;
}
@@ -466,6 +466,7 @@ bool CompilerInstance::setupCASIfNeeded(ArrayRef<const char *> Args) {
auto BaseKey = createCompileJobBaseCacheKey(*CAS, Args);
if (!BaseKey) {
Diagnostics.diagnose(SourceLoc(), diag::error_cas,
"creating base cache key",
toString(BaseKey.takeError()));
return true;
}
@@ -636,7 +637,7 @@ bool CompilerInstance::setUpVirtualFileSystemOverlays() {
CASOpts.ClangIncludeTrees,
CASOpts.ClangIncludeTreeFileList);
if (!FS) {
Diagnostics.diagnose(SourceLoc(), diag::error_cas,
Diagnostics.diagnose(SourceLoc(), diag::error_cas_fs_creation,
toString(FS.takeError()));
return true;
}

View File

@@ -221,6 +221,7 @@ bool swift::emitMakeDependenciesIfNeeded(CompilerInstance &instance,
if (auto err = CASBackend.storeMakeDependenciesFile(dependenciesFilePath,
buffer)) {
instance.getDiags().diagnose(SourceLoc(), diag::error_cas,
"storing make-style dependency file",
toString(std::move(err)));
return true;
}

View File

@@ -2466,18 +2466,25 @@ struct ExplicitCASModuleLoader::Implementation {
llvm::cas::ActionCache &Cache)
: Ctx(Ctx), CAS(CAS), Cache(Cache) {}
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> loadBuffer(StringRef ID) {
std::unique_ptr<llvm::MemoryBuffer> loadBuffer(StringRef ID) {
auto key = CAS.parseID(ID);
if (!key)
return key.takeError();
if (!key) {
Ctx.Diags.diagnose(SourceLoc(), diag::error_invalid_cas_id, ID,
toString(key.takeError()));
return nullptr;
}
auto ref = CAS.getReference(*key);
if (!ref)
return nullptr;
auto loaded = CAS.getProxy(*ref);
if (!loaded)
return loaded.takeError();
if (!loaded) {
Ctx.Diags.diagnose(SourceLoc(), diag::error_cas,
"loading module map from CAS",
toString(loaded.takeError()));
return nullptr;
}
return loaded->getMemoryBuffer();
}
@@ -2490,11 +2497,6 @@ struct ExplicitCASModuleLoader::Implementation {
llvm::StringMap<std::string> ModuleAliases;
auto buf = loadBuffer(ID);
if (!buf) {
Ctx.Diags.diagnose(SourceLoc(), diag::error_cas,
toString(buf.takeError()));
return;
}
if (!*buf) {
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_missing,
ID);
return;
@@ -2503,7 +2505,7 @@ struct ExplicitCASModuleLoader::Implementation {
llvm::MemoryBuffer::getFile(ID);
auto hasError = parser.parseSwiftExplicitModuleMap(
(*buf)->getMemBufferRef(), ExplicitModuleMap, ExplicitClangModuleMap,
buf->getMemBufferRef(), ExplicitModuleMap, ExplicitClangModuleMap,
ModuleAliases);
if (hasError)
@@ -2555,41 +2557,54 @@ struct ExplicitCASModuleLoader::Implementation {
}
}
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
loadFileBuffer(StringRef ID, StringRef Name) {
std::unique_ptr<llvm::MemoryBuffer>
loadFileBuffer(SourceLoc Loc, StringRef ID, StringRef Name) {
auto outputMissing = [&]() {
Ctx.Diags.diagnose(Loc, diag::error_opening_explicit_module_file, Name);
return nullptr;
};
auto casError = [&](StringRef Stage, llvm::Error Err) {
Ctx.Diags.diagnose(Loc, diag::error_cas, Stage, toString(std::move(Err)));
return nullptr;
};
auto key = CAS.parseID(ID);
if (!key)
return key.takeError();
if (!key) {
Ctx.Diags.diagnose(Loc, diag::error_invalid_cas_id, ID,
toString(key.takeError()));
return nullptr;
}
auto moduleLookup = Cache.get(*key);
if (!moduleLookup)
return moduleLookup.takeError();
return casError("looking up module output cache",
moduleLookup.takeError());
if (!*moduleLookup)
return nullptr;
return outputMissing();
auto moduleRef = CAS.getReference(**moduleLookup);
if (!moduleRef)
return nullptr;
return outputMissing();
auto proxy = CAS.getProxy(*moduleRef);
if (!proxy)
return proxy.takeError();
return casError("loading module build outputs", proxy.takeError());
swift::cas::CompileJobResultSchema schema(CAS);
if (!schema.isRootNode(*proxy))
return nullptr;
return outputMissing();
auto result = schema.load(*moduleRef);
if (!result)
return result.takeError();
return casError("loading module schema", result.takeError());
auto output = result->getOutput(file_types::ID::TY_SwiftModuleFile);
if (!output)
return nullptr;
return outputMissing();
auto buf = CAS.getProxy(output->Object);
if (!buf)
return buf.takeError();
return casError("loading dependency module", result.takeError());
return buf->getMemoryBuffer(Name);
}
@@ -2750,18 +2765,14 @@ bool ExplicitCASModuleLoader::canImportModule(
std::string moduleCASID = it->second.moduleCacheKey
? *it->second.moduleCacheKey
: it->second.modulePath;
auto moduleBuf = Impl.loadFileBuffer(moduleCASID, it->second.modulePath);
auto moduleBuf = Impl.loadFileBuffer(loc, moduleCASID, it->second.modulePath);
if (!moduleBuf) {
Ctx.Diags.diagnose(loc, diag::error_cas, toString(moduleBuf.takeError()));
return false;
}
if (!*moduleBuf) {
Ctx.Diags.diagnose(loc, diag::error_opening_explicit_module_file,
it->second.modulePath);
return false;
}
auto metaData = serialization::validateSerializedAST(
(*moduleBuf)->getBuffer(), Ctx.SILOpts.EnableOSSAModules,
moduleBuf->getBuffer(), Ctx.SILOpts.EnableOSSAModules,
Ctx.LangOpts.SDKName);
versionInfo->setVersion(metaData.userModuleVersion,
ModuleVersionSourceKind::SwiftBinaryModule);