1249259Sdim//===---- IRReader.cpp - Reader for LLVM IR files -------------------------===// 2249259Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6249259Sdim// 7249259Sdim//===----------------------------------------------------------------------===// 8249259Sdim 9249259Sdim#include "llvm/IRReader/IRReader.h" 10276479Sdim#include "llvm-c/IRReader.h" 11276479Sdim#include "llvm/AsmParser/Parser.h" 12314564Sdim#include "llvm/Bitcode/BitcodeReader.h" 13261991Sdim#include "llvm/IR/LLVMContext.h" 14261991Sdim#include "llvm/IR/Module.h" 15249259Sdim#include "llvm/Support/MemoryBuffer.h" 16249259Sdim#include "llvm/Support/SourceMgr.h" 17249259Sdim#include "llvm/Support/Timer.h" 18261991Sdim#include "llvm/Support/raw_ostream.h" 19276479Sdim#include <system_error> 20249259Sdim 21249259Sdimusing namespace llvm; 22249259Sdim 23249259Sdimnamespace llvm { 24249259Sdim extern bool TimePassesIsEnabled; 25249259Sdim} 26249259Sdim 27314564Sdimstatic const char *const TimeIRParsingGroupName = "irparse"; 28314564Sdimstatic const char *const TimeIRParsingGroupDescription = "LLVM IR Parsing"; 29314564Sdimstatic const char *const TimeIRParsingName = "parse"; 30314564Sdimstatic const char *const TimeIRParsingDescription = "Parse IR"; 31249259Sdim 32353358Sdimstd::unique_ptr<Module> 33353358Sdimllvm::getLazyIRModule(std::unique_ptr<MemoryBuffer> Buffer, SMDiagnostic &Err, 34353358Sdim LLVMContext &Context, bool ShouldLazyLoadMetadata) { 35249259Sdim if (isBitcode((const unsigned char *)Buffer->getBufferStart(), 36249259Sdim (const unsigned char *)Buffer->getBufferEnd())) { 37314564Sdim Expected<std::unique_ptr<Module>> ModuleOrErr = getOwningLazyBitcodeModule( 38296417Sdim std::move(Buffer), Context, ShouldLazyLoadMetadata); 39314564Sdim if (Error E = ModuleOrErr.takeError()) { 40314564Sdim handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { 41314564Sdim Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error, 42314564Sdim EIB.message()); 43314564Sdim }); 44276479Sdim return nullptr; 45249259Sdim } 46288943Sdim return std::move(ModuleOrErr.get()); 47249259Sdim } 48249259Sdim 49280031Sdim return parseAssembly(Buffer->getMemBufferRef(), Err, Context); 50249259Sdim} 51249259Sdim 52280031Sdimstd::unique_ptr<Module> llvm::getLazyIRFileModule(StringRef Filename, 53280031Sdim SMDiagnostic &Err, 54296417Sdim LLVMContext &Context, 55296417Sdim bool ShouldLazyLoadMetadata) { 56276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 57276479Sdim MemoryBuffer::getFileOrSTDIN(Filename); 58276479Sdim if (std::error_code EC = FileOrErr.getError()) { 59249259Sdim Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 60276479Sdim "Could not open input file: " + EC.message()); 61276479Sdim return nullptr; 62249259Sdim } 63249259Sdim 64296417Sdim return getLazyIRModule(std::move(FileOrErr.get()), Err, Context, 65296417Sdim ShouldLazyLoadMetadata); 66249259Sdim} 67249259Sdim 68280031Sdimstd::unique_ptr<Module> llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err, 69327952Sdim LLVMContext &Context, 70341825Sdim bool UpgradeDebugInfo, 71341825Sdim StringRef DataLayoutString) { 72314564Sdim NamedRegionTimer T(TimeIRParsingName, TimeIRParsingDescription, 73314564Sdim TimeIRParsingGroupName, TimeIRParsingGroupDescription, 74249259Sdim TimePassesIsEnabled); 75280031Sdim if (isBitcode((const unsigned char *)Buffer.getBufferStart(), 76280031Sdim (const unsigned char *)Buffer.getBufferEnd())) { 77314564Sdim Expected<std::unique_ptr<Module>> ModuleOrErr = 78288943Sdim parseBitcodeFile(Buffer, Context); 79314564Sdim if (Error E = ModuleOrErr.takeError()) { 80314564Sdim handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { 81314564Sdim Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error, 82314564Sdim EIB.message()); 83314564Sdim }); 84280031Sdim return nullptr; 85280031Sdim } 86341825Sdim if (!DataLayoutString.empty()) 87341825Sdim ModuleOrErr.get()->setDataLayout(DataLayoutString); 88288943Sdim return std::move(ModuleOrErr.get()); 89249259Sdim } 90249259Sdim 91341825Sdim return parseAssembly(Buffer, Err, Context, nullptr, UpgradeDebugInfo, 92341825Sdim DataLayoutString); 93249259Sdim} 94249259Sdim 95280031Sdimstd::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err, 96327952Sdim LLVMContext &Context, 97341825Sdim bool UpgradeDebugInfo, 98341825Sdim StringRef DataLayoutString) { 99276479Sdim ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 100276479Sdim MemoryBuffer::getFileOrSTDIN(Filename); 101276479Sdim if (std::error_code EC = FileOrErr.getError()) { 102249259Sdim Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 103276479Sdim "Could not open input file: " + EC.message()); 104276479Sdim return nullptr; 105249259Sdim } 106249259Sdim 107327952Sdim return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context, 108341825Sdim UpgradeDebugInfo, DataLayoutString); 109249259Sdim} 110261991Sdim 111261991Sdim//===----------------------------------------------------------------------===// 112261991Sdim// C API. 113261991Sdim//===----------------------------------------------------------------------===// 114261991Sdim 115261991SdimLLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef, 116261991Sdim LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, 117261991Sdim char **OutMessage) { 118261991Sdim SMDiagnostic Diag; 119261991Sdim 120276479Sdim std::unique_ptr<MemoryBuffer> MB(unwrap(MemBuf)); 121280031Sdim *OutM = 122280031Sdim wrap(parseIR(MB->getMemBufferRef(), Diag, *unwrap(ContextRef)).release()); 123261991Sdim 124261991Sdim if(!*OutM) { 125261991Sdim if (OutMessage) { 126261991Sdim std::string buf; 127261991Sdim raw_string_ostream os(buf); 128261991Sdim 129276479Sdim Diag.print(nullptr, os, false); 130261991Sdim os.flush(); 131261991Sdim 132261991Sdim *OutMessage = strdup(buf.c_str()); 133261991Sdim } 134261991Sdim return 1; 135261991Sdim } 136261991Sdim 137261991Sdim return 0; 138261991Sdim} 139