LLVM API Documentation

IRReader.cpp
Go to the documentation of this file.
00001 //===---- IRReader.cpp - Reader for LLVM IR files -------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/IRReader/IRReader.h"
00011 #include "llvm-c/Core.h"
00012 #include "llvm-c/IRReader.h"
00013 #include "llvm/AsmParser/Parser.h"
00014 #include "llvm/Bitcode/ReaderWriter.h"
00015 #include "llvm/IR/LLVMContext.h"
00016 #include "llvm/IR/Module.h"
00017 #include "llvm/Support/MemoryBuffer.h"
00018 #include "llvm/Support/SourceMgr.h"
00019 #include "llvm/Support/Timer.h"
00020 #include "llvm/Support/raw_ostream.h"
00021 #include <system_error>
00022 
00023 using namespace llvm;
00024 
00025 namespace llvm {
00026   extern bool TimePassesIsEnabled;
00027 }
00028 
00029 static const char *const TimeIRParsingGroupName = "LLVM IR Parsing";
00030 static const char *const TimeIRParsingName = "Parse IR";
00031 
00032 static std::unique_ptr<Module>
00033 getLazyIRModule(std::unique_ptr<MemoryBuffer> Buffer, SMDiagnostic &Err,
00034                 LLVMContext &Context) {
00035   if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
00036                 (const unsigned char *)Buffer->getBufferEnd())) {
00037     std::string ErrMsg;
00038     ErrorOr<Module *> ModuleOrErr =
00039         getLazyBitcodeModule(std::move(Buffer), Context);
00040     if (std::error_code EC = ModuleOrErr.getError()) {
00041       Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
00042                          EC.message());
00043       return nullptr;
00044     }
00045     return std::unique_ptr<Module>(ModuleOrErr.get());
00046   }
00047 
00048   return parseAssembly(Buffer->getMemBufferRef(), Err, Context);
00049 }
00050 
00051 std::unique_ptr<Module> llvm::getLazyIRFileModule(StringRef Filename,
00052                                                   SMDiagnostic &Err,
00053                                                   LLVMContext &Context) {
00054   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
00055       MemoryBuffer::getFileOrSTDIN(Filename);
00056   if (std::error_code EC = FileOrErr.getError()) {
00057     Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
00058                        "Could not open input file: " + EC.message());
00059     return nullptr;
00060   }
00061 
00062   return getLazyIRModule(std::move(FileOrErr.get()), Err, Context);
00063 }
00064 
00065 std::unique_ptr<Module> llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err,
00066                                       LLVMContext &Context) {
00067   NamedRegionTimer T(TimeIRParsingName, TimeIRParsingGroupName,
00068                      TimePassesIsEnabled);
00069   if (isBitcode((const unsigned char *)Buffer.getBufferStart(),
00070                 (const unsigned char *)Buffer.getBufferEnd())) {
00071     ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(Buffer, Context);
00072     if (std::error_code EC = ModuleOrErr.getError()) {
00073       Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error,
00074                          EC.message());
00075       return nullptr;
00076     }
00077     return std::unique_ptr<Module>(ModuleOrErr.get());
00078   }
00079 
00080   return parseAssembly(Buffer, Err, Context);
00081 }
00082 
00083 std::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err,
00084                                           LLVMContext &Context) {
00085   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
00086       MemoryBuffer::getFileOrSTDIN(Filename);
00087   if (std::error_code EC = FileOrErr.getError()) {
00088     Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
00089                        "Could not open input file: " + EC.message());
00090     return nullptr;
00091   }
00092 
00093   return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context);
00094 }
00095 
00096 //===----------------------------------------------------------------------===//
00097 // C API.
00098 //===----------------------------------------------------------------------===//
00099 
00100 LLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef,
00101                               LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
00102                               char **OutMessage) {
00103   SMDiagnostic Diag;
00104 
00105   std::unique_ptr<MemoryBuffer> MB(unwrap(MemBuf));
00106   *OutM =
00107       wrap(parseIR(MB->getMemBufferRef(), Diag, *unwrap(ContextRef)).release());
00108 
00109   if(!*OutM) {
00110     if (OutMessage) {
00111       std::string buf;
00112       raw_string_ostream os(buf);
00113 
00114       Diag.print(nullptr, os, false);
00115       os.flush();
00116 
00117       *OutMessage = strdup(buf.c_str());
00118     }
00119     return 1;
00120   }
00121 
00122   return 0;
00123 }