IRReader.cpp 4.8 KB

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