Home | History | Annotate | Download | only in Reader
      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 
     10 #include "llvm-c/BitReader.h"
     11 #include "llvm-c/Core.h"
     12 #include "llvm/Bitcode/ReaderWriter.h"
     13 #include "llvm/IR/DiagnosticPrinter.h"
     14 #include "llvm/IR/LLVMContext.h"
     15 #include "llvm/IR/Module.h"
     16 #include "llvm/Support/MemoryBuffer.h"
     17 #include "llvm/Support/raw_ostream.h"
     18 #include <cstring>
     19 #include <string>
     20 
     21 using namespace llvm;
     22 
     23 /* Builds a module from the bitcode in the specified memory buffer, returning a
     24    reference to the module via the OutModule parameter. Returns 0 on success.
     25    Optionally returns a human-readable error message via OutMessage. */
     26 LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutModule,
     27                           char **OutMessage) {
     28   return LLVMParseBitcodeInContext(LLVMGetGlobalContext(), MemBuf, OutModule,
     29                                    OutMessage);
     30 }
     31 
     32 LLVMBool LLVMParseBitcode2(LLVMMemoryBufferRef MemBuf,
     33                            LLVMModuleRef *OutModule) {
     34   return LLVMParseBitcodeInContext2(LLVMGetGlobalContext(), MemBuf, OutModule);
     35 }
     36 
     37 static void diagnosticHandler(const DiagnosticInfo &DI, void *C) {
     38   auto *Message = reinterpret_cast<std::string *>(C);
     39   raw_string_ostream Stream(*Message);
     40   DiagnosticPrinterRawOStream DP(Stream);
     41   DI.print(DP);
     42 }
     43 
     44 LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
     45                                    LLVMMemoryBufferRef MemBuf,
     46                                    LLVMModuleRef *OutModule,
     47                                    char **OutMessage) {
     48   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
     49   LLVMContext &Ctx = *unwrap(ContextRef);
     50 
     51   LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
     52       Ctx.getDiagnosticHandler();
     53   void *OldDiagnosticContext = Ctx.getDiagnosticContext();
     54   std::string Message;
     55   Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
     56 
     57   ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
     58 
     59   Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
     60 
     61   if (ModuleOrErr.getError()) {
     62     if (OutMessage)
     63       *OutMessage = strdup(Message.c_str());
     64     *OutModule = wrap((Module *)nullptr);
     65     return 1;
     66   }
     67 
     68   *OutModule = wrap(ModuleOrErr.get().release());
     69   return 0;
     70 }
     71 
     72 LLVMBool LLVMParseBitcodeInContext2(LLVMContextRef ContextRef,
     73                                     LLVMMemoryBufferRef MemBuf,
     74                                     LLVMModuleRef *OutModule) {
     75   MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
     76   LLVMContext &Ctx = *unwrap(ContextRef);
     77 
     78   ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile(Buf, Ctx);
     79   if (ModuleOrErr.getError()) {
     80     *OutModule = wrap((Module *)nullptr);
     81     return 1;
     82   }
     83 
     84   *OutModule = wrap(ModuleOrErr.get().release());
     85   return 0;
     86 }
     87 
     88 /* Reads a module from the specified path, returning via the OutModule parameter
     89    a module provider which performs lazy deserialization. Returns 0 on success.
     90    Optionally returns a human-readable error message via OutMessage. */
     91 LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
     92                                        LLVMMemoryBufferRef MemBuf,
     93                                        LLVMModuleRef *OutM, char **OutMessage) {
     94   LLVMContext &Ctx = *unwrap(ContextRef);
     95   LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
     96       Ctx.getDiagnosticHandler();
     97   void *OldDiagnosticContext = Ctx.getDiagnosticContext();
     98 
     99   std::string Message;
    100   Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
    101   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
    102 
    103   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
    104       getLazyBitcodeModule(std::move(Owner), Ctx);
    105   Owner.release();
    106   Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
    107 
    108   if (ModuleOrErr.getError()) {
    109     *OutM = wrap((Module *)nullptr);
    110     if (OutMessage)
    111       *OutMessage = strdup(Message.c_str());
    112     return 1;
    113   }
    114 
    115   *OutM = wrap(ModuleOrErr.get().release());
    116 
    117   return 0;
    118 }
    119 
    120 LLVMBool LLVMGetBitcodeModuleInContext2(LLVMContextRef ContextRef,
    121                                         LLVMMemoryBufferRef MemBuf,
    122                                         LLVMModuleRef *OutM) {
    123   LLVMContext &Ctx = *unwrap(ContextRef);
    124   std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf));
    125 
    126   ErrorOr<std::unique_ptr<Module>> ModuleOrErr =
    127       getLazyBitcodeModule(std::move(Owner), Ctx);
    128   Owner.release();
    129 
    130   if (ModuleOrErr.getError()) {
    131     *OutM = wrap((Module *)nullptr);
    132     return 1;
    133   }
    134 
    135   *OutM = wrap(ModuleOrErr.get().release());
    136   return 0;
    137 }
    138 
    139 LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
    140                               char **OutMessage) {
    141   return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
    142                                        OutMessage);
    143 }
    144 
    145 LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
    146                                LLVMModuleRef *OutM) {
    147   return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
    148 }
    149