llvm-cat.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //===- llvm-cat.cpp - LLVM module concatenation utility -------------------===//
  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. //===----------------------------------------------------------------------===//
  8. //
  9. // This program is for testing features that rely on multi-module bitcode files.
  10. // It takes a list of input modules and uses them to create a multi-module
  11. // bitcode file.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/ADT/SmallVector.h"
  15. #include "llvm/Bitcode/BitcodeReader.h"
  16. #include "llvm/Bitcode/BitcodeWriter.h"
  17. #include "llvm/IR/LLVMContext.h"
  18. #include "llvm/IR/Module.h"
  19. #include "llvm/IRReader/IRReader.h"
  20. #include "llvm/Support/CommandLine.h"
  21. #include "llvm/Support/Error.h"
  22. #include "llvm/Support/FileSystem.h"
  23. #include "llvm/Support/MemoryBuffer.h"
  24. #include "llvm/Support/SourceMgr.h"
  25. #include "llvm/Support/raw_ostream.h"
  26. #include <algorithm>
  27. #include <memory>
  28. #include <string>
  29. #include <system_error>
  30. #include <vector>
  31. using namespace llvm;
  32. cl::OptionCategory CatCategory("llvm-cat Options");
  33. static cl::opt<bool>
  34. BinaryCat("b", cl::desc("Whether to perform binary concatenation"),
  35. cl::cat(CatCategory));
  36. static cl::opt<std::string> OutputFilename("o", cl::Required,
  37. cl::desc("Output filename"),
  38. cl::value_desc("filename"),
  39. cl::cat(CatCategory));
  40. static cl::list<std::string> InputFilenames(cl::Positional, cl::ZeroOrMore,
  41. cl::desc("<input files>"),
  42. cl::cat(CatCategory));
  43. int main(int argc, char **argv) {
  44. cl::HideUnrelatedOptions(CatCategory);
  45. cl::ParseCommandLineOptions(argc, argv, "Module concatenation");
  46. ExitOnError ExitOnErr("llvm-cat: ");
  47. LLVMContext Context;
  48. SmallVector<char, 0> Buffer;
  49. BitcodeWriter Writer(Buffer);
  50. if (BinaryCat) {
  51. for (const auto &InputFilename : InputFilenames) {
  52. std::unique_ptr<MemoryBuffer> MB = ExitOnErr(
  53. errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename)));
  54. std::vector<BitcodeModule> Mods = ExitOnErr(getBitcodeModuleList(*MB));
  55. for (auto &BitcodeMod : Mods) {
  56. llvm::append_range(Buffer, BitcodeMod.getBuffer());
  57. Writer.copyStrtab(BitcodeMod.getStrtab());
  58. }
  59. }
  60. } else {
  61. // The string table does not own strings added to it, some of which are
  62. // owned by the modules; keep them alive until we write the string table.
  63. std::vector<std::unique_ptr<Module>> OwnedMods;
  64. for (const auto &InputFilename : InputFilenames) {
  65. SMDiagnostic Err;
  66. std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);
  67. if (!M) {
  68. Err.print(argv[0], errs());
  69. return 1;
  70. }
  71. Writer.writeModule(*M);
  72. OwnedMods.push_back(std::move(M));
  73. }
  74. Writer.writeStrtab();
  75. }
  76. std::error_code EC;
  77. raw_fd_ostream OS(OutputFilename, EC, sys::fs::OpenFlags::OF_None);
  78. if (EC) {
  79. errs() << argv[0] << ": cannot open " << OutputFilename << " for writing: "
  80. << EC.message();
  81. return 1;
  82. }
  83. OS.write(Buffer.data(), Buffer.size());
  84. return 0;
  85. }