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