BitReader.cpp 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //===-- BitReader.cpp -----------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm-c/BitReader.h"
  10. #include "llvm-c/Core.h"
  11. #include "llvm/Bitcode/ReaderWriter.h"
  12. #include "llvm/IR/DiagnosticPrinter.h"
  13. #include "llvm/IR/LLVMContext.h"
  14. #include "llvm/IR/Module.h"
  15. #include "llvm/Support/MemoryBuffer.h"
  16. #include "llvm/Support/raw_ostream.h"
  17. #include <cstring>
  18. #include <string>
  19. using namespace llvm;
  20. /* Builds a module from the bitcode in the specified memory buffer, returning a
  21. reference to the module via the OutModule parameter. Returns 0 on success.
  22. Optionally returns a human-readable error message via OutMessage. */
  23. LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
  24. LLVMModuleRef *OutModule, char **OutMessage) {
  25. return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
  26. OutMessage);
  27. }
  28. static void diagnosticHandler(const DiagnosticInfo &DI, void *C) {
  29. auto *Message = reinterpret_cast<std::string *>(C);
  30. raw_string_ostream Stream(*Message);
  31. DiagnosticPrinterRawOStream DP(Stream);
  32. DI.print(DP);
  33. }
  34. LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
  35. LLVMMemoryBufferRef MemBuf,
  36. LLVMModuleRef *OutModule,
  37. char **OutMessage) {
  38. MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
  39. LLVMContext &Ctx = *unwrap(ContextRef);
  40. LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
  41. Ctx.getDiagnosticHandler();
  42. void *OldDiagnosticContext = Ctx.getDiagnosticContext();
  43. std::string Message;
  44. Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
  45. ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
  46. Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
  47. if (ModuleOrErr.getError()) {
  48. if (OutMessage)
  49. *OutMessage = strdup(Message.c_str());
  50. *OutModule = wrap((Module*)nullptr);
  51. return 1;
  52. }
  53. *OutModule = wrap(ModuleOrErr.get().release());
  54. return 0;
  55. }
  56. /* Reads a module from the specified path, returning via the OutModule parameter
  57. a module provider which performs lazy deserialization. Returns 0 on success.
  58. Optionally returns a human-readable error message via OutMessage. */
  59. LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
  60. LLVMMemoryBufferRef MemBuf,
  61. LLVMModuleRef *OutM,
  62. char **OutMessage) {
  63. std::string Message;
  64. std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
  65. ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
  66. getLazyBitcodeModule(std::move(Owner), *unwrap(ContextRef));
  67. Owner.release();
  68. if (std::error_code EC = ModuleOrErr.getError()) {
  69. *OutM = wrap((Module *)nullptr);
  70. if (OutMessage)
  71. *OutMessage = strdup(EC.message().c_str());
  72. return 1;
  73. }
  74. *OutM = wrap(ModuleOrErr.get().release());
  75. return 0;
  76. }
  77. LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
  78. char **OutMessage) {
  79. return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
  80. OutMessage);
  81. }