1//===- NamePool.h ---------------------------------------------------------===//
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#ifndef MCLD_LD_NAMEPOOL_H_
10#define MCLD_LD_NAMEPOOL_H_
11
12#include "mcld/ADT/HashTable.h"
13#include "mcld/ADT/StringHash.h"
14#include "mcld/Config/Config.h"
15#include "mcld/LD/ResolveInfo.h"
16#include "mcld/LD/Resolver.h"
17#include "mcld/Support/Compiler.h"
18#include "mcld/Support/GCFactory.h"
19
20#include <llvm/ADT/StringRef.h>
21
22#include <utility>
23
24namespace mcld {
25
26/** \class NamePool
27 *  \brief Store symbol and search symbol by name. Can help symbol resolution.
28 *
29 *  - MCLinker is responsed for creating NamePool.
30 */
31class NamePool {
32 public:
33  typedef HashTable<ResolveInfo, hash::StringHash<hash::DJB> > Table;
34  typedef Table::iterator syminfo_iterator;
35  typedef Table::const_iterator const_syminfo_iterator;
36
37  typedef GCFactory<ResolveInfo*, 128> FreeInfoSet;
38  typedef FreeInfoSet::iterator freeinfo_iterator;
39  typedef FreeInfoSet::const_iterator const_freeinfo_iterator;
40
41  typedef size_t size_type;
42
43 public:
44  explicit NamePool(size_type pSize = 3);
45
46  ~NamePool();
47
48  // -----  modifiers  ----- //
49  /// createSymbol - create a symbol but do not insert into the pool.
50  /// The created symbol did not go through the path of symbol resolution.
51  ResolveInfo* createSymbol(
52      const llvm::StringRef& pName,
53      bool pIsDyn,
54      ResolveInfo::Type pType,
55      ResolveInfo::Desc pDesc,
56      ResolveInfo::Binding pBinding,
57      ResolveInfo::SizeType pSize,
58      ResolveInfo::Visibility pVisibility = ResolveInfo::Default);
59
60  /// insertSymbol - insert a symbol and resolve the symbol immediately
61  /// @param pOldInfo - if pOldInfo is not NULL, the old ResolveInfo being
62  ///                   overriden is kept in pOldInfo.
63  /// @param pResult the result of symbol resultion.
64  /// @note pResult.override is true if the output LDSymbol also need to be
65  ///       overriden
66  void insertSymbol(const llvm::StringRef& pName,
67                    bool pIsDyn,
68                    ResolveInfo::Type pType,
69                    ResolveInfo::Desc pDesc,
70                    ResolveInfo::Binding pBinding,
71                    ResolveInfo::SizeType pSize,
72                    LDSymbol::ValueType pValue,
73                    ResolveInfo::Visibility pVisibility,
74                    ResolveInfo* pOldInfo,
75                    Resolver::Result& pResult);
76
77  /// findSymbol - find the resolved output LDSymbol
78  const LDSymbol* findSymbol(const llvm::StringRef& pName) const;
79  LDSymbol* findSymbol(const llvm::StringRef& pName);
80
81  /// findInfo - find the resolved ResolveInfo
82  const ResolveInfo* findInfo(const llvm::StringRef& pName) const;
83  ResolveInfo* findInfo(const llvm::StringRef& pName);
84
85  /// insertString - insert a string
86  /// if the string has existed, modify pString to the existing string
87  /// @return the StringRef points to the hash table
88  llvm::StringRef insertString(const llvm::StringRef& pString);
89
90  // -----  observers  ----- //
91  size_type size() const { return m_Table.numOfEntries(); }
92
93  bool empty() const { return m_Table.empty(); }
94
95  // syminfo_iterator - traverse the ResolveInfo in the resolved HashTable
96  syminfo_iterator syminfo_begin() { return m_Table.begin(); }
97
98  syminfo_iterator syminfo_end() { return m_Table.end(); }
99
100  const_syminfo_iterator syminfo_begin() const { return m_Table.begin(); }
101
102  const_syminfo_iterator syminfo_end() const { return m_Table.end(); }
103
104  // freeinfo_iterator - traverse the ResolveInfo those do not need to be
105  // resolved, for example, local symbols
106  freeinfo_iterator freeinfo_begin() { return m_FreeInfoSet.begin(); }
107
108  freeinfo_iterator freeinfo_end() { return m_FreeInfoSet.end(); }
109
110  const_freeinfo_iterator freeinfo_begin() const {
111    return m_FreeInfoSet.begin();
112  }
113
114  const_freeinfo_iterator freeinfo_end() const { return m_FreeInfoSet.end(); }
115
116  // -----  capacity  ----- //
117  void reserve(size_type pN);
118
119  size_type capacity() const;
120
121 private:
122  Resolver* m_pResolver;
123  Table m_Table;
124  FreeInfoSet m_FreeInfoSet;
125
126 private:
127  DISALLOW_COPY_AND_ASSIGN(NamePool);
128};
129
130}  // namespace mcld
131
132#endif  // MCLD_LD_NAMEPOOL_H_
133