| //===- 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(); |
| } |
| |