NonRelocatableStringpool.h revision 360784
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
17namespace 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.
23class NonRelocatableStringpool {
24public:
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
58private:
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.
67template <typename T, typename S> class StrongType : public T {
68public:
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.
76struct UniqueTag {};
77struct OffsetsTag {};
78using UniquingStringPool = StrongType<NonRelocatableStringpool, UniqueTag>;
79using OffsetsStringPool = StrongType<NonRelocatableStringpool, OffsetsTag>;
80
81} // end namespace llvm
82
83#endif // LLVM_CODEGEN_NONRELOCATABLESTRINGPOOL_H
84