1249259Sdim//===---- IRReader.cpp - Reader for LLVM IR files -------------------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim 10249259Sdim#include "llvm/IRReader/IRReader.h" 11276479Sdim#include "llvm-c/Core.h" 12276479Sdim#include "llvm-c/IRReader.h" 13276479Sdim#include "llvm/AsmParser/Parser.h" 14249259Sdim#include "llvm/Bitcode/ReaderWriter.h" 15261991Sdim#include "llvm/IR/LLVMContext.h" 16261991Sdim#include "llvm/IR/Module.h" 17249259Sdim#include "llvm/Support/MemoryBuffer.h" 18249259Sdim#include "llvm/Support/SourceMgr.h" 19249259Sdim#include "llvm/Support/Timer.h" 20261991Sdim#include "llvm/Support/raw_ostream.h" 21276479Sdim#include <system_error> 22249259Sdim 23249259Sdimusing namespace llvm; 24249259Sdim 25249259Sdimnamespace llvm { 26249259Sdim extern bool TimePassesIsEnabled; 27249259Sdim} 28249259Sdim 29261991Sdimstatic const char *const TimeIRParsingGroupName = "LLVM IR Parsing"; 30261991Sdimstatic const char *const TimeIRParsingName = "Parse IR"; 31249259Sdim 32280031Sdimstatic std::unique_ptr<Module> 33280031SdimgetLazyIRModule(std::unique_ptr<MemoryBuffer> Buffer, SMDiagnostic &Err, 34296417Sdim LLVMContext &Context, bool ShouldLazyLoadMetadata) { 35249259Sdim if (isBitcode((const unsigned char *)Buffer->getBufferStart(), 36249259Sdim (const unsigned char *)Buffer->getBufferEnd())) { 37296417Sdim ErrorOr<std::unique_ptr<Module>> ModuleOrErr = getLazyBitcodeModule( 38296417Sdim std::move(Buffer), Context, ShouldLazyLoadMetadata); 39276479Sdim if (std::error_code EC = ModuleOrErr.getError()) { 40249259Sdim Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error, 41276479Sdim EC.message()); 42276479Sdim return nullptr; 43249259Sdim } 44288943Sdim return std::move(ModuleOrErr.get()); 45249259Sdim } 46249259Sdim 47280031Sdim return parseAssembly(Buffer->getMemBufferRef(), Err, Context); 48249259Sdim} 49249259Sdim 50280031Sdimstd::unique_ptr<Module> llvm::getLazyIRFileModule(StringRef Filename, 51280031Sdim SMDiagnostic &Err, 52296417Sdim LLVMContext &Context, 53296417Sdim bool ShouldLazyLoadMetadata) { 54276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 55276479Sdim MemoryBuffer::getFileOrSTDIN(Filename); 56276479Sdim if (std::error_code EC = FileOrErr.getError()) { 57249259Sdim Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 58276479Sdim "Could not open input file: " + EC.message()); 59276479Sdim return nullptr; 60249259Sdim } 61249259Sdim 62296417Sdim return getLazyIRModule(std::move(FileOrErr.get()), Err, Context, 63296417Sdim ShouldLazyLoadMetadata); 64249259Sdim} 65249259Sdim 66280031Sdimstd::unique_ptr<Module> llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err, 67280031Sdim LLVMContext &Context) { 68249259Sdim NamedRegionTimer T(TimeIRParsingName, TimeIRParsingGroupName, 69249259Sdim TimePassesIsEnabled); 70280031Sdim if (isBitcode((const unsigned char *)Buffer.getBufferStart(), 71280031Sdim (const unsigned char *)Buffer.getBufferEnd())) { 72288943Sdim ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 73288943Sdim parseBitcodeFile(Buffer, Context); 74280031Sdim if (std::error_code EC = ModuleOrErr.getError()) { 75280031Sdim Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error, 76276479Sdim EC.message()); 77280031Sdim return nullptr; 78280031Sdim } 79288943Sdim return std::move(ModuleOrErr.get()); 80249259Sdim } 81249259Sdim 82280031Sdim return parseAssembly(Buffer, Err, Context); 83249259Sdim} 84249259Sdim 85280031Sdimstd::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err, 86280031Sdim LLVMContext &Context) { 87276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 88276479Sdim MemoryBuffer::getFileOrSTDIN(Filename); 89276479Sdim if (std::error_code EC = FileOrErr.getError()) { 90249259Sdim Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 91276479Sdim "Could not open input file: " + EC.message()); 92276479Sdim return nullptr; 93249259Sdim } 94249259Sdim 95280031Sdim return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context); 96249259Sdim} 97261991Sdim 98261991Sdim//===----------------------------------------------------------------------===// 99261991Sdim// C API. 100261991Sdim//===----------------------------------------------------------------------===// 101261991Sdim 102261991SdimLLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef, 103261991Sdim LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 104261991Sdim char **OutMessage) { 105261991Sdim SMDiagnostic Diag; 106261991Sdim 107276479Sdim std::unique_ptr<MemoryBuffer> MB(unwrap(MemBuf)); 108280031Sdim *OutM = 109280031Sdim wrap(parseIR(MB->getMemBufferRef(), Diag, *unwrap(ContextRef)).release()); 110261991Sdim 111261991Sdim if(!*OutM) { 112261991Sdim if (OutMessage) { 113261991Sdim std::string buf; 114261991Sdim raw_string_ostream os(buf); 115261991Sdim 116276479Sdim Diag.print(nullptr, os, false); 117261991Sdim os.flush(); 118261991Sdim 119261991Sdim *OutMessage = strdup(buf.c_str()); 120261991Sdim } 121261991Sdim return 1; 122261991Sdim } 123261991Sdim 124261991Sdim return 0; 125261991Sdim} 126