1 //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Part of the IRObjectFile class implementation.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Bitcode/ReaderWriter.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/Object/IRObjectFile.h"
19 using namespace object;
21 IRObjectFile::IRObjectFile(MemoryBuffer *Object, error_code &EC,
22 LLVMContext &Context, bool BufferOwned)
23 : SymbolicFile(Binary::ID_IR, Object, BufferOwned) {
24 ErrorOr<Module*> MOrErr = parseBitcodeFile(Object, Context);
25 if ((EC = MOrErr.getError()))
28 M.reset(MOrErr.get());
31 static const GlobalValue &getGV(DataRefImpl &Symb) {
32 return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
35 static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
36 if (I == M.alias_end())
38 const GlobalValue *GV = &*I;
39 return reinterpret_cast<uintptr_t>(GV) | 2;
42 static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) {
43 if (I == M.global_end())
44 return skipEmpty(M.alias_begin(), M);
45 const GlobalValue *GV = &*I;
46 return reinterpret_cast<uintptr_t>(GV) | 1;
49 static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
51 return skipEmpty(M.global_begin(), M);
52 const GlobalValue *GV = &*I;
53 return reinterpret_cast<uintptr_t>(GV) | 0;
56 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
57 const GlobalValue *GV = &getGV(Symb);
58 const Module &M = *GV->getParent();
62 Module::const_iterator Iter(static_cast<const Function*>(GV));
64 Res = skipEmpty(Iter, M);
68 Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
70 Res = skipEmpty(Iter, M);
74 Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
76 Res = skipEmpty(Iter, M);
80 llvm_unreachable("Invalid symbol reference");
86 error_code IRObjectFile::printSymbolName(raw_ostream &OS,
87 DataRefImpl Symb) const {
88 // FIXME: This should use the Mangler.
89 const GlobalValue &GV = getGV(Symb);
91 return object_error::success;
94 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
95 const GlobalValue &GV = getGV(Symb);
97 uint32_t Res = BasicSymbolRef::SF_None;
98 if (GV.isDeclaration() || GV.hasAvailableExternallyLinkage())
99 Res |= BasicSymbolRef::SF_Undefined;
100 if (GV.hasPrivateLinkage() || GV.hasLinkerPrivateLinkage() ||
101 GV.hasLinkerPrivateWeakLinkage())
102 Res |= BasicSymbolRef::SF_FormatSpecific;
103 if (!GV.hasLocalLinkage())
104 Res |= BasicSymbolRef::SF_Global;
105 if (GV.hasCommonLinkage())
106 Res |= BasicSymbolRef::SF_Common;
107 if (GV.hasLinkOnceLinkage() || GV.hasWeakLinkage())
108 Res |= BasicSymbolRef::SF_Weak;
113 const GlobalValue &IRObjectFile::getSymbolGV(DataRefImpl Symb) const {
114 const GlobalValue &GV = getGV(Symb);
118 basic_symbol_iterator IRObjectFile::symbol_begin_impl() const {
119 Module::const_iterator I = M->begin();
121 Ret.p = skipEmpty(I, *M);
122 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
125 basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
128 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
131 ErrorOr<SymbolicFile *> llvm::object::SymbolicFile::createIRObjectFile(
132 MemoryBuffer *Object, LLVMContext &Context, bool BufferOwned) {
134 OwningPtr<IRObjectFile> Ret(
135 new IRObjectFile(Object, EC, Context, BufferOwned));