//===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//

#include "llvm/LTO/legacy/LTOCodeGenerator.h"

#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/config.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassTimingInfo.h"
#include "llvm/IR/Verifier.h"
#include "llvm/LTO/LTO.h"
#include "llvm/LTO/LTOBackend.h"
#include "llvm/LTO/legacy/LTOModule.h"
#include "llvm/LTO/legacy/UpdateCompilerUsed.h"
#include "llvm/Linker/Linker.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Remarks/HotnessThresholdParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/Internalize.h"
#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <optional>
#include <system_error>
using namespace llvm;

const char* LTOCodeGenerator::getVersionString() {
  return PACKAGE_NAME " version " PACKAGE_VERSION;
}

namespace llvm {
cl::opt<bool> LTODiscardValueNames(
    "lto-discard-value-names",
    cl::desc("Strip names from Value during LTO (other than GlobalValue)."),
#ifdef NDEBUG
    cl::init(true),
#else
    cl::init(false),
#endif
    cl::Hidden);

cl::opt<bool> RemarksWithHotness(
    "lto-pass-remarks-with-hotness",
    cl::desc("With PGO, include profile count in optimization remarks"),
    cl::Hidden);

cl::opt<std::optional<uint64_t>, false, remarks::HotnessThresholdParser>
    RemarksHotnessThreshold(
        "lto-pass-remarks-hotness-threshold",
        cl::desc("Minimum profile count required for an "
                 "optimization remark to be output."
                 " Use 'auto' to apply the threshold from profile summary."),
        cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden);

cl::opt<std::string>
    RemarksFilename("lto-pass-remarks-output",
                    cl::desc("Output filename for pass remarks"),
                    cl::value_desc("filename"));

cl::opt<std::string>
    RemarksPasses("lto-pass-remarks-filter",
                  cl::desc("Only record optimization remarks from passes whose "
                           "names match the given regular expression"),
                  cl::value_desc("regex"));

cl::opt<std::string> RemarksFormat(
    "lto-pass-remarks-format",
    cl::desc("The format used for serializing remarks (default: YAML)"),
    cl::value_desc("format"), cl::init("yaml"));

static cl::opt<std::string>
    LTOStatsFile("lto-stats-file",
                 cl::desc("Save statistics to the specified file"), cl::Hidden);

static cl::opt<std::string> AIXSystemAssemblerPath(
    "lto-aix-system-assembler",
    cl::desc("Path to a system assembler, picked up on AIX only"),
    cl::value_desc("path"));

cl::opt<bool>
    LTORunCSIRInstr("cs-profile-generate",
                    cl::desc("Perform context sensitive PGO instrumentation"));

cl::opt<std::string>
    LTOCSIRProfile("cs-profile-path",
                   cl::desc("Context sensitive profile file path"));

extern cl::opt<std::string> SampleProfileFile;
} // namespace llvm

LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
    : Context(Context), MergedModule(new Module("ld-temp.o", Context)),
      TheLinker(new Linker(*MergedModule)) {
  Context.setDiscardValueNames(LTODiscardValueNames);
  Context.enableDebugTypeODRUniquing();

  Config.CodeModel = std::nullopt;
  Config.StatsFile = LTOStatsFile;
  Config.RunCSIRInstr = LTORunCSIRInstr;
  Config.CSIRProfile = LTOCSIRProfile;
}

LTOCodeGenerator::~LTOCodeGenerator() = default;

void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
  AsmUndefinedRefs.insert_range(Mod->getAsmUndefinedRefs());
}

bool LTOCodeGenerator::addModule(LTOModule *Mod) {
  assert(&Mod->getModule().getContext() == &Context &&
         "Expected module in same context");

  bool ret = TheLinker->linkInModule(Mod->takeModule());
  setAsmUndefinedRefs(Mod);

  // We've just changed the input, so let's make sure we verify it.
  HasVerifiedInput = false;

  return !ret;
}

void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) {
  assert(&Mod->getModule().getContext() == &Context &&
         "Expected module in same context");

  AsmUndefinedRefs.clear();

  MergedModule = Mod->takeModule();
  TheLinker = std::make_unique<Linker>(*MergedModule);
  setAsmUndefinedRefs(&*Mod);

  // We've just changed the input, so let's make sure we verify it.
  HasVerifiedInput = false;
}

void LTOCodeGenerator::setTargetOptions(const TargetOptions &Options) {
  Config.Options = Options;
}

void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) {
  switch (Debug) {
  case LTO_DEBUG_MODEL_NONE:
    EmitDwarfDebugInfo = false;
    return;

  case LTO_DEBUG_MODEL_DWARF:
    EmitDwarfDebugInfo = true;
    return;
  }
  llvm_unreachable("Unknown debug format!");
}

void LTOCodeGenerator::setOptLevel(unsigned Level) {
  Config.OptLevel = Level;
  Config.PTO.LoopVectorization = Config.OptLevel > 1;
  Config.PTO.SLPVectorization = Config.OptLevel > 1;
  std::optional<CodeGenOptLevel> CGOptLevelOrNone =
      CodeGenOpt::getLevel(Config.OptLevel);
  assert(CGOptLevelOrNone && "Unknown optimization level!");
  Config.CGOptLevel = *CGOptLevelOrNone;
}

bool LTOCodeGenerator::writeMergedModules(StringRef Path) {
  if (!determineTarget())
    return false;

  // We always run the verifier once on the merged module.
  verifyMergedModuleOnce();

  // mark which symbols can not be internalized
  applyScopeRestrictions();

  // create output file
  std::error_code EC;
  ToolOutputFile Out(Path, EC, sys::fs::OF_None);
  if (EC) {
    std::string ErrMsg = "could not open bitcode file for writing: ";
    ErrMsg += Path.str() + ": " + EC.message();
    emitError(ErrMsg);
    return false;
  }

  // write bitcode to it
  WriteBitcodeToFile(*MergedModule, Out.os(), ShouldEmbedUselists);
  Out.os().close();

  if (Out.os().has_error()) {
    std::string ErrMsg = "could not write bitcode file: ";
    ErrMsg += Path.str() + ": " + Out.os().error().message();
    emitError(ErrMsg);
    Out.os().clear_error();
    return false;
  }

  Out.keep();
  return true;
}

bool LTOCodeGenerator::useAIXSystemAssembler() {
  const auto &Triple = TargetMach->getTargetTriple();
  return Triple.isOSAIX() && Config.Options.DisableIntegratedAS;
}

bool LTOCodeGenerator::runAIXSystemAssembler(SmallString<128> &AssemblyFile) {
  assert(useAIXSystemAssembler() &&
         "Runing AIX system assembler when integrated assembler is available!");

  // Set the system assembler path.
  SmallString<256> AssemblerPath("/usr/bin/as");
  if (!llvm::AIXSystemAssemblerPath.empty()) {
    if (llvm::sys::fs::real_path(llvm::AIXSystemAssemblerPath, AssemblerPath,
                                 /* expand_tilde */ true)) {
      emitError(
          "Cannot find the assembler specified by lto-aix-system-assembler");
      return false;
    }
  }

  // Setup the LDR_CNTRL variable
  std::string LDR_CNTRL_var = "LDR_CNTRL=MAXDATA32=0xA0000000@DSA";
  if (std::optional<std::string> V = sys::Process::GetEnv("LDR_CNTRL"))
    LDR_CNTRL_var += ("@" + *V);

  // Prepare inputs for the assember.
  const auto &Triple = TargetMach->getTargetTriple();
  const char *Arch = Triple.isArch64Bit() ? "-a64" : "-a32";
  std::string ObjectFileName(AssemblyFile);
  ObjectFileName[ObjectFileName.size() - 1] = 'o';
  SmallVector<StringRef, 8> Args = {
      "/bin/env",     LDR_CNTRL_var,
      AssemblerPath,  Arch,
      "-many",        "-o",
      ObjectFileName, AssemblyFile};

  // Invoke the assembler.
  int RC = sys::ExecuteAndWait(Args[0], Args);

  // Handle errors.
  if (RC < -1) {
    emitError("LTO assembler exited abnormally");
    return false;
  }
  if (RC < 0) {
    emitError("Unable to invoke LTO assembler");
    return false;
  }
  if (RC > 0) {
    emitError("LTO assembler invocation returned non-zero");
    return false;
  }

  // Cleanup.
  remove(AssemblyFile.c_str());

  // Fix the output file name.
  AssemblyFile = ObjectFileName;

  return true;
}

bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
  if (useAIXSystemAssembler())
    setFileType(CodeGenFileType::AssemblyFile);

  // make unique temp output file to put generated code
  SmallString<128> Filename;

  auto AddStream =
      [&](size_t Task,
          const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
    StringRef Extension(
        Config.CGFileType == CodeGenFileType::AssemblyFile ? "s" : "o");

    int FD;
    std::error_code EC =
        sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
    if (EC)
      emitError(EC.message());

    return std::make_unique<CachedFileStream>(
        std::make_unique<llvm::raw_fd_ostream>(FD, true));
  };

  bool genResult = compileOptimized(AddStream, 1);

  if (!genResult) {
    sys::fs::remove(Twine(Filename));
    return false;
  }

  // If statistics were requested, save them to the specified file or
  // print them out after codegen.
  if (StatsFile)
    PrintStatisticsJSON(StatsFile->os());
  else if (AreStatisticsEnabled())
    PrintStatistics();

  if (useAIXSystemAssembler())
    if (!runAIXSystemAssembler(Filename))
      return false;

  NativeObjectPath = Filename.c_str();
  *Name = NativeObjectPath.c_str();
  return true;
}

std::unique_ptr<MemoryBuffer>
LTOCodeGenerator::compileOptimized() {
  const char *name;
  if (!compileOptimizedToFile(&name))
    return nullptr;

  // read .o file into memory buffer
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(
      name, /*IsText=*/false, /*RequiresNullTerminator=*/false);
  if (std::error_code EC = BufferOrErr.getError()) {
    emitError(EC.message());
    sys::fs::remove(NativeObjectPath);
    return nullptr;
  }

  // remove temp files
  sys::fs::remove(NativeObjectPath);

  return std::move(*BufferOrErr);
}

bool LTOCodeGenerator::compile_to_file(const char **Name) {
  if (!optimize())
    return false;

  return compileOptimizedToFile(Name);
}

std::unique_ptr<MemoryBuffer> LTOCodeGenerator::compile() {
  if (!optimize())
    return nullptr;

  return compileOptimized();
}

bool LTOCodeGenerator::determineTarget() {
  if (TargetMach)
    return true;

  if (MergedModule->getTargetTriple().empty())
    MergedModule->setTargetTriple(Triple(sys::getDefaultTargetTriple()));

  // create target machine from info for merged modules
  std::string ErrMsg;
  MArch = TargetRegistry::lookupTarget(MergedModule->getTargetTriple(), ErrMsg);
  if (!MArch) {
    emitError(ErrMsg);
    return false;
  }

  // Construct LTOModule, hand over ownership of module and target. Use MAttr as
  // the default set of features.
  SubtargetFeatures Features(join(Config.MAttrs, ""));
  Features.getDefaultSubtargetFeatures(MergedModule->getTargetTriple());
  FeatureStr = Features.getString();
  if (Config.CPU.empty())
    Config.CPU = lto::getThinLTODefaultCPU(MergedModule->getTargetTriple());

  // If data-sections is not explicitly set or unset, set data-sections by
  // default to match the behaviour of lld and gold plugin.
  if (!codegen::getExplicitDataSections())
    Config.Options.DataSections = true;

  TargetMach = createTargetMachine();
  assert(TargetMach && "Unable to create target machine");

  return true;
}

std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
  assert(MArch && "MArch is not set!");
  return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
      MergedModule->getTargetTriple(), Config.CPU, FeatureStr, Config.Options,
      Config.RelocModel, std::nullopt, Config.CGOptLevel));
}

// If a linkonce global is present in the MustPreserveSymbols, we need to make
// sure we honor this. To force the compiler to not drop it, we add it to the
// "llvm.compiler.used" global.
void LTOCodeGenerator::preserveDiscardableGVs(
    Module &TheModule,
    llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV) {
  std::vector<GlobalValue *> Used;
  auto mayPreserveGlobal = [&](GlobalValue &GV) {
    if (!GV.isDiscardableIfUnused() || GV.isDeclaration() ||
        !mustPreserveGV(GV))
      return;
    if (GV.hasAvailableExternallyLinkage())
      return emitWarning(
          (Twine("Linker asked to preserve available_externally global: '") +
           GV.getName() + "'").str());
    if (GV.hasInternalLinkage())
      return emitWarning((Twine("Linker asked to preserve internal global: '") +
                   GV.getName() + "'").str());
    Used.push_back(&GV);
  };
  for (auto &GV : TheModule)
    mayPreserveGlobal(GV);
  for (auto &GV : TheModule.globals())
    mayPreserveGlobal(GV);
  for (auto &GV : TheModule.aliases())
    mayPreserveGlobal(GV);

  if (Used.empty())
    return;

  appendToCompilerUsed(TheModule, Used);
}

void LTOCodeGenerator::applyScopeRestrictions() {
  if (ScopeRestrictionsDone)
    return;

  // Declare a callback for the internalize pass that will ask for every
  // candidate GlobalValue if it can be internalized or not.
  Mangler Mang;
  SmallString<64> MangledName;
  auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
    // Unnamed globals can't be mangled, but they can't be preserved either.
    if (!GV.hasName())
      return false;

    // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
    // with the linker supplied name, which on Darwin includes a leading
    // underscore.
    MangledName.clear();
    MangledName.reserve(GV.getName().size() + 1);
    Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
    return MustPreserveSymbols.count(MangledName);
  };

  // Preserve linkonce value on linker request
  preserveDiscardableGVs(*MergedModule, mustPreserveGV);

  if (!ShouldInternalize)
    return;

  if (ShouldRestoreGlobalsLinkage) {
    // Record the linkage type of non-local symbols so they can be restored
    // prior
    // to module splitting.
    auto RecordLinkage = [&](const GlobalValue &GV) {
      if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
          GV.hasName())
        ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
    };
    for (auto &GV : *MergedModule)
      RecordLinkage(GV);
    for (auto &GV : MergedModule->globals())
      RecordLinkage(GV);
    for (auto &GV : MergedModule->aliases())
      RecordLinkage(GV);
  }

  // Update the llvm.compiler_used globals to force preserving libcalls and
  // symbols referenced from asm
  updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);

  internalizeModule(*MergedModule, mustPreserveGV);

  ScopeRestrictionsDone = true;
}

/// Restore original linkage for symbols that may have been internalized
void LTOCodeGenerator::restoreLinkageForExternals() {
  if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage)
    return;

  assert(ScopeRestrictionsDone &&
         "Cannot externalize without internalization!");

  if (ExternalSymbols.empty())
    return;

  auto externalize = [this](GlobalValue &GV) {
    if (!GV.hasLocalLinkage() || !GV.hasName())
      return;

    auto I = ExternalSymbols.find(GV.getName());
    if (I == ExternalSymbols.end())
      return;

    GV.setLinkage(I->second);
  };

  llvm::for_each(MergedModule->functions(), externalize);
  llvm::for_each(MergedModule->globals(), externalize);
  llvm::for_each(MergedModule->aliases(), externalize);
}

void LTOCodeGenerator::verifyMergedModuleOnce() {
  // Only run on the first call.
  if (HasVerifiedInput)
    return;
  HasVerifiedInput = true;

  bool BrokenDebugInfo = false;
  if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo))
    report_fatal_error("Broken module found, compilation aborted!");
  if (BrokenDebugInfo) {
    emitWarning("Invalid debug info found, debug info will be stripped");
    StripDebugInfo(*MergedModule);
  }
}

void LTOCodeGenerator::finishOptimizationRemarks() {
  if (DiagnosticOutputFile) {
    DiagnosticOutputFile->keep();
    // FIXME: LTOCodeGenerator dtor is not invoked on Darwin
    DiagnosticOutputFile.finalize();
    DiagnosticOutputFile->os().flush();
  }
}

/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::optimize() {
  if (!this->determineTarget())
    return false;

  // libLTO parses options late, so re-set them here.
  Context.setDiscardValueNames(LTODiscardValueNames);
  Config.StatsFile = LTOStatsFile;
  Config.RunCSIRInstr = LTORunCSIRInstr;
  Config.CSIRProfile = LTOCSIRProfile;
  Config.SampleProfile = SampleProfileFile;

  auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
      Context, RemarksFilename, RemarksPasses, RemarksFormat,
      RemarksWithHotness, RemarksHotnessThreshold);
  if (!DiagFileOrErr) {
    errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
    report_fatal_error("Can't get an output file for the remarks");
  }
  DiagnosticOutputFile = std::move(*DiagFileOrErr);

  // Setup output file to emit statistics.
  auto StatsFileOrErr = lto::setupStatsFile(LTOStatsFile);
  if (!StatsFileOrErr) {
    errs() << "Error: " << toString(StatsFileOrErr.takeError()) << "\n";
    report_fatal_error("Can't get an output file for the statistics");
  }
  StatsFile = std::move(StatsFileOrErr.get());

  // Currently there is no support for enabling whole program visibility via a
  // linker option in the old LTO API, but this call allows it to be specified
  // via the internal option. Must be done before WPD invoked via the optimizer
  // pipeline run below.
  updatePublicTypeTestCalls(*MergedModule,
                            /* WholeProgramVisibilityEnabledInLTO */ false);
  updateVCallVisibilityInModule(
      *MergedModule,
      /* WholeProgramVisibilityEnabledInLTO */ false,
      // FIXME: These need linker information via a
      // TBD new interface.
      /*DynamicExportSymbols=*/{},
      /*ValidateAllVtablesHaveTypeInfos=*/false,
      /*IsVisibleToRegularObj=*/[](StringRef) { return true; });

  // We always run the verifier once on the merged module, the `DisableVerify`
  // parameter only applies to subsequent verify.
  verifyMergedModuleOnce();

  // Mark which symbols can not be internalized
  this->applyScopeRestrictions();

  // Add an appropriate DataLayout instance for this module...
  MergedModule->setDataLayout(TargetMach->createDataLayout());

  if (!SaveIRBeforeOptPath.empty()) {
    std::error_code EC;
    raw_fd_ostream OS(SaveIRBeforeOptPath, EC, sys::fs::OF_None);
    if (EC)
      report_fatal_error(Twine("Failed to open ") + SaveIRBeforeOptPath +
                         " to save optimized bitcode\n");
    WriteBitcodeToFile(*MergedModule, OS,
                       /* ShouldPreserveUseListOrder */ true);
  }

  ModuleSummaryIndex CombinedIndex(false);
  TargetMach = createTargetMachine();
  if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
           /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
           /*CmdArgs*/ std::vector<uint8_t>(), /*BitcodeLibFuncs=*/{})) {
    emitError("LTO middle-end optimizations failed");
    return false;
  }

  return true;
}

bool LTOCodeGenerator::compileOptimized(AddStreamFn AddStream,
                                        unsigned ParallelismLevel) {
  if (!this->determineTarget())
    return false;

  // We always run the verifier once on the merged module.  If it has already
  // been called in optimize(), this call will return early.
  verifyMergedModuleOnce();

  // Re-externalize globals that may have been internalized to increase scope
  // for splitting
  restoreLinkageForExternals();

  ModuleSummaryIndex CombinedIndex(false);

  Config.CodeGenOnly = true;
  Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule,
                      CombinedIndex, /*BitcodeLibFuncs=*/{});
  assert(!Err && "unexpected code-generation failure");
  (void)Err;

  // If statistics were requested, save them to the specified file or
  // print them out after codegen.
  if (StatsFile)
    PrintStatisticsJSON(StatsFile->os());
  else if (AreStatisticsEnabled())
    PrintStatistics();

  reportAndResetTimings();

  finishOptimizationRemarks();

  return true;
}

void LTOCodeGenerator::setCodeGenDebugOptions(ArrayRef<StringRef> Options) {
  for (StringRef Option : Options)
    CodegenOptions.push_back(Option.str());
}

void LTOCodeGenerator::parseCodeGenDebugOptions() {
  if (!CodegenOptions.empty())
    llvm::parseCommandLineOptions(CodegenOptions);
}

void llvm::parseCommandLineOptions(std::vector<std::string> &Options) {
  if (!Options.empty()) {
    // ParseCommandLineOptions() expects argv[0] to be program name.
    std::vector<const char *> CodegenArgv(1, "libLLVMLTO");
    for (std::string &Arg : Options)
      CodegenArgv.push_back(Arg.c_str());
    cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
  }
}

void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) {
  // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
  lto_codegen_diagnostic_severity_t Severity;
  switch (DI.getSeverity()) {
  case DS_Error:
    Severity = LTO_DS_ERROR;
    break;
  case DS_Warning:
    Severity = LTO_DS_WARNING;
    break;
  case DS_Remark:
    Severity = LTO_DS_REMARK;
    break;
  case DS_Note:
    Severity = LTO_DS_NOTE;
    break;
  }
  // Create the string that will be reported to the external diagnostic handler.
  std::string MsgStorage;
  raw_string_ostream Stream(MsgStorage);
  DiagnosticPrinterRawOStream DP(Stream);
  DI.print(DP);

  // If this method has been called it means someone has set up an external
  // diagnostic handler. Assert on that.
  assert(DiagHandler && "Invalid diagnostic handler");
  (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
}

namespace {
struct LTODiagnosticHandler : public DiagnosticHandler {
  LTOCodeGenerator *CodeGenerator;
  LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr)
      : CodeGenerator(CodeGenPtr) {}
  bool handleDiagnostics(const DiagnosticInfo &DI) override {
    CodeGenerator->DiagnosticHandler(DI);
    return true;
  }
};
}

void
LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
                                       void *Ctxt) {
  this->DiagHandler = DiagHandler;
  this->DiagContext = Ctxt;
  if (!DiagHandler)
    return Context.setDiagnosticHandler(nullptr);
  // Register the LTOCodeGenerator stub in the LLVMContext to forward the
  // diagnostic to the external DiagHandler.
  Context.setDiagnosticHandler(std::make_unique<LTODiagnosticHandler>(this),
                               true);
}

namespace {
class LTODiagnosticInfo : public DiagnosticInfo {
  const Twine &Msg;
public:
  LTODiagnosticInfo(const Twine &DiagMsg LLVM_LIFETIME_BOUND,
                    DiagnosticSeverity Severity = DS_Error)
      : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
  void print(DiagnosticPrinter &DP) const override { DP << Msg; }
};
}

void LTOCodeGenerator::emitError(const std::string &ErrMsg) {
  if (DiagHandler)
    (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext);
  else
    Context.diagnose(LTODiagnosticInfo(ErrMsg));
}

void LTOCodeGenerator::emitWarning(const std::string &ErrMsg) {
  if (DiagHandler)
    (*DiagHandler)(LTO_DS_WARNING, ErrMsg.c_str(), DiagContext);
  else
    Context.diagnose(LTODiagnosticInfo(ErrMsg, DS_Warning));
}
