1//===- LDSymbol.cpp -------------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "mcld/LD/LDSymbol.h"
10
11#include "mcld/Config/Config.h"
12#include "mcld/Fragment/FragmentRef.h"
13#include "mcld/Fragment/NullFragment.h"
14#include "mcld/Support/GCFactory.h"
15
16#include <llvm/Support/ManagedStatic.h>
17
18#include <cstring>
19
20namespace mcld {
21
22typedef GCFactory<LDSymbol, MCLD_SYMBOLS_PER_INPUT> LDSymbolFactory;
23
24static llvm::ManagedStatic<LDSymbol> g_NullSymbol;
25static llvm::ManagedStatic<NullFragment> g_NullSymbolFragment;
26static llvm::ManagedStatic<LDSymbolFactory> g_LDSymbolFactory;
27
28//===----------------------------------------------------------------------===//
29// LDSymbol
30//===----------------------------------------------------------------------===//
31LDSymbol::LDSymbol() : m_pResolveInfo(NULL), m_pFragRef(NULL), m_Value(0) {
32}
33
34LDSymbol::~LDSymbol() {
35}
36
37LDSymbol::LDSymbol(const LDSymbol& pCopy)
38    : m_pResolveInfo(pCopy.m_pResolveInfo),
39      m_pFragRef(pCopy.m_pFragRef),
40      m_Value(pCopy.m_Value) {
41}
42
43LDSymbol& LDSymbol::operator=(const LDSymbol& pCopy) {
44  m_pResolveInfo = pCopy.m_pResolveInfo;
45  m_pFragRef = pCopy.m_pFragRef;
46  m_Value = pCopy.m_Value;
47  return (*this);
48}
49
50LDSymbol* LDSymbol::Create(ResolveInfo& pResolveInfo) {
51  LDSymbol* result = g_LDSymbolFactory->allocate();
52  new (result) LDSymbol();
53  result->setResolveInfo(pResolveInfo);
54  return result;
55}
56
57void LDSymbol::Destroy(LDSymbol*& pSymbol) {
58  pSymbol->~LDSymbol();
59  g_LDSymbolFactory->deallocate(pSymbol);
60  pSymbol = NULL;
61}
62
63void LDSymbol::Clear() {
64  g_LDSymbolFactory->clear();
65}
66
67LDSymbol* LDSymbol::Null() {
68  // lazy initialization
69  if (g_NullSymbol->resolveInfo() == NULL) {
70    g_NullSymbol->setResolveInfo(*ResolveInfo::Null());
71    g_NullSymbol->setFragmentRef(FragmentRef::Create(*g_NullSymbolFragment, 0));
72    ResolveInfo::Null()->setSymPtr(&*g_NullSymbol);
73  }
74  return &*g_NullSymbol;
75}
76
77void LDSymbol::setFragmentRef(FragmentRef* pFragmentRef) {
78  m_pFragRef = pFragmentRef;
79}
80
81void LDSymbol::setResolveInfo(const ResolveInfo& pInfo) {
82  m_pResolveInfo = const_cast<ResolveInfo*>(&pInfo);
83}
84
85bool LDSymbol::isNull() const {
86  return (this == Null());
87}
88
89bool LDSymbol::hasFragRef() const {
90  return !m_pFragRef->isNull();
91}
92
93}  // namespace mcld
94