//===- NamePool.cpp -------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <llvm/Support/raw_ostream.h>
#include <mcld/LD/NamePool.h>
#include <mcld/LD/Resolver.h>

using namespace mcld;

//==========================
// NamePool
NamePool::NamePool(const Resolver& pResolver, NamePool::size_type pSize)
  : m_pResolver(&pResolver), m_Table(pSize) {
}

NamePool::~NamePool()
{
}

/// createSymbol - create a symbol
ResolveInfo* NamePool::createSymbol(const llvm::StringRef& pName,
                                      bool pIsDyn,
                                      ResolveInfo::Type pType,
                                      ResolveInfo::Desc pDesc,
                                      ResolveInfo::Binding pBinding,
                                      ResolveInfo::SizeType pSize,
                                      ResolveInfo::Visibility pVisibility)
{
  ResolveInfo* result = m_Table.getEntryFactory().produce(pName);
  result->setIsSymbol(true);
  result->setSource(pIsDyn);
  result->setType(pType);
  result->setDesc(pDesc);
  result->setBinding(pBinding);
  result->setVisibility(pVisibility);
  result->setSize(pSize);
  return result;
}

/// insertSymbol - insert a symbol and resolve it immediately
/// @return the pointer of resolved ResolveInfo
/// @return is the symbol existent?
void NamePool::insertSymbol(const llvm::StringRef& pName,
                              bool pIsDyn,
                              ResolveInfo::Type pType,
                              ResolveInfo::Desc pDesc,
                              ResolveInfo::Binding pBinding,
                              ResolveInfo::SizeType pSize,
                              ResolveInfo::Visibility pVisibility,
                              ResolveInfo* pOldInfo,
                              Resolver::Result& pResult)
{
  // We should check if there is any symbol with the same name existed.
  // If it already exists, we should use resolver to decide which symbol
  // should be reserved. Otherwise, we insert the symbol and set up its
  // attributes.
  bool exist = false;
  ResolveInfo* old_symbol = m_Table.insert(pName, exist);
  ResolveInfo* new_symbol = NULL;
  if (exist && old_symbol->isSymbol()) {
    exist = true;
    new_symbol = m_Table.getEntryFactory().produce(pName);
  }
  else {
    exist = false;
    new_symbol = old_symbol;
  }

  new_symbol->setIsSymbol(true);
  new_symbol->setSource(pIsDyn);
  new_symbol->setType(pType);
  new_symbol->setDesc(pDesc);
  new_symbol->setBinding(pBinding);
  new_symbol->setVisibility(pVisibility);
  new_symbol->setSize(pSize);

  if (!exist) {
    // not exit or not a symbol
    pResult.info      = new_symbol;
    pResult.existent  = false;
    pResult.overriden = true;
    return;
  }
  else if (NULL != pOldInfo) {
    // existent, remember its attribute
    pOldInfo->override(*old_symbol);
  }

  // exit and is a symbol
  // symbol resolution
  bool override = false;
  unsigned int action = Resolver::LastAction;
  if (m_pResolver->resolve(*old_symbol, *new_symbol, override)) {
    pResult.info      = old_symbol;
    pResult.existent  = true;
    pResult.overriden = override;
  }
  else
      m_pResolver->resolveAgain(*this, action, *old_symbol, *new_symbol, pResult);
  return;
}

llvm::StringRef NamePool::insertString(const llvm::StringRef& pString)
{
  bool exist = false;
  ResolveInfo* resolve_info = m_Table.insert(pString, exist);
  return llvm::StringRef(resolve_info->name(), resolve_info->nameSize());
}

void NamePool::reserve(NamePool::size_type pSize)
{
  m_Table.rehash(pSize);
}

NamePool::size_type NamePool::capacity() const
{
  return (m_Table.numOfBuckets() - m_Table.numOfEntries());
}

/// findInfo - find the resolved ResolveInfo
ResolveInfo* NamePool::findInfo(const llvm::StringRef& pName)
{
  Table::iterator iter = m_Table.find(pName);
  return iter.getEntry();
}

/// findInfo - find the resolved ResolveInfo
const ResolveInfo* NamePool::findInfo(const llvm::StringRef& pName) const
{
  Table::const_iterator iter = m_Table.find(pName);
  return iter.getEntry();
}

/// findSymbol - find the resolved output LDSymbol
LDSymbol* NamePool::findSymbol(const llvm::StringRef& pName)
{
  ResolveInfo* info = findInfo(pName);
  if (NULL == info)
    return NULL;
  return info->outSymbol();
}

/// findSymbol - find the resolved output LDSymbol
const LDSymbol* NamePool::findSymbol(const llvm::StringRef& pName) const
{
  const ResolveInfo* info = findInfo(pName);
  if (NULL == info)
    return NULL;
  return info->outSymbol();
}

