//===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Part of the IRObjectFile class implementation.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace object;

IRObjectFile::IRObjectFile(MemoryBuffer *Object, std::error_code &EC,
                           LLVMContext &Context, bool BufferOwned)
    : SymbolicFile(Binary::ID_IR, Object, BufferOwned) {
  ErrorOr<Module *> MOrErr =
      getLazyBitcodeModule(Object, Context, /*BufferOwned*/ false);
  if ((EC = MOrErr.getError()))
    return;

  M.reset(MOrErr.get());

  // If we have a DataLayout, setup a mangler.
  const DataLayout *DL = M->getDataLayout();
  if (!DL)
    return;

  Mang.reset(new Mangler(DL));
}

static const GlobalValue &getGV(DataRefImpl &Symb) {
  return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
}

static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
  if (I == M.alias_end())
    return 3;
  const GlobalValue *GV = &*I;
  return reinterpret_cast<uintptr_t>(GV) | 2;
}

static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) {
  if (I == M.global_end())
    return skipEmpty(M.alias_begin(), M);
  const GlobalValue *GV = &*I;
  return reinterpret_cast<uintptr_t>(GV) | 1;
}

static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
  if (I == M.end())
    return skipEmpty(M.global_begin(), M);
  const GlobalValue *GV = &*I;
  return reinterpret_cast<uintptr_t>(GV) | 0;
}

void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
  const GlobalValue *GV = &getGV(Symb);
  const Module &M = *GV->getParent();
  uintptr_t Res;
  switch (Symb.p & 3) {
  case 0: {
    Module::const_iterator Iter(static_cast<const Function*>(GV));
    ++Iter;
    Res = skipEmpty(Iter, M);
    break;
  }
  case 1: {
    Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
    ++Iter;
    Res = skipEmpty(Iter, M);
    break;
  }
  case 2: {
    Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
    ++Iter;
    Res = skipEmpty(Iter, M);
    break;
  }
  case 3:
    llvm_unreachable("Invalid symbol reference");
  }

  Symb.p = Res;
}

std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
                                              DataRefImpl Symb) const {
  const GlobalValue &GV = getGV(Symb);

  if (Mang)
    Mang->getNameWithPrefix(OS, &GV, false);
  else
    OS << GV.getName();

  return object_error::success;
}

static bool isDeclaration(const GlobalValue &V) {
  if (V.hasAvailableExternallyLinkage())
    return true;

  if (V.isMaterializable())
    return false;

  return V.isDeclaration();
}

uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
  const GlobalValue &GV = getGV(Symb);

  uint32_t Res = BasicSymbolRef::SF_None;
  if (isDeclaration(GV))
    Res |= BasicSymbolRef::SF_Undefined;
  if (GV.hasPrivateLinkage())
    Res |= BasicSymbolRef::SF_FormatSpecific;
  if (!GV.hasLocalLinkage())
    Res |= BasicSymbolRef::SF_Global;
  if (GV.hasCommonLinkage())
    Res |= BasicSymbolRef::SF_Common;
  if (GV.hasLinkOnceLinkage() || GV.hasWeakLinkage())
    Res |= BasicSymbolRef::SF_Weak;

  return Res;
}

const GlobalValue &IRObjectFile::getSymbolGV(DataRefImpl Symb) const {
  const GlobalValue &GV = getGV(Symb);
  return GV;
}

basic_symbol_iterator IRObjectFile::symbol_begin_impl() const {
  Module::const_iterator I = M->begin();
  DataRefImpl Ret;
  Ret.p = skipEmpty(I, *M);
  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
}

basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
  DataRefImpl Ret;
  Ret.p = 3;
  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
}

ErrorOr<SymbolicFile *> llvm::object::SymbolicFile::createIRObjectFile(
    MemoryBuffer *Object, LLVMContext &Context, bool BufferOwned) {
  std::error_code EC;
  std::unique_ptr<IRObjectFile> Ret(
      new IRObjectFile(Object, EC, Context, BufferOwned));
  if (EC)
    return EC;
  return Ret.release();
}
