1 //===- StringTableBuilder.h - String table building utility -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_MC_STRINGTABLEBUILDER_H
10 #define LLVM_MC_STRINGTABLEBUILDER_H
11 
12 #include "llvm/ADT/CachedHashString.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/Alignment.h"
16 #include <cstddef>
17 #include <cstdint>
18 
19 namespace llvm {
20 
21 class raw_ostream;
22 
23 /// Utility for building string tables with deduplicated suffixes.
24 class StringTableBuilder {
25 public:
26   enum Kind {
27     ELF,
28     WinCOFF,
29     MachO,
30     MachO64,
31     MachOLinked,
32     MachO64Linked,
33     RAW,
34     DWARF,
35     XCOFF
36   };
37 
38 private:
39   DenseMap<CachedHashStringRef, size_t> StringIndexMap;
40   size_t Size = 0;
41   Kind K;
42   Align Alignment;
43   bool Finalized = false;
44 
45   void finalizeStringTable(bool Optimize);
46   void initSize();
47 
48 public:
49   StringTableBuilder(Kind K, Align Alignment = Align(1));
50   ~StringTableBuilder();
51 
52   /// Add a string to the builder. Returns the position of S in the
53   /// table. The position will be changed if finalize is used.
54   /// Can only be used before the table is finalized.
55   size_t add(CachedHashStringRef S);
56   size_t add(StringRef S) { return add(CachedHashStringRef(S)); }
57 
58   /// Analyze the strings and build the final table. No more strings can
59   /// be added after this point.
60   void finalize();
61 
62   /// Finalize the string table without reording it. In this mode, offsets
63   /// returned by add will still be valid.
64   void finalizeInOrder();
65 
66   /// Get the offest of a string in the string table. Can only be used
67   /// after the table is finalized.
68   size_t getOffset(CachedHashStringRef S) const;
69   size_t getOffset(StringRef S) const {
70     return getOffset(CachedHashStringRef(S));
71   }
72 
73   /// Check if a string is contained in the string table. Since this class
74   /// doesn't store the string values, this function can be used to check if
75   /// storage needs to be done prior to adding the string.
76   bool contains(StringRef S) const {
77     return contains(CachedHashStringRef(S));
78   }
79   bool contains(CachedHashStringRef S) const {
80     return StringIndexMap.count(S);
81   }
82 
83   size_t getSize() const { return Size; }
84   void clear();
85 
86   void write(raw_ostream &OS) const;
87   void write(uint8_t *Buf) const;
88 
89   bool isFinalized() const { return Finalized; }
90 };
91 
92 } // end namespace llvm
93 
94 #endif // LLVM_MC_STRINGTABLEBUILDER_H
95