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(bool PutEmptyString = false) { |
31 | if (PutEmptyString) |
32 | getEntry(S: "" ); |
33 | } |
34 | |
35 | DwarfStringPoolEntryRef getEntry(StringRef S); |
36 | |
37 | /// Get the offset of string \p S in the string table. This can insert a new |
38 | /// element or return the offset of a pre-existing one. |
39 | uint64_t getStringOffset(StringRef S) { return getEntry(S).getOffset(); } |
40 | |
41 | /// Get permanent storage for \p S (but do not necessarily emit \p S in the |
42 | /// output section). A latter call to getStringOffset() with the same string |
43 | /// will chain it though. |
44 | /// |
45 | /// \returns The StringRef that points to permanent storage to use |
46 | /// in place of \p S. |
47 | StringRef internString(StringRef S); |
48 | |
49 | uint64_t getSize() { return CurrentEndOffset; } |
50 | |
51 | /// Return the list of strings to be emitted. This does not contain the |
52 | /// strings which were added via internString only. |
53 | std::vector<DwarfStringPoolEntryRef> getEntriesForEmission() const; |
54 | |
55 | private: |
56 | MapTy Strings; |
57 | uint64_t CurrentEndOffset = 0; |
58 | unsigned NumEntries = 0; |
59 | }; |
60 | |
61 | /// Helper for making strong types. |
62 | template <typename T, typename S> class StrongType : public T { |
63 | public: |
64 | template <typename... Args> |
65 | explicit StrongType(Args... A) : T(std::forward<Args>(A)...) {} |
66 | }; |
67 | |
68 | /// It's very easy to introduce bugs by passing the wrong string pool. |
69 | /// By using strong types the interface enforces that the right |
70 | /// kind of pool is used. |
71 | struct UniqueTag {}; |
72 | struct OffsetsTag {}; |
73 | using UniquingStringPool = StrongType<NonRelocatableStringpool, UniqueTag>; |
74 | using OffsetsStringPool = StrongType<NonRelocatableStringpool, OffsetsTag>; |
75 | |
76 | } // end namespace llvm |
77 | |
78 | #endif // LLVM_CODEGEN_NONRELOCATABLESTRINGPOOL_H |
79 | |