Home | History | Annotate | Line # | Download | only in CodeGen
      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   uint64_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   uint64_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