xref: /minix3/external/bsd/llvm/dist/llvm/lib/Object/IRObjectFile.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
2*0a6a1f1dSLionel Sambuc //
3*0a6a1f1dSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*0a6a1f1dSLionel Sambuc //
5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details.
7*0a6a1f1dSLionel Sambuc //
8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
9*0a6a1f1dSLionel Sambuc //
10*0a6a1f1dSLionel Sambuc // Part of the IRObjectFile class implementation.
11*0a6a1f1dSLionel Sambuc //
12*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
13*0a6a1f1dSLionel Sambuc 
14*0a6a1f1dSLionel Sambuc #include "llvm/Object/IRObjectFile.h"
15*0a6a1f1dSLionel Sambuc #include "RecordStreamer.h"
16*0a6a1f1dSLionel Sambuc #include "llvm/Bitcode/ReaderWriter.h"
17*0a6a1f1dSLionel Sambuc #include "llvm/IR/GVMaterializer.h"
18*0a6a1f1dSLionel Sambuc #include "llvm/IR/LLVMContext.h"
19*0a6a1f1dSLionel Sambuc #include "llvm/IR/Mangler.h"
20*0a6a1f1dSLionel Sambuc #include "llvm/IR/Module.h"
21*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCAsmInfo.h"
22*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCContext.h"
23*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCInstrInfo.h"
24*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCObjectFileInfo.h"
25*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCParser/MCAsmParser.h"
26*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCRegisterInfo.h"
27*0a6a1f1dSLionel Sambuc #include "llvm/MC/MCTargetAsmParser.h"
28*0a6a1f1dSLionel Sambuc #include "llvm/Object/ObjectFile.h"
29*0a6a1f1dSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
30*0a6a1f1dSLionel Sambuc #include "llvm/Support/SourceMgr.h"
31*0a6a1f1dSLionel Sambuc #include "llvm/Support/TargetRegistry.h"
32*0a6a1f1dSLionel Sambuc #include "llvm/Support/raw_ostream.h"
33*0a6a1f1dSLionel Sambuc using namespace llvm;
34*0a6a1f1dSLionel Sambuc using namespace object;
35*0a6a1f1dSLionel Sambuc 
IRObjectFile(MemoryBufferRef Object,std::unique_ptr<Module> Mod)36*0a6a1f1dSLionel Sambuc IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
37*0a6a1f1dSLionel Sambuc     : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
38*0a6a1f1dSLionel Sambuc   // If we have a DataLayout, setup a mangler.
39*0a6a1f1dSLionel Sambuc   const DataLayout *DL = M->getDataLayout();
40*0a6a1f1dSLionel Sambuc   if (!DL)
41*0a6a1f1dSLionel Sambuc     return;
42*0a6a1f1dSLionel Sambuc 
43*0a6a1f1dSLionel Sambuc   Mang.reset(new Mangler(DL));
44*0a6a1f1dSLionel Sambuc 
45*0a6a1f1dSLionel Sambuc   const std::string &InlineAsm = M->getModuleInlineAsm();
46*0a6a1f1dSLionel Sambuc   if (InlineAsm.empty())
47*0a6a1f1dSLionel Sambuc     return;
48*0a6a1f1dSLionel Sambuc 
49*0a6a1f1dSLionel Sambuc   StringRef Triple = M->getTargetTriple();
50*0a6a1f1dSLionel Sambuc   std::string Err;
51*0a6a1f1dSLionel Sambuc   const Target *T = TargetRegistry::lookupTarget(Triple, Err);
52*0a6a1f1dSLionel Sambuc   if (!T)
53*0a6a1f1dSLionel Sambuc     return;
54*0a6a1f1dSLionel Sambuc 
55*0a6a1f1dSLionel Sambuc   std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(Triple));
56*0a6a1f1dSLionel Sambuc   if (!MRI)
57*0a6a1f1dSLionel Sambuc     return;
58*0a6a1f1dSLionel Sambuc 
59*0a6a1f1dSLionel Sambuc   std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, Triple));
60*0a6a1f1dSLionel Sambuc   if (!MAI)
61*0a6a1f1dSLionel Sambuc     return;
62*0a6a1f1dSLionel Sambuc 
63*0a6a1f1dSLionel Sambuc   std::unique_ptr<MCSubtargetInfo> STI(
64*0a6a1f1dSLionel Sambuc       T->createMCSubtargetInfo(Triple, "", ""));
65*0a6a1f1dSLionel Sambuc   if (!STI)
66*0a6a1f1dSLionel Sambuc     return;
67*0a6a1f1dSLionel Sambuc 
68*0a6a1f1dSLionel Sambuc   std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
69*0a6a1f1dSLionel Sambuc   if (!MCII)
70*0a6a1f1dSLionel Sambuc     return;
71*0a6a1f1dSLionel Sambuc 
72*0a6a1f1dSLionel Sambuc   MCObjectFileInfo MOFI;
73*0a6a1f1dSLionel Sambuc   MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
74*0a6a1f1dSLionel Sambuc   MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx);
75*0a6a1f1dSLionel Sambuc   std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx));
76*0a6a1f1dSLionel Sambuc 
77*0a6a1f1dSLionel Sambuc   std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
78*0a6a1f1dSLionel Sambuc   SourceMgr SrcMgr;
79*0a6a1f1dSLionel Sambuc   SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
80*0a6a1f1dSLionel Sambuc   std::unique_ptr<MCAsmParser> Parser(
81*0a6a1f1dSLionel Sambuc       createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI));
82*0a6a1f1dSLionel Sambuc 
83*0a6a1f1dSLionel Sambuc   MCTargetOptions MCOptions;
84*0a6a1f1dSLionel Sambuc   std::unique_ptr<MCTargetAsmParser> TAP(
85*0a6a1f1dSLionel Sambuc       T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
86*0a6a1f1dSLionel Sambuc   if (!TAP)
87*0a6a1f1dSLionel Sambuc     return;
88*0a6a1f1dSLionel Sambuc 
89*0a6a1f1dSLionel Sambuc   Parser->setTargetParser(*TAP);
90*0a6a1f1dSLionel Sambuc   if (Parser->Run(false))
91*0a6a1f1dSLionel Sambuc     return;
92*0a6a1f1dSLionel Sambuc 
93*0a6a1f1dSLionel Sambuc   for (auto &KV : *Streamer) {
94*0a6a1f1dSLionel Sambuc     StringRef Key = KV.first();
95*0a6a1f1dSLionel Sambuc     RecordStreamer::State Value = KV.second;
96*0a6a1f1dSLionel Sambuc     uint32_t Res = BasicSymbolRef::SF_None;
97*0a6a1f1dSLionel Sambuc     switch (Value) {
98*0a6a1f1dSLionel Sambuc     case RecordStreamer::NeverSeen:
99*0a6a1f1dSLionel Sambuc       llvm_unreachable("foo");
100*0a6a1f1dSLionel Sambuc     case RecordStreamer::DefinedGlobal:
101*0a6a1f1dSLionel Sambuc       Res |= BasicSymbolRef::SF_Global;
102*0a6a1f1dSLionel Sambuc       break;
103*0a6a1f1dSLionel Sambuc     case RecordStreamer::Defined:
104*0a6a1f1dSLionel Sambuc       break;
105*0a6a1f1dSLionel Sambuc     case RecordStreamer::Global:
106*0a6a1f1dSLionel Sambuc     case RecordStreamer::Used:
107*0a6a1f1dSLionel Sambuc       Res |= BasicSymbolRef::SF_Undefined;
108*0a6a1f1dSLionel Sambuc       Res |= BasicSymbolRef::SF_Global;
109*0a6a1f1dSLionel Sambuc       break;
110*0a6a1f1dSLionel Sambuc     }
111*0a6a1f1dSLionel Sambuc     AsmSymbols.push_back(
112*0a6a1f1dSLionel Sambuc         std::make_pair<std::string, uint32_t>(Key, std::move(Res)));
113*0a6a1f1dSLionel Sambuc   }
114*0a6a1f1dSLionel Sambuc }
115*0a6a1f1dSLionel Sambuc 
~IRObjectFile()116*0a6a1f1dSLionel Sambuc IRObjectFile::~IRObjectFile() {
117*0a6a1f1dSLionel Sambuc  }
118*0a6a1f1dSLionel Sambuc 
getGV(DataRefImpl & Symb)119*0a6a1f1dSLionel Sambuc static GlobalValue *getGV(DataRefImpl &Symb) {
120*0a6a1f1dSLionel Sambuc   if ((Symb.p & 3) == 3)
121*0a6a1f1dSLionel Sambuc     return nullptr;
122*0a6a1f1dSLionel Sambuc 
123*0a6a1f1dSLionel Sambuc   return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
124*0a6a1f1dSLionel Sambuc }
125*0a6a1f1dSLionel Sambuc 
skipEmpty(Module::const_alias_iterator I,const Module & M)126*0a6a1f1dSLionel Sambuc static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
127*0a6a1f1dSLionel Sambuc   if (I == M.alias_end())
128*0a6a1f1dSLionel Sambuc     return 3;
129*0a6a1f1dSLionel Sambuc   const GlobalValue *GV = &*I;
130*0a6a1f1dSLionel Sambuc   return reinterpret_cast<uintptr_t>(GV) | 2;
131*0a6a1f1dSLionel Sambuc }
132*0a6a1f1dSLionel Sambuc 
skipEmpty(Module::const_global_iterator I,const Module & M)133*0a6a1f1dSLionel Sambuc static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) {
134*0a6a1f1dSLionel Sambuc   if (I == M.global_end())
135*0a6a1f1dSLionel Sambuc     return skipEmpty(M.alias_begin(), M);
136*0a6a1f1dSLionel Sambuc   const GlobalValue *GV = &*I;
137*0a6a1f1dSLionel Sambuc   return reinterpret_cast<uintptr_t>(GV) | 1;
138*0a6a1f1dSLionel Sambuc }
139*0a6a1f1dSLionel Sambuc 
skipEmpty(Module::const_iterator I,const Module & M)140*0a6a1f1dSLionel Sambuc static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
141*0a6a1f1dSLionel Sambuc   if (I == M.end())
142*0a6a1f1dSLionel Sambuc     return skipEmpty(M.global_begin(), M);
143*0a6a1f1dSLionel Sambuc   const GlobalValue *GV = &*I;
144*0a6a1f1dSLionel Sambuc   return reinterpret_cast<uintptr_t>(GV) | 0;
145*0a6a1f1dSLionel Sambuc }
146*0a6a1f1dSLionel Sambuc 
getAsmSymIndex(DataRefImpl Symb)147*0a6a1f1dSLionel Sambuc static unsigned getAsmSymIndex(DataRefImpl Symb) {
148*0a6a1f1dSLionel Sambuc   assert((Symb.p & uintptr_t(3)) == 3);
149*0a6a1f1dSLionel Sambuc   uintptr_t Index = Symb.p & ~uintptr_t(3);
150*0a6a1f1dSLionel Sambuc   Index >>= 2;
151*0a6a1f1dSLionel Sambuc   return Index;
152*0a6a1f1dSLionel Sambuc }
153*0a6a1f1dSLionel Sambuc 
moveSymbolNext(DataRefImpl & Symb) const154*0a6a1f1dSLionel Sambuc void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
155*0a6a1f1dSLionel Sambuc   const GlobalValue *GV = getGV(Symb);
156*0a6a1f1dSLionel Sambuc   uintptr_t Res;
157*0a6a1f1dSLionel Sambuc 
158*0a6a1f1dSLionel Sambuc   switch (Symb.p & 3) {
159*0a6a1f1dSLionel Sambuc   case 0: {
160*0a6a1f1dSLionel Sambuc     Module::const_iterator Iter(static_cast<const Function*>(GV));
161*0a6a1f1dSLionel Sambuc     ++Iter;
162*0a6a1f1dSLionel Sambuc     Res = skipEmpty(Iter, *M);
163*0a6a1f1dSLionel Sambuc     break;
164*0a6a1f1dSLionel Sambuc   }
165*0a6a1f1dSLionel Sambuc   case 1: {
166*0a6a1f1dSLionel Sambuc     Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
167*0a6a1f1dSLionel Sambuc     ++Iter;
168*0a6a1f1dSLionel Sambuc     Res = skipEmpty(Iter, *M);
169*0a6a1f1dSLionel Sambuc     break;
170*0a6a1f1dSLionel Sambuc   }
171*0a6a1f1dSLionel Sambuc   case 2: {
172*0a6a1f1dSLionel Sambuc     Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
173*0a6a1f1dSLionel Sambuc     ++Iter;
174*0a6a1f1dSLionel Sambuc     Res = skipEmpty(Iter, *M);
175*0a6a1f1dSLionel Sambuc     break;
176*0a6a1f1dSLionel Sambuc   }
177*0a6a1f1dSLionel Sambuc   case 3: {
178*0a6a1f1dSLionel Sambuc     unsigned Index = getAsmSymIndex(Symb);
179*0a6a1f1dSLionel Sambuc     assert(Index < AsmSymbols.size());
180*0a6a1f1dSLionel Sambuc     ++Index;
181*0a6a1f1dSLionel Sambuc     Res = (Index << 2) | 3;
182*0a6a1f1dSLionel Sambuc     break;
183*0a6a1f1dSLionel Sambuc   }
184*0a6a1f1dSLionel Sambuc   default:
185*0a6a1f1dSLionel Sambuc     llvm_unreachable("unreachable case");
186*0a6a1f1dSLionel Sambuc   }
187*0a6a1f1dSLionel Sambuc 
188*0a6a1f1dSLionel Sambuc   Symb.p = Res;
189*0a6a1f1dSLionel Sambuc }
190*0a6a1f1dSLionel Sambuc 
printSymbolName(raw_ostream & OS,DataRefImpl Symb) const191*0a6a1f1dSLionel Sambuc std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
192*0a6a1f1dSLionel Sambuc                                               DataRefImpl Symb) const {
193*0a6a1f1dSLionel Sambuc   const GlobalValue *GV = getGV(Symb);
194*0a6a1f1dSLionel Sambuc   if (!GV) {
195*0a6a1f1dSLionel Sambuc     unsigned Index = getAsmSymIndex(Symb);
196*0a6a1f1dSLionel Sambuc     assert(Index <= AsmSymbols.size());
197*0a6a1f1dSLionel Sambuc     OS << AsmSymbols[Index].first;
198*0a6a1f1dSLionel Sambuc     return object_error::success;;
199*0a6a1f1dSLionel Sambuc   }
200*0a6a1f1dSLionel Sambuc 
201*0a6a1f1dSLionel Sambuc   if (Mang)
202*0a6a1f1dSLionel Sambuc     Mang->getNameWithPrefix(OS, GV, false);
203*0a6a1f1dSLionel Sambuc   else
204*0a6a1f1dSLionel Sambuc     OS << GV->getName();
205*0a6a1f1dSLionel Sambuc 
206*0a6a1f1dSLionel Sambuc   return object_error::success;
207*0a6a1f1dSLionel Sambuc }
208*0a6a1f1dSLionel Sambuc 
getSymbolFlags(DataRefImpl Symb) const209*0a6a1f1dSLionel Sambuc uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
210*0a6a1f1dSLionel Sambuc   const GlobalValue *GV = getGV(Symb);
211*0a6a1f1dSLionel Sambuc 
212*0a6a1f1dSLionel Sambuc   if (!GV) {
213*0a6a1f1dSLionel Sambuc     unsigned Index = getAsmSymIndex(Symb);
214*0a6a1f1dSLionel Sambuc     assert(Index <= AsmSymbols.size());
215*0a6a1f1dSLionel Sambuc     return AsmSymbols[Index].second;
216*0a6a1f1dSLionel Sambuc   }
217*0a6a1f1dSLionel Sambuc 
218*0a6a1f1dSLionel Sambuc   uint32_t Res = BasicSymbolRef::SF_None;
219*0a6a1f1dSLionel Sambuc   if (GV->isDeclarationForLinker())
220*0a6a1f1dSLionel Sambuc     Res |= BasicSymbolRef::SF_Undefined;
221*0a6a1f1dSLionel Sambuc   if (GV->hasPrivateLinkage())
222*0a6a1f1dSLionel Sambuc     Res |= BasicSymbolRef::SF_FormatSpecific;
223*0a6a1f1dSLionel Sambuc   if (!GV->hasLocalLinkage())
224*0a6a1f1dSLionel Sambuc     Res |= BasicSymbolRef::SF_Global;
225*0a6a1f1dSLionel Sambuc   if (GV->hasCommonLinkage())
226*0a6a1f1dSLionel Sambuc     Res |= BasicSymbolRef::SF_Common;
227*0a6a1f1dSLionel Sambuc   if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage())
228*0a6a1f1dSLionel Sambuc     Res |= BasicSymbolRef::SF_Weak;
229*0a6a1f1dSLionel Sambuc 
230*0a6a1f1dSLionel Sambuc   if (GV->getName().startswith("llvm."))
231*0a6a1f1dSLionel Sambuc     Res |= BasicSymbolRef::SF_FormatSpecific;
232*0a6a1f1dSLionel Sambuc   else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
233*0a6a1f1dSLionel Sambuc     if (Var->getSection() == StringRef("llvm.metadata"))
234*0a6a1f1dSLionel Sambuc       Res |= BasicSymbolRef::SF_FormatSpecific;
235*0a6a1f1dSLionel Sambuc   }
236*0a6a1f1dSLionel Sambuc 
237*0a6a1f1dSLionel Sambuc   return Res;
238*0a6a1f1dSLionel Sambuc }
239*0a6a1f1dSLionel Sambuc 
getSymbolGV(DataRefImpl Symb)240*0a6a1f1dSLionel Sambuc GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); }
241*0a6a1f1dSLionel Sambuc 
takeModule()242*0a6a1f1dSLionel Sambuc std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); }
243*0a6a1f1dSLionel Sambuc 
symbol_begin_impl() const244*0a6a1f1dSLionel Sambuc basic_symbol_iterator IRObjectFile::symbol_begin_impl() const {
245*0a6a1f1dSLionel Sambuc   Module::const_iterator I = M->begin();
246*0a6a1f1dSLionel Sambuc   DataRefImpl Ret;
247*0a6a1f1dSLionel Sambuc   Ret.p = skipEmpty(I, *M);
248*0a6a1f1dSLionel Sambuc   return basic_symbol_iterator(BasicSymbolRef(Ret, this));
249*0a6a1f1dSLionel Sambuc }
250*0a6a1f1dSLionel Sambuc 
symbol_end_impl() const251*0a6a1f1dSLionel Sambuc basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
252*0a6a1f1dSLionel Sambuc   DataRefImpl Ret;
253*0a6a1f1dSLionel Sambuc   uint64_t NumAsm = AsmSymbols.size();
254*0a6a1f1dSLionel Sambuc   NumAsm <<= 2;
255*0a6a1f1dSLionel Sambuc   Ret.p = 3 | NumAsm;
256*0a6a1f1dSLionel Sambuc   return basic_symbol_iterator(BasicSymbolRef(Ret, this));
257*0a6a1f1dSLionel Sambuc }
258*0a6a1f1dSLionel Sambuc 
findBitcodeInObject(const ObjectFile & Obj)259*0a6a1f1dSLionel Sambuc ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
260*0a6a1f1dSLionel Sambuc   for (const SectionRef &Sec : Obj.sections()) {
261*0a6a1f1dSLionel Sambuc     StringRef SecName;
262*0a6a1f1dSLionel Sambuc     if (std::error_code EC = Sec.getName(SecName))
263*0a6a1f1dSLionel Sambuc       return EC;
264*0a6a1f1dSLionel Sambuc     if (SecName == ".llvmbc") {
265*0a6a1f1dSLionel Sambuc       StringRef SecContents;
266*0a6a1f1dSLionel Sambuc       if (std::error_code EC = Sec.getContents(SecContents))
267*0a6a1f1dSLionel Sambuc         return EC;
268*0a6a1f1dSLionel Sambuc       return MemoryBufferRef(SecContents, Obj.getFileName());
269*0a6a1f1dSLionel Sambuc     }
270*0a6a1f1dSLionel Sambuc   }
271*0a6a1f1dSLionel Sambuc 
272*0a6a1f1dSLionel Sambuc   return object_error::bitcode_section_not_found;
273*0a6a1f1dSLionel Sambuc }
274*0a6a1f1dSLionel Sambuc 
findBitcodeInMemBuffer(MemoryBufferRef Object)275*0a6a1f1dSLionel Sambuc ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
276*0a6a1f1dSLionel Sambuc   sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
277*0a6a1f1dSLionel Sambuc   switch (Type) {
278*0a6a1f1dSLionel Sambuc   case sys::fs::file_magic::bitcode:
279*0a6a1f1dSLionel Sambuc     return Object;
280*0a6a1f1dSLionel Sambuc   case sys::fs::file_magic::elf_relocatable:
281*0a6a1f1dSLionel Sambuc   case sys::fs::file_magic::macho_object:
282*0a6a1f1dSLionel Sambuc   case sys::fs::file_magic::coff_object: {
283*0a6a1f1dSLionel Sambuc     ErrorOr<std::unique_ptr<ObjectFile>> ObjFile =
284*0a6a1f1dSLionel Sambuc         ObjectFile::createObjectFile(Object, Type);
285*0a6a1f1dSLionel Sambuc     if (!ObjFile)
286*0a6a1f1dSLionel Sambuc       return ObjFile.getError();
287*0a6a1f1dSLionel Sambuc     return findBitcodeInObject(*ObjFile->get());
288*0a6a1f1dSLionel Sambuc   }
289*0a6a1f1dSLionel Sambuc   default:
290*0a6a1f1dSLionel Sambuc     return object_error::invalid_file_type;
291*0a6a1f1dSLionel Sambuc   }
292*0a6a1f1dSLionel Sambuc }
293*0a6a1f1dSLionel Sambuc 
294*0a6a1f1dSLionel Sambuc ErrorOr<std::unique_ptr<IRObjectFile>>
create(MemoryBufferRef Object,LLVMContext & Context)295*0a6a1f1dSLionel Sambuc llvm::object::IRObjectFile::create(MemoryBufferRef Object,
296*0a6a1f1dSLionel Sambuc                                    LLVMContext &Context) {
297*0a6a1f1dSLionel Sambuc   ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
298*0a6a1f1dSLionel Sambuc   if (!BCOrErr)
299*0a6a1f1dSLionel Sambuc     return BCOrErr.getError();
300*0a6a1f1dSLionel Sambuc 
301*0a6a1f1dSLionel Sambuc   std::unique_ptr<MemoryBuffer> Buff(
302*0a6a1f1dSLionel Sambuc       MemoryBuffer::getMemBuffer(BCOrErr.get(), false));
303*0a6a1f1dSLionel Sambuc 
304*0a6a1f1dSLionel Sambuc   ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buff), Context);
305*0a6a1f1dSLionel Sambuc   if (std::error_code EC = MOrErr.getError())
306*0a6a1f1dSLionel Sambuc     return EC;
307*0a6a1f1dSLionel Sambuc 
308*0a6a1f1dSLionel Sambuc   std::unique_ptr<Module> M(MOrErr.get());
309*0a6a1f1dSLionel Sambuc   return llvm::make_unique<IRObjectFile>(Object, std::move(M));
310*0a6a1f1dSLionel Sambuc }
311