1 //===- NonRelocatableStringpool.h -------------------------------*- 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_CODEGEN_NONRELOCATABLESTRINGPOOL_H
10 #define LLVM_CODEGEN_NONRELOCATABLESTRINGPOOL_H
11 
12 #include "llvm/CodeGen/DwarfStringPoolEntry.h"
13 #include "llvm/Support/Allocator.h"
14 #include <cstdint>
15 #include <vector>
16 
17 namespace llvm {
18 
19 /// A string table that doesn't need relocations.
20 ///
21 /// Use this class when a string table doesn't need relocations.
22 /// This class provides this ability by just associating offsets with strings.
23 class NonRelocatableStringpool {
24 public:
25   /// Entries are stored into the StringMap and simply linked together through
26   /// the second element of this pair in order to keep track of insertion
27   /// order.
28   using MapTy = StringMap<DwarfStringPoolEntry, BumpPtrAllocator>;
29 
30   NonRelocatableStringpool(
31       std::function<StringRef(StringRef Input)> Translator = nullptr,
32       bool PutEmptyString = false)
33       : Translator(Translator) {
34     if (PutEmptyString)
35       EmptyString = getEntry("");
36   }
37 
38   DwarfStringPoolEntryRef getEntry(StringRef S);
39 
40   /// Get the offset of string \p S in the string table. This can insert a new
41   /// element or return the offset of a pre-existing one.
42   uint32_t getStringOffset(StringRef S) { return getEntry(S).getOffset(); }
43 
44   /// Get permanent storage for \p S (but do not necessarily emit \p S in the
45   /// output section). A latter call to getStringOffset() with the same string
46   /// will chain it though.
47   ///
48   /// \returns The StringRef that points to permanent storage to use
49   /// in place of \p S.
50   StringRef internString(StringRef S);
51 
52   uint64_t getSize() { return CurrentEndOffset; }
53 
54   /// Return the list of strings to be emitted. This does not contain the
55   /// strings which were added via internString only.
56   std::vector<DwarfStringPoolEntryRef> getEntriesForEmission() const;
57 
58 private:
59   MapTy Strings;
60   uint32_t CurrentEndOffset = 0;
61   unsigned NumEntries = 0;
62   DwarfStringPoolEntryRef EmptyString;
63   std::function<StringRef(StringRef Input)> Translator;
64 };
65 
66 /// Helper for making strong types.
67 template <typename T, typename S> class StrongType : public T {
68 public:
69   template <typename... Args>
70   explicit StrongType(Args... A) : T(std::forward<Args>(A)...) {}
71 };
72 
73 /// It's very easy to introduce bugs by passing the wrong string pool.
74 /// By using strong types the interface enforces that the right
75 /// kind of pool is used.
76 struct UniqueTag {};
77 struct OffsetsTag {};
78 using UniquingStringPool = StrongType<NonRelocatableStringpool, UniqueTag>;
79 using OffsetsStringPool = StrongType<NonRelocatableStringpool, OffsetsTag>;
80 
81 } // end namespace llvm
82 
83 #endif // LLVM_CODEGEN_NONRELOCATABLESTRINGPOOL_H
84