1f4a2713aSLionel Sambuc //===---- IRReader.cpp - Reader for LLVM IR files -------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc #include "llvm/IRReader/IRReader.h"
11*0a6a1f1dSLionel Sambuc #include "llvm-c/Core.h"
12*0a6a1f1dSLionel Sambuc #include "llvm-c/IRReader.h"
13*0a6a1f1dSLionel Sambuc #include "llvm/AsmParser/Parser.h"
14f4a2713aSLionel Sambuc #include "llvm/Bitcode/ReaderWriter.h"
15f4a2713aSLionel Sambuc #include "llvm/IR/LLVMContext.h"
16f4a2713aSLionel Sambuc #include "llvm/IR/Module.h"
17f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
18f4a2713aSLionel Sambuc #include "llvm/Support/SourceMgr.h"
19f4a2713aSLionel Sambuc #include "llvm/Support/Timer.h"
20f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
21*0a6a1f1dSLionel Sambuc #include <system_error>
22f4a2713aSLionel Sambuc 
23f4a2713aSLionel Sambuc using namespace llvm;
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc namespace llvm {
26f4a2713aSLionel Sambuc   extern bool TimePassesIsEnabled;
27f4a2713aSLionel Sambuc }
28f4a2713aSLionel Sambuc 
29f4a2713aSLionel Sambuc static const char *const TimeIRParsingGroupName = "LLVM IR Parsing";
30f4a2713aSLionel Sambuc static const char *const TimeIRParsingName = "Parse IR";
31f4a2713aSLionel Sambuc 
32*0a6a1f1dSLionel Sambuc static std::unique_ptr<Module>
getLazyIRModule(std::unique_ptr<MemoryBuffer> Buffer,SMDiagnostic & Err,LLVMContext & Context)33*0a6a1f1dSLionel Sambuc getLazyIRModule(std::unique_ptr<MemoryBuffer> Buffer, SMDiagnostic &Err,
34f4a2713aSLionel Sambuc                 LLVMContext &Context) {
35f4a2713aSLionel Sambuc   if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
36f4a2713aSLionel Sambuc                 (const unsigned char *)Buffer->getBufferEnd())) {
37*0a6a1f1dSLionel Sambuc     ErrorOr<Module *> ModuleOrErr =
38*0a6a1f1dSLionel Sambuc         getLazyBitcodeModule(std::move(Buffer), Context);
39*0a6a1f1dSLionel Sambuc     if (std::error_code EC = ModuleOrErr.getError()) {
40f4a2713aSLionel Sambuc       Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
41*0a6a1f1dSLionel Sambuc                          EC.message());
42*0a6a1f1dSLionel Sambuc       return nullptr;
43f4a2713aSLionel Sambuc     }
44*0a6a1f1dSLionel Sambuc     return std::unique_ptr<Module>(ModuleOrErr.get());
45f4a2713aSLionel Sambuc   }
46f4a2713aSLionel Sambuc 
47*0a6a1f1dSLionel Sambuc   return parseAssembly(Buffer->getMemBufferRef(), Err, Context);
48f4a2713aSLionel Sambuc }
49f4a2713aSLionel Sambuc 
getLazyIRFileModule(StringRef Filename,SMDiagnostic & Err,LLVMContext & Context)50*0a6a1f1dSLionel Sambuc std::unique_ptr<Module> llvm::getLazyIRFileModule(StringRef Filename,
51*0a6a1f1dSLionel Sambuc                                                   SMDiagnostic &Err,
52f4a2713aSLionel Sambuc                                                   LLVMContext &Context) {
53*0a6a1f1dSLionel Sambuc   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
54*0a6a1f1dSLionel Sambuc       MemoryBuffer::getFileOrSTDIN(Filename);
55*0a6a1f1dSLionel Sambuc   if (std::error_code EC = FileOrErr.getError()) {
56f4a2713aSLionel Sambuc     Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
57*0a6a1f1dSLionel Sambuc                        "Could not open input file: " + EC.message());
58*0a6a1f1dSLionel Sambuc     return nullptr;
59f4a2713aSLionel Sambuc   }
60f4a2713aSLionel Sambuc 
61*0a6a1f1dSLionel Sambuc   return getLazyIRModule(std::move(FileOrErr.get()), Err, Context);
62f4a2713aSLionel Sambuc }
63f4a2713aSLionel Sambuc 
parseIR(MemoryBufferRef Buffer,SMDiagnostic & Err,LLVMContext & Context)64*0a6a1f1dSLionel Sambuc std::unique_ptr<Module> llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err,
65f4a2713aSLionel Sambuc                                       LLVMContext &Context) {
66f4a2713aSLionel Sambuc   NamedRegionTimer T(TimeIRParsingName, TimeIRParsingGroupName,
67f4a2713aSLionel Sambuc                      TimePassesIsEnabled);
68*0a6a1f1dSLionel Sambuc   if (isBitcode((const unsigned char *)Buffer.getBufferStart(),
69*0a6a1f1dSLionel Sambuc                 (const unsigned char *)Buffer.getBufferEnd())) {
70*0a6a1f1dSLionel Sambuc     ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(Buffer, Context);
71*0a6a1f1dSLionel Sambuc     if (std::error_code EC = ModuleOrErr.getError()) {
72*0a6a1f1dSLionel Sambuc       Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error,
73*0a6a1f1dSLionel Sambuc                          EC.message());
74*0a6a1f1dSLionel Sambuc       return nullptr;
75*0a6a1f1dSLionel Sambuc     }
76*0a6a1f1dSLionel Sambuc     return std::unique_ptr<Module>(ModuleOrErr.get());
77f4a2713aSLionel Sambuc   }
78f4a2713aSLionel Sambuc 
79*0a6a1f1dSLionel Sambuc   return parseAssembly(Buffer, Err, Context);
80f4a2713aSLionel Sambuc }
81f4a2713aSLionel Sambuc 
parseIRFile(StringRef Filename,SMDiagnostic & Err,LLVMContext & Context)82*0a6a1f1dSLionel Sambuc std::unique_ptr<Module> llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err,
83f4a2713aSLionel Sambuc                                           LLVMContext &Context) {
84*0a6a1f1dSLionel Sambuc   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
85*0a6a1f1dSLionel Sambuc       MemoryBuffer::getFileOrSTDIN(Filename);
86*0a6a1f1dSLionel Sambuc   if (std::error_code EC = FileOrErr.getError()) {
87f4a2713aSLionel Sambuc     Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
88*0a6a1f1dSLionel Sambuc                        "Could not open input file: " + EC.message());
89*0a6a1f1dSLionel Sambuc     return nullptr;
90f4a2713aSLionel Sambuc   }
91f4a2713aSLionel Sambuc 
92*0a6a1f1dSLionel Sambuc   return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context);
93f4a2713aSLionel Sambuc }
94f4a2713aSLionel Sambuc 
95f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
96f4a2713aSLionel Sambuc // C API.
97f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
98f4a2713aSLionel Sambuc 
LLVMParseIRInContext(LLVMContextRef ContextRef,LLVMMemoryBufferRef MemBuf,LLVMModuleRef * OutM,char ** OutMessage)99f4a2713aSLionel Sambuc LLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef,
100f4a2713aSLionel Sambuc                               LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
101f4a2713aSLionel Sambuc                               char **OutMessage) {
102f4a2713aSLionel Sambuc   SMDiagnostic Diag;
103f4a2713aSLionel Sambuc 
104*0a6a1f1dSLionel Sambuc   std::unique_ptr<MemoryBuffer> MB(unwrap(MemBuf));
105*0a6a1f1dSLionel Sambuc   *OutM =
106*0a6a1f1dSLionel Sambuc       wrap(parseIR(MB->getMemBufferRef(), Diag, *unwrap(ContextRef)).release());
107f4a2713aSLionel Sambuc 
108f4a2713aSLionel Sambuc   if(!*OutM) {
109f4a2713aSLionel Sambuc     if (OutMessage) {
110f4a2713aSLionel Sambuc       std::string buf;
111f4a2713aSLionel Sambuc       raw_string_ostream os(buf);
112f4a2713aSLionel Sambuc 
113*0a6a1f1dSLionel Sambuc       Diag.print(nullptr, os, false);
114f4a2713aSLionel Sambuc       os.flush();
115f4a2713aSLionel Sambuc 
116f4a2713aSLionel Sambuc       *OutMessage = strdup(buf.c_str());
117f4a2713aSLionel Sambuc     }
118f4a2713aSLionel Sambuc     return 1;
119f4a2713aSLionel Sambuc   }
120f4a2713aSLionel Sambuc 
121f4a2713aSLionel Sambuc   return 0;
122f4a2713aSLionel Sambuc }
123