1280461Sdim//===- Core/SymbolTable.h - Main Symbol Table -----------------------------===//
2280461Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6280461Sdim//
7280461Sdim//===----------------------------------------------------------------------===//
8280461Sdim
9280461Sdim#ifndef LLD_CORE_SYMBOL_TABLE_H
10280461Sdim#define LLD_CORE_SYMBOL_TABLE_H
11280461Sdim
12327952Sdim#include "lld/Common/LLVM.h"
13280461Sdim#include "llvm/ADT/DenseSet.h"
14341825Sdim#include "llvm/Support/DJB.h"
15280461Sdim#include <cstring>
16280461Sdim#include <map>
17280461Sdim#include <vector>
18280461Sdim
19280461Sdimnamespace lld {
20280461Sdim
21280461Sdimclass AbsoluteAtom;
22280461Sdimclass Atom;
23280461Sdimclass DefinedAtom;
24280461Sdimclass LinkingContext;
25280461Sdimclass ResolverOptions;
26280461Sdimclass SharedLibraryAtom;
27280461Sdimclass UndefinedAtom;
28280461Sdim
29341825Sdim/// The SymbolTable class is responsible for coalescing atoms.
30280461Sdim///
31280461Sdim/// All atoms coalescable by-name or by-content should be added.
32280461Sdim/// The method replacement() can be used to find the replacement atom
33280461Sdim/// if an atom has been coalesced away.
34280461Sdimclass SymbolTable {
35280461Sdimpublic:
36341825Sdim  /// add atom to symbol table
37280461Sdim  bool add(const DefinedAtom &);
38280461Sdim
39341825Sdim  /// add atom to symbol table
40280461Sdim  bool add(const UndefinedAtom &);
41280461Sdim
42341825Sdim  /// add atom to symbol table
43280461Sdim  bool add(const SharedLibraryAtom &);
44280461Sdim
45341825Sdim  /// add atom to symbol table
46280461Sdim  bool add(const AbsoluteAtom &);
47280461Sdim
48341825Sdim  /// returns atom in symbol table for specified name (or nullptr)
49280461Sdim  const Atom *findByName(StringRef sym);
50280461Sdim
51341825Sdim  /// returns vector of remaining UndefinedAtoms
52280461Sdim  std::vector<const UndefinedAtom *> undefines();
53280461Sdim
54341825Sdim  /// if atom has been coalesced away, return replacement, else return atom
55280461Sdim  const Atom *replacement(const Atom *);
56280461Sdim
57341825Sdim  /// if atom has been coalesced away, return true
58280461Sdim  bool isCoalescedAway(const Atom *);
59280461Sdim
60280461Sdimprivate:
61280461Sdim  typedef llvm::DenseMap<const Atom *, const Atom *> AtomToAtom;
62280461Sdim
63280461Sdim  struct StringRefMappingInfo {
64280461Sdim    static StringRef getEmptyKey() { return StringRef(); }
65280461Sdim    static StringRef getTombstoneKey() { return StringRef(" ", 1); }
66280461Sdim    static unsigned getHashValue(StringRef const val) {
67341825Sdim      return llvm::djbHash(val, 0);
68280461Sdim    }
69280461Sdim    static bool isEqual(StringRef const lhs, StringRef const rhs) {
70280461Sdim      return lhs.equals(rhs);
71280461Sdim    }
72280461Sdim  };
73280461Sdim  typedef llvm::DenseMap<StringRef, const Atom *,
74280461Sdim                                           StringRefMappingInfo> NameToAtom;
75280461Sdim
76280461Sdim  struct AtomMappingInfo {
77280461Sdim    static const DefinedAtom * getEmptyKey() { return nullptr; }
78280461Sdim    static const DefinedAtom * getTombstoneKey() { return (DefinedAtom*)(-1); }
79280461Sdim    static unsigned getHashValue(const DefinedAtom * const Val);
80280461Sdim    static bool isEqual(const DefinedAtom * const LHS,
81280461Sdim                        const DefinedAtom * const RHS);
82280461Sdim  };
83280461Sdim  typedef llvm::DenseSet<const DefinedAtom*, AtomMappingInfo> AtomContentSet;
84280461Sdim
85280461Sdim  bool addByName(const Atom &);
86280461Sdim  bool addByContent(const DefinedAtom &);
87280461Sdim
88280461Sdim  AtomToAtom _replacedAtoms;
89280461Sdim  NameToAtom _nameTable;
90280461Sdim  AtomContentSet _contentTable;
91280461Sdim};
92280461Sdim
93280461Sdim} // namespace lld
94280461Sdim
95280461Sdim#endif // LLD_CORE_SYMBOL_TABLE_H
96