Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / tools / dsymutil / Reproducer.cpp
bloba6cc10424dc524e5f21d5c06c78c6f061ab2d61a
1 //===- Reproducer.cpp -----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "Reproducer.h"
10 #include "llvm/Support/Path.h"
11 #include "llvm/Support/Process.h"
13 using namespace llvm;
14 using namespace llvm::dsymutil;
16 static std::string createReproducerDir(std::error_code &EC) {
17 SmallString<128> Root;
18 if (const char *Path = getenv("DSYMUTIL_REPRODUCER_PATH")) {
19 Root.assign(Path);
20 EC = sys::fs::create_directories(Root);
21 } else if (const char *Path = getenv("LLVM_DIAGNOSTIC_DIR")) {
22 Root.assign(Path);
23 llvm::sys::path::append(
24 Root, "dsymutil-" + llvm::Twine(llvm::sys::Process::getProcessId()));
25 EC = sys::fs::create_directories(Root);
26 } else {
27 EC = sys::fs::createUniqueDirectory("dsymutil", Root);
29 sys::fs::make_absolute(Root);
30 return EC ? "" : std::string(Root);
33 Reproducer::Reproducer() : VFS(vfs::getRealFileSystem()) {}
34 Reproducer::~Reproducer() = default;
36 ReproducerGenerate::ReproducerGenerate(std::error_code &EC, int Argc,
37 char **Argv, bool GenerateOnExit)
38 : Root(createReproducerDir(EC)), GenerateOnExit(GenerateOnExit) {
39 for (int I = 0; I < Argc; ++I)
40 Args.push_back(Argv[I]);
41 if (!Root.empty())
42 FC = std::make_shared<FileCollector>(Root, Root);
43 VFS = FileCollector::createCollectorVFS(vfs::getRealFileSystem(), FC);
46 ReproducerGenerate::~ReproducerGenerate() {
47 if (GenerateOnExit && !Generated)
48 generate();
49 else if (!Generated && !Root.empty())
50 sys::fs::remove_directories(Root, /* IgnoreErrors */ true);
53 void ReproducerGenerate::generate() {
54 if (!FC)
55 return;
56 Generated = true;
57 FC->copyFiles(false);
58 SmallString<128> Mapping(Root);
59 sys::path::append(Mapping, "mapping.yaml");
60 FC->writeMapping(Mapping.str());
61 errs() << "********************\n";
62 errs() << "Reproducer written to " << Root << '\n';
63 errs() << "Please include the reproducer and the following invocation in "
64 "your bug report:\n";
65 for (llvm::StringRef Arg : Args)
66 errs() << Arg << ' ';
67 errs() << "--use-reproducer " << Root << '\n';
68 errs() << "********************\n";
71 ReproducerUse::~ReproducerUse() = default;
73 ReproducerUse::ReproducerUse(StringRef Root, std::error_code &EC) {
74 SmallString<128> Mapping(Root);
75 sys::path::append(Mapping, "mapping.yaml");
76 ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
77 vfs::getRealFileSystem()->getBufferForFile(Mapping.str());
79 if (!Buffer) {
80 EC = Buffer.getError();
81 return;
84 VFS = llvm::vfs::getVFSFromYAML(std::move(Buffer.get()), nullptr, Mapping);
87 llvm::Expected<std::unique_ptr<Reproducer>>
88 Reproducer::createReproducer(ReproducerMode Mode, StringRef Root, int Argc,
89 char **Argv) {
91 std::error_code EC;
92 std::unique_ptr<Reproducer> Repro;
93 switch (Mode) {
94 case ReproducerMode::GenerateOnExit:
95 Repro = std::make_unique<ReproducerGenerate>(EC, Argc, Argv, true);
96 break;
97 case ReproducerMode::GenerateOnCrash:
98 Repro = std::make_unique<ReproducerGenerate>(EC, Argc, Argv, false);
99 break;
100 case ReproducerMode::Use:
101 Repro = std::make_unique<ReproducerUse>(Root, EC);
102 break;
103 case ReproducerMode::Off:
104 Repro = std::make_unique<Reproducer>();
105 break;
107 if (EC)
108 return errorCodeToError(EC);
109 return {std::move(Repro)};