IRReader.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. //===---- IRReader.cpp - Reader for LLVM IR files -------------------------===//
  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. #include "llvm/IRReader/IRReader.h"
  9. #include "llvm-c/IRReader.h"
  10. #include "llvm/AsmParser/Parser.h"
  11. #include "llvm/Bitcode/BitcodeReader.h"
  12. #include "llvm/IR/LLVMContext.h"
  13. #include "llvm/IR/Module.h"
  14. #include "llvm/Support/MemoryBuffer.h"
  15. #include "llvm/Support/SourceMgr.h"
  16. #include "llvm/Support/Timer.h"
  17. #include "llvm/Support/raw_ostream.h"
  18. #include <optional>
  19. #include <system_error>
  20. using namespace llvm;
  21. namespace llvm {
  22. extern bool TimePassesIsEnabled;
  23. }
  24. const char TimeIRParsingGroupName[] = "irparse";
  25. const char TimeIRParsingGroupDescription[] = "LLVM IR Parsing";
  26. const char TimeIRParsingName[] = "parse";
  27. const char TimeIRParsingDescription[] = "Parse IR";
  28. std::unique_ptr<Module>
  29. llvm::getLazyIRModule(std::unique_ptr<MemoryBuffer> Buffer, SMDiagnostic &Err,
  30. LLVMContext &Context, bool ShouldLazyLoadMetadata) {
  31. if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
  32. (const unsigned char *)Buffer->getBufferEnd())) {
  33. Expected<std::unique_ptr<Module>> ModuleOrErr = getOwningLazyBitcodeModule(
  34. std::move(Buffer), Context, ShouldLazyLoadMetadata);
  35. if (Error E = ModuleOrErr.takeError()) {
  36. handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
  37. Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
  38. EIB.message());
  39. });
  40. return nullptr;
  41. }
  42. return std::move(ModuleOrErr.get());
  43. }
  44. return parseAssembly(Buffer->getMemBufferRef(), Err, Context);
  45. }
  46. std::unique_ptr<Module> llvm::getLazyIRFileModule(StringRef Filename,
  47. SMDiagnostic &Err,
  48. LLVMContext &Context,
  49. bool ShouldLazyLoadMetadata) {
  50. ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
  51. MemoryBuffer::getFileOrSTDIN(Filename);
  52. if (std::error_code EC = FileOrErr.getError()) {
  53. Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
  54. "Could not open input file: " + EC.message());
  55. return nullptr;
  56. }
  57. return getLazyIRModule(std::move(FileOrErr.get()), Err, Context,
  58. ShouldLazyLoadMetadata);
  59. }
  60. std::unique_ptr<Module> llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err,
  61. LLVMContext &Context,
  62. ParserCallbacks Callbacks) {
  63. NamedRegionTimer T(TimeIRParsingName, TimeIRParsingDescription,
  64. TimeIRParsingGroupName, TimeIRParsingGroupDescription,
  65. TimePassesIsEnabled);
  66. if (isBitcode((const unsigned char *)Buffer.getBufferStart(),
  67. (const unsigned char *)Buffer.getBufferEnd())) {
  68. Expected<std::unique_ptr<Module>> ModuleOrErr =
  69. parseBitcodeFile(Buffer, Context, Callbacks);
  70. if (Error E = ModuleOrErr.takeError()) {
  71. handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
  72. Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error,
  73. EIB.message());
  74. });
  75. return nullptr;
  76. }
  77. return std::move(ModuleOrErr.get());
  78. }
  79. return parseAssembly(Buffer, Err, Context, nullptr,
  80. Callbacks.DataLayout.value_or(
  81. [](StringRef, StringRef) { return std::nullopt; }));
  82. }
  83. std::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err,
  84. LLVMContext &Context,
  85. ParserCallbacks Callbacks) {
  86. ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
  87. MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
  88. if (std::error_code EC = FileOrErr.getError()) {
  89. Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
  90. "Could not open input file: " + EC.message());
  91. return nullptr;
  92. }
  93. return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context, Callbacks);
  94. }
  95. //===----------------------------------------------------------------------===//
  96. // C API.
  97. //===----------------------------------------------------------------------===//
  98. LLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef,
  99. LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
  100. char **OutMessage) {
  101. SMDiagnostic Diag;
  102. std::unique_ptr<MemoryBuffer> MB(unwrap(MemBuf));
  103. *OutM =
  104. wrap(parseIR(MB->getMemBufferRef(), Diag, *unwrap(ContextRef)).release());
  105. if(!*OutM) {
  106. if (OutMessage) {
  107. std::string buf;
  108. raw_string_ostream os(buf);
  109. Diag.print(nullptr, os, false);
  110. os.flush();
  111. *OutMessage = strdup(buf.c_str());
  112. }
  113. return 1;
  114. }
  115. return 0;
  116. }