10b57cec5SDimitry Andric //===- llvm/CodeGen/DwarfStringPoolEntry.h - String pool entry --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_DWARFSTRINGPOOLENTRY_H
100b57cec5SDimitry Andric #define LLVM_CODEGEN_DWARFSTRINGPOOLENTRY_H
110b57cec5SDimitry Andric 
1281ad6265SDimitry Andric #include "llvm/ADT/PointerUnion.h"
130b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric namespace llvm {
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric class MCSymbol;
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric /// Data for a string pool entry.
200b57cec5SDimitry Andric struct DwarfStringPoolEntry {
210b57cec5SDimitry Andric   static constexpr unsigned NotIndexed = -1;
220b57cec5SDimitry Andric 
2381ad6265SDimitry Andric   MCSymbol *Symbol = nullptr;
2481ad6265SDimitry Andric   uint64_t Offset = 0;
2581ad6265SDimitry Andric   unsigned Index = 0;
260b57cec5SDimitry Andric 
isIndexedDwarfStringPoolEntry270b57cec5SDimitry Andric   bool isIndexed() const { return Index != NotIndexed; }
280b57cec5SDimitry Andric };
290b57cec5SDimitry Andric 
305f757f3fSDimitry Andric /// DwarfStringPoolEntry with string keeping externally.
315f757f3fSDimitry Andric struct DwarfStringPoolEntryWithExtString : public DwarfStringPoolEntry {
325f757f3fSDimitry Andric   StringRef String;
335f757f3fSDimitry Andric };
345f757f3fSDimitry Andric 
3581ad6265SDimitry Andric /// DwarfStringPoolEntryRef: Dwarf string pool entry reference.
3681ad6265SDimitry Andric ///
3781ad6265SDimitry Andric /// Dwarf string pool entry keeps string value and its data.
3881ad6265SDimitry Andric /// There are two variants how data are represented:
3981ad6265SDimitry Andric ///
405f757f3fSDimitry Andric ///   1. String data in pool  - StringMapEntry<DwarfStringPoolEntry>.
415f757f3fSDimitry Andric ///   2. External string data - DwarfStringPoolEntryWithExtString.
4281ad6265SDimitry Andric ///
435f757f3fSDimitry Andric /// The external data variant allows reducing memory usage for the case
445f757f3fSDimitry Andric /// when string pool entry does not have data: string entry does not
455f757f3fSDimitry Andric /// keep any data and so no need to waste space for the full
465f757f3fSDimitry Andric /// DwarfStringPoolEntry. It is recommended to use external variant if not all
475f757f3fSDimitry Andric /// entries of dwarf string pool have corresponding DwarfStringPoolEntry.
480b57cec5SDimitry Andric 
4981ad6265SDimitry Andric class DwarfStringPoolEntryRef {
5081ad6265SDimitry Andric   /// Pointer type for "By value" string entry.
5181ad6265SDimitry Andric   using ByValStringEntryPtr = const StringMapEntry<DwarfStringPoolEntry> *;
5281ad6265SDimitry Andric 
535f757f3fSDimitry Andric   /// Pointer type for external string entry.
545f757f3fSDimitry Andric   using ExtStringEntryPtr = const DwarfStringPoolEntryWithExtString *;
5581ad6265SDimitry Andric 
5681ad6265SDimitry Andric   /// Pointer to the dwarf string pool Entry.
575f757f3fSDimitry Andric   PointerUnion<ByValStringEntryPtr, ExtStringEntryPtr> MapEntry = nullptr;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric public:
600b57cec5SDimitry Andric   DwarfStringPoolEntryRef() = default;
610b57cec5SDimitry Andric 
6281ad6265SDimitry Andric   /// ASSUMPTION: DwarfStringPoolEntryRef keeps pointer to \p Entry,
6381ad6265SDimitry Andric   /// thus specified entry mustn`t be reallocated.
DwarfStringPoolEntryRef(const StringMapEntry<DwarfStringPoolEntry> & Entry)6481ad6265SDimitry Andric   DwarfStringPoolEntryRef(const StringMapEntry<DwarfStringPoolEntry> &Entry)
6581ad6265SDimitry Andric       : MapEntry(&Entry) {}
6681ad6265SDimitry Andric 
6781ad6265SDimitry Andric   /// ASSUMPTION: DwarfStringPoolEntryRef keeps pointer to \p Entry,
6881ad6265SDimitry Andric   /// thus specified entry mustn`t be reallocated.
DwarfStringPoolEntryRef(const DwarfStringPoolEntryWithExtString & Entry)695f757f3fSDimitry Andric   DwarfStringPoolEntryRef(const DwarfStringPoolEntryWithExtString &Entry)
705f757f3fSDimitry Andric       : MapEntry(&Entry) {}
7181ad6265SDimitry Andric 
7281ad6265SDimitry Andric   explicit operator bool() const { return !MapEntry.isNull(); }
7381ad6265SDimitry Andric 
7481ad6265SDimitry Andric   /// \returns symbol for the dwarf string.
getSymbol()750b57cec5SDimitry Andric   MCSymbol *getSymbol() const {
7681ad6265SDimitry Andric     assert(getEntry().Symbol && "No symbol available!");
7781ad6265SDimitry Andric     return getEntry().Symbol;
780b57cec5SDimitry Andric   }
7981ad6265SDimitry Andric 
8081ad6265SDimitry Andric   /// \returns offset for the dwarf string.
getOffset()8181ad6265SDimitry Andric   uint64_t getOffset() const { return getEntry().Offset; }
8281ad6265SDimitry Andric 
8381ad6265SDimitry Andric   /// \returns index for the dwarf string.
getIndex()840b57cec5SDimitry Andric   unsigned getIndex() const {
8581ad6265SDimitry Andric     assert(getEntry().isIndexed() && "Index is not set!");
8681ad6265SDimitry Andric     return getEntry().Index;
870b57cec5SDimitry Andric   }
8881ad6265SDimitry Andric 
8981ad6265SDimitry Andric   /// \returns string.
getString()9081ad6265SDimitry Andric   StringRef getString() const {
9106c3fb27SDimitry Andric     if (isa<ByValStringEntryPtr>(MapEntry))
9206c3fb27SDimitry Andric       return cast<ByValStringEntryPtr>(MapEntry)->first();
9381ad6265SDimitry Andric 
945f757f3fSDimitry Andric     return cast<ExtStringEntryPtr>(MapEntry)->String;
9581ad6265SDimitry Andric   }
9681ad6265SDimitry Andric 
9781ad6265SDimitry Andric   /// \returns the entire string pool entry for convenience.
getEntry()9881ad6265SDimitry Andric   const DwarfStringPoolEntry &getEntry() const {
9906c3fb27SDimitry Andric     if (isa<ByValStringEntryPtr>(MapEntry))
10006c3fb27SDimitry Andric       return cast<ByValStringEntryPtr>(MapEntry)->second;
10181ad6265SDimitry Andric 
1025f757f3fSDimitry Andric     return *cast<ExtStringEntryPtr>(MapEntry);
10381ad6265SDimitry Andric   }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   bool operator==(const DwarfStringPoolEntryRef &X) const {
10681ad6265SDimitry Andric     return MapEntry.getOpaqueValue() == X.MapEntry.getOpaqueValue();
1070b57cec5SDimitry Andric   }
10881ad6265SDimitry Andric 
1090b57cec5SDimitry Andric   bool operator!=(const DwarfStringPoolEntryRef &X) const {
11081ad6265SDimitry Andric     return MapEntry.getOpaqueValue() != X.MapEntry.getOpaqueValue();
1110b57cec5SDimitry Andric   }
1120b57cec5SDimitry Andric };
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric } // end namespace llvm
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric #endif
117