//===- Reproducer.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "Reproducer.h" #include "llvm/Support/Path.h" using namespace llvm; using namespace llvm::dsymutil; static std::string createReproducerDir(std::error_code &EC) { SmallString<128> Root; if (const char *Path = getenv("DSYMUTIL_REPRODUCER_PATH")) { Root.assign(Path); EC = sys::fs::create_directory(Root); } else { EC = sys::fs::createUniqueDirectory("dsymutil", Root); } return EC ? "" : std::string(Root); } Reproducer::Reproducer() : VFS(vfs::getRealFileSystem()) {} Reproducer::~Reproducer() = default; ReproducerGenerate::ReproducerGenerate(std::error_code &EC) : Root(createReproducerDir(EC)), FC() { if (!Root.empty()) FC = std::make_shared(Root, Root); VFS = FileCollector::createCollectorVFS(vfs::getRealFileSystem(), FC); } ReproducerGenerate::~ReproducerGenerate() { if (!FC) return; FC->copyFiles(false); SmallString<128> Mapping(Root); sys::path::append(Mapping, "mapping.yaml"); FC->writeMapping(Mapping.str()); outs() << "reproducer written to " << Root << '\n'; } ReproducerUse::~ReproducerUse() = default; ReproducerUse::ReproducerUse(StringRef Root, std::error_code &EC) { SmallString<128> Mapping(Root); sys::path::append(Mapping, "mapping.yaml"); ErrorOr> Buffer = vfs::getRealFileSystem()->getBufferForFile(Mapping.str()); if (!Buffer) { EC = Buffer.getError(); return; } VFS = llvm::vfs::getVFSFromYAML(std::move(Buffer.get()), nullptr, Mapping); } llvm::Expected> Reproducer::createReproducer(ReproducerMode Mode, StringRef Root) { switch (Mode) { case ReproducerMode::Generate: { std::error_code EC; std::unique_ptr Repro = std::make_unique(EC); if (EC) return errorCodeToError(EC); return std::move(Repro); } case ReproducerMode::Use: { std::error_code EC; std::unique_ptr Repro = std::make_unique(Root, EC); if (EC) return errorCodeToError(EC); return std::move(Repro); } case ReproducerMode::Off: return std::make_unique(); } llvm_unreachable("All cases handled above."); }