reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
//===-- BitReader.cpp -----------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm-c/BitReader.h"
#include "llvm-c/Core.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <cstring>
#include <string>

using namespace llvm;

/* Builds a module from the bitcode in the specified memory buffer, returning a
   reference to the module via the OutModule parameter. Returns 0 on success.
   Optionally returns a human-readable error message via OutMessage. */
LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
                          char **OutMessage) {
  return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule,
                                   OutMessage);
}

LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
                           LLVMModuleRef *OutModule) {
  return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule);
}

LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
                                   LLVMMemoryBufferRef MemBuf,
                                   LLVMModuleRef *OutModule,
                                   char **OutMessage) {
  MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
  LLVMContext &Ctx = *unwrap(ContextRef);

  Expected<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
  if (Error Err = ModuleOrErr.takeError()) {
    std::string Message;
    handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
      Message = EIB.message();
    });
    if (OutMessage)
      *OutMessage = strdup(Message.c_str());
    *OutModule = wrap((Module *)nullptr);
    return 1;
  }

  *OutModule = wrap(ModuleOrErr.get().release());
  return 0;
}

LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
                                    LLVMMemoryBufferRef MemBuf,
                                    LLVMModuleRef *OutModule) {
  MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
  LLVMContext &Ctx = *unwrap(ContextRef);

  ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
      expectedToErrorOrAndEmitErrors(Ctx, parseBitcodeFile(Buf, Ctx));
  if (ModuleOrErr.getError()) {
    *OutModule = wrap((Module *)nullptr);
    return 1;
  }

  *OutModule = wrap(ModuleOrErr.get().release());
  return 0;
}

/* Reads a module from the specified path, returning via the OutModule parameter
   a module provider which performs lazy deserialization. Returns 0 on success.
   Optionally returns a human-readable error message via OutMessage. */
LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
                                       LLVMMemoryBufferRef MemBuf,
                                       LLVMModuleRef *OutM, char **OutMessage) {
  LLVMContext &Ctx = *unwrap(ContextRef);
  std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
  Expected<std::unique_ptr<Module>> ModuleOrErr =
      getOwningLazyBitcodeModule(std::move(Owner), Ctx);
  // Release the buffer if we didn't take ownership of it since we never owned
  // it anyway.
  (void)Owner.release();

  if (Error Err = ModuleOrErr.takeError()) {
    std::string Message;
    handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
      Message = EIB.message();
    });
    if (OutMessage)
      *OutMessage = strdup(Message.c_str());
    *OutM = wrap((Module *)nullptr);
    return 1;
  }

  *OutM = wrap(ModuleOrErr.get().release());

  return 0;
}

LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
                                        LLVMMemoryBufferRef MemBuf,
                                        LLVMModuleRef *OutM) {
  LLVMContext &Ctx = *unwrap(ContextRef);
  std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));

  ErrorOr<std::unique_ptr<Module>> ModuleOrErr = expectedToErrorOrAndEmitErrors(
      Ctx, getOwningLazyBitcodeModule(std::move(Owner), Ctx));
  Owner.release();

  if (ModuleOrErr.getError()) {
    *OutM = wrap((Module *)nullptr);
    return 1;
  }

  *OutM = wrap(ModuleOrErr.get().release());
  return 0;
}

LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
                              char **OutMessage) {
  return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
                                       OutMessage);
}

LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
                               LLVMModuleRef *OutM) {
  return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
}