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 
24 namespace 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  */
31 class 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  ----- //
size()91   size_type size() const { return m_Table.numOfEntries(); }
92 
empty()93   bool empty() const { return m_Table.empty(); }
94 
95   // syminfo_iterator - traverse the ResolveInfo in the resolved HashTable
syminfo_begin()96   syminfo_iterator syminfo_begin() { return m_Table.begin(); }
97 
syminfo_end()98   syminfo_iterator syminfo_end() { return m_Table.end(); }
99 
syminfo_begin()100   const_syminfo_iterator syminfo_begin() const { return m_Table.begin(); }
101 
syminfo_end()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
freeinfo_begin()106   freeinfo_iterator freeinfo_begin() { return m_FreeInfoSet.begin(); }
107 
freeinfo_end()108   freeinfo_iterator freeinfo_end() { return m_FreeInfoSet.end(); }
109 
freeinfo_begin()110   const_freeinfo_iterator freeinfo_begin() const {
111     return m_FreeInfoSet.begin();
112   }
113 
freeinfo_end()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