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