| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 
 | //===- 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<FileCollector>(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<std::unique_ptr<MemoryBuffer>> Buffer =
      vfs::getRealFileSystem()->getBufferForFile(Mapping.str());
  if (!Buffer) {
    EC = Buffer.getError();
    return;
  }
  VFS = llvm::vfs::getVFSFromYAML(std::move(Buffer.get()), nullptr, Mapping);
}
llvm::Expected<std::unique_ptr<Reproducer>>
Reproducer::createReproducer(ReproducerMode Mode, StringRef Root) {
  switch (Mode) {
  case ReproducerMode::Generate: {
    std::error_code EC;
    std::unique_ptr<Reproducer> Repro =
        std::make_unique<ReproducerGenerate>(EC);
    if (EC)
      return errorCodeToError(EC);
    return std::move(Repro);
  }
  case ReproducerMode::Use: {
    std::error_code EC;
    std::unique_ptr<Reproducer> Repro =
        std::make_unique<ReproducerUse>(Root, EC);
    if (EC)
      return errorCodeToError(EC);
    return std::move(Repro);
  }
  case ReproducerMode::Off:
    return std::make_unique<Reproducer>();
  }
  llvm_unreachable("All cases handled above.");
}
 |