xref: /aosp_15_r20/external/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--- lib/CodeGen/DebugLocStream.h - DWARF debug_loc stream --*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCSTREAM_H
11*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCSTREAM_H
12*9880d681SAndroid Build Coastguard Worker 
13*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
15*9880d681SAndroid Build Coastguard Worker #include "ByteStreamer.h"
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker namespace llvm {
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker class AsmPrinter;
20*9880d681SAndroid Build Coastguard Worker class DbgVariable;
21*9880d681SAndroid Build Coastguard Worker class DwarfCompileUnit;
22*9880d681SAndroid Build Coastguard Worker class MachineInstr;
23*9880d681SAndroid Build Coastguard Worker class MCSymbol;
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker /// \brief Byte stream of .debug_loc entries.
26*9880d681SAndroid Build Coastguard Worker ///
27*9880d681SAndroid Build Coastguard Worker /// Stores a unified stream of .debug_loc entries.  There's \a List for each
28*9880d681SAndroid Build Coastguard Worker /// variable/inlined-at pair, and an \a Entry for each \a DebugLocEntry.
29*9880d681SAndroid Build Coastguard Worker ///
30*9880d681SAndroid Build Coastguard Worker /// FIXME: Do we need all these temp symbols?
31*9880d681SAndroid Build Coastguard Worker /// FIXME: Why not output directly to the output stream?
32*9880d681SAndroid Build Coastguard Worker class DebugLocStream {
33*9880d681SAndroid Build Coastguard Worker public:
34*9880d681SAndroid Build Coastguard Worker   struct List {
35*9880d681SAndroid Build Coastguard Worker     DwarfCompileUnit *CU;
36*9880d681SAndroid Build Coastguard Worker     MCSymbol *Label = nullptr;
37*9880d681SAndroid Build Coastguard Worker     size_t EntryOffset;
ListList38*9880d681SAndroid Build Coastguard Worker     List(DwarfCompileUnit *CU, size_t EntryOffset)
39*9880d681SAndroid Build Coastguard Worker         : CU(CU), EntryOffset(EntryOffset) {}
40*9880d681SAndroid Build Coastguard Worker   };
41*9880d681SAndroid Build Coastguard Worker   struct Entry {
42*9880d681SAndroid Build Coastguard Worker     const MCSymbol *BeginSym;
43*9880d681SAndroid Build Coastguard Worker     const MCSymbol *EndSym;
44*9880d681SAndroid Build Coastguard Worker     size_t ByteOffset;
45*9880d681SAndroid Build Coastguard Worker     size_t CommentOffset;
EntryEntry46*9880d681SAndroid Build Coastguard Worker     Entry(const MCSymbol *BeginSym, const MCSymbol *EndSym, size_t ByteOffset,
47*9880d681SAndroid Build Coastguard Worker           size_t CommentOffset)
48*9880d681SAndroid Build Coastguard Worker         : BeginSym(BeginSym), EndSym(EndSym), ByteOffset(ByteOffset),
49*9880d681SAndroid Build Coastguard Worker           CommentOffset(CommentOffset) {}
50*9880d681SAndroid Build Coastguard Worker   };
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker private:
53*9880d681SAndroid Build Coastguard Worker   SmallVector<List, 4> Lists;
54*9880d681SAndroid Build Coastguard Worker   SmallVector<Entry, 32> Entries;
55*9880d681SAndroid Build Coastguard Worker   SmallString<256> DWARFBytes;
56*9880d681SAndroid Build Coastguard Worker   SmallVector<std::string, 32> Comments;
57*9880d681SAndroid Build Coastguard Worker 
58*9880d681SAndroid Build Coastguard Worker   /// \brief Only verbose textual output needs comments.  This will be set to
59*9880d681SAndroid Build Coastguard Worker   /// true for that case, and false otherwise.
60*9880d681SAndroid Build Coastguard Worker   bool GenerateComments;
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker public:
DebugLocStream(bool GenerateComments)63*9880d681SAndroid Build Coastguard Worker   DebugLocStream(bool GenerateComments) : GenerateComments(GenerateComments) { }
getNumLists()64*9880d681SAndroid Build Coastguard Worker   size_t getNumLists() const { return Lists.size(); }
getList(size_t LI)65*9880d681SAndroid Build Coastguard Worker   const List &getList(size_t LI) const { return Lists[LI]; }
getLists()66*9880d681SAndroid Build Coastguard Worker   ArrayRef<List> getLists() const { return Lists; }
67*9880d681SAndroid Build Coastguard Worker 
68*9880d681SAndroid Build Coastguard Worker   class ListBuilder;
69*9880d681SAndroid Build Coastguard Worker   class EntryBuilder;
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker private:
72*9880d681SAndroid Build Coastguard Worker   /// \brief Start a new .debug_loc entry list.
73*9880d681SAndroid Build Coastguard Worker   ///
74*9880d681SAndroid Build Coastguard Worker   /// Start a new .debug_loc entry list.  Return the new list's index so it can
75*9880d681SAndroid Build Coastguard Worker   /// be retrieved later via \a getList().
76*9880d681SAndroid Build Coastguard Worker   ///
77*9880d681SAndroid Build Coastguard Worker   /// Until the next call, \a startEntry() will add entries to this list.
startList(DwarfCompileUnit * CU)78*9880d681SAndroid Build Coastguard Worker   size_t startList(DwarfCompileUnit *CU) {
79*9880d681SAndroid Build Coastguard Worker     size_t LI = Lists.size();
80*9880d681SAndroid Build Coastguard Worker     Lists.emplace_back(CU, Entries.size());
81*9880d681SAndroid Build Coastguard Worker     return LI;
82*9880d681SAndroid Build Coastguard Worker   }
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   /// Finalize a .debug_loc entry list.
85*9880d681SAndroid Build Coastguard Worker   ///
86*9880d681SAndroid Build Coastguard Worker   /// If there are no entries in this list, delete it outright.  Otherwise,
87*9880d681SAndroid Build Coastguard Worker   /// create a label with \a Asm.
88*9880d681SAndroid Build Coastguard Worker   ///
89*9880d681SAndroid Build Coastguard Worker   /// \return false iff the list is deleted.
90*9880d681SAndroid Build Coastguard Worker   bool finalizeList(AsmPrinter &Asm);
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker   /// \brief Start a new .debug_loc entry.
93*9880d681SAndroid Build Coastguard Worker   ///
94*9880d681SAndroid Build Coastguard Worker   /// Until the next call, bytes added to the stream will be added to this
95*9880d681SAndroid Build Coastguard Worker   /// entry.
startEntry(const MCSymbol * BeginSym,const MCSymbol * EndSym)96*9880d681SAndroid Build Coastguard Worker   void startEntry(const MCSymbol *BeginSym, const MCSymbol *EndSym) {
97*9880d681SAndroid Build Coastguard Worker     Entries.emplace_back(BeginSym, EndSym, DWARFBytes.size(), Comments.size());
98*9880d681SAndroid Build Coastguard Worker   }
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   /// Finalize a .debug_loc entry, deleting if it's empty.
101*9880d681SAndroid Build Coastguard Worker   void finalizeEntry();
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker public:
getStreamer()104*9880d681SAndroid Build Coastguard Worker   BufferByteStreamer getStreamer() {
105*9880d681SAndroid Build Coastguard Worker     return BufferByteStreamer(DWARFBytes, Comments, GenerateComments);
106*9880d681SAndroid Build Coastguard Worker   }
107*9880d681SAndroid Build Coastguard Worker 
getEntries(const List & L)108*9880d681SAndroid Build Coastguard Worker   ArrayRef<Entry> getEntries(const List &L) const {
109*9880d681SAndroid Build Coastguard Worker     size_t LI = getIndex(L);
110*9880d681SAndroid Build Coastguard Worker     return makeArrayRef(Entries)
111*9880d681SAndroid Build Coastguard Worker         .slice(Lists[LI].EntryOffset, getNumEntries(LI));
112*9880d681SAndroid Build Coastguard Worker   }
113*9880d681SAndroid Build Coastguard Worker 
getBytes(const Entry & E)114*9880d681SAndroid Build Coastguard Worker   ArrayRef<char> getBytes(const Entry &E) const {
115*9880d681SAndroid Build Coastguard Worker     size_t EI = getIndex(E);
116*9880d681SAndroid Build Coastguard Worker     return makeArrayRef(DWARFBytes.begin(), DWARFBytes.end())
117*9880d681SAndroid Build Coastguard Worker         .slice(Entries[EI].ByteOffset, getNumBytes(EI));
118*9880d681SAndroid Build Coastguard Worker   }
getComments(const Entry & E)119*9880d681SAndroid Build Coastguard Worker   ArrayRef<std::string> getComments(const Entry &E) const {
120*9880d681SAndroid Build Coastguard Worker     size_t EI = getIndex(E);
121*9880d681SAndroid Build Coastguard Worker     return makeArrayRef(Comments)
122*9880d681SAndroid Build Coastguard Worker         .slice(Entries[EI].CommentOffset, getNumComments(EI));
123*9880d681SAndroid Build Coastguard Worker   }
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker private:
getIndex(const List & L)126*9880d681SAndroid Build Coastguard Worker   size_t getIndex(const List &L) const {
127*9880d681SAndroid Build Coastguard Worker     assert(&Lists.front() <= &L && &L <= &Lists.back() &&
128*9880d681SAndroid Build Coastguard Worker            "Expected valid list");
129*9880d681SAndroid Build Coastguard Worker     return &L - &Lists.front();
130*9880d681SAndroid Build Coastguard Worker   }
getIndex(const Entry & E)131*9880d681SAndroid Build Coastguard Worker   size_t getIndex(const Entry &E) const {
132*9880d681SAndroid Build Coastguard Worker     assert(&Entries.front() <= &E && &E <= &Entries.back() &&
133*9880d681SAndroid Build Coastguard Worker            "Expected valid entry");
134*9880d681SAndroid Build Coastguard Worker     return &E - &Entries.front();
135*9880d681SAndroid Build Coastguard Worker   }
getNumEntries(size_t LI)136*9880d681SAndroid Build Coastguard Worker   size_t getNumEntries(size_t LI) const {
137*9880d681SAndroid Build Coastguard Worker     if (LI + 1 == Lists.size())
138*9880d681SAndroid Build Coastguard Worker       return Entries.size() - Lists[LI].EntryOffset;
139*9880d681SAndroid Build Coastguard Worker     return Lists[LI + 1].EntryOffset - Lists[LI].EntryOffset;
140*9880d681SAndroid Build Coastguard Worker   }
getNumBytes(size_t EI)141*9880d681SAndroid Build Coastguard Worker   size_t getNumBytes(size_t EI) const {
142*9880d681SAndroid Build Coastguard Worker     if (EI + 1 == Entries.size())
143*9880d681SAndroid Build Coastguard Worker       return DWARFBytes.size() - Entries[EI].ByteOffset;
144*9880d681SAndroid Build Coastguard Worker     return Entries[EI + 1].ByteOffset - Entries[EI].ByteOffset;
145*9880d681SAndroid Build Coastguard Worker   }
getNumComments(size_t EI)146*9880d681SAndroid Build Coastguard Worker   size_t getNumComments(size_t EI) const {
147*9880d681SAndroid Build Coastguard Worker     if (EI + 1 == Entries.size())
148*9880d681SAndroid Build Coastguard Worker       return Comments.size() - Entries[EI].CommentOffset;
149*9880d681SAndroid Build Coastguard Worker     return Entries[EI + 1].CommentOffset - Entries[EI].CommentOffset;
150*9880d681SAndroid Build Coastguard Worker   }
151*9880d681SAndroid Build Coastguard Worker };
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker /// Builder for DebugLocStream lists.
154*9880d681SAndroid Build Coastguard Worker class DebugLocStream::ListBuilder {
155*9880d681SAndroid Build Coastguard Worker   DebugLocStream &Locs;
156*9880d681SAndroid Build Coastguard Worker   AsmPrinter &Asm;
157*9880d681SAndroid Build Coastguard Worker   DbgVariable &V;
158*9880d681SAndroid Build Coastguard Worker   const MachineInstr &MI;
159*9880d681SAndroid Build Coastguard Worker   size_t ListIndex;
160*9880d681SAndroid Build Coastguard Worker 
161*9880d681SAndroid Build Coastguard Worker public:
ListBuilder(DebugLocStream & Locs,DwarfCompileUnit & CU,AsmPrinter & Asm,DbgVariable & V,const MachineInstr & MI)162*9880d681SAndroid Build Coastguard Worker   ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm,
163*9880d681SAndroid Build Coastguard Worker               DbgVariable &V, const MachineInstr &MI)
164*9880d681SAndroid Build Coastguard Worker       : Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)) {}
165*9880d681SAndroid Build Coastguard Worker 
166*9880d681SAndroid Build Coastguard Worker   /// Finalize the list.
167*9880d681SAndroid Build Coastguard Worker   ///
168*9880d681SAndroid Build Coastguard Worker   /// If the list is empty, delete it.  Otherwise, finalize it by creating a
169*9880d681SAndroid Build Coastguard Worker   /// temp symbol in \a Asm and setting up the \a DbgVariable.
170*9880d681SAndroid Build Coastguard Worker   ~ListBuilder();
171*9880d681SAndroid Build Coastguard Worker 
getLocs()172*9880d681SAndroid Build Coastguard Worker   DebugLocStream &getLocs() { return Locs; }
173*9880d681SAndroid Build Coastguard Worker };
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker /// Builder for DebugLocStream entries.
176*9880d681SAndroid Build Coastguard Worker class DebugLocStream::EntryBuilder {
177*9880d681SAndroid Build Coastguard Worker   DebugLocStream &Locs;
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker public:
EntryBuilder(ListBuilder & List,const MCSymbol * Begin,const MCSymbol * End)180*9880d681SAndroid Build Coastguard Worker   EntryBuilder(ListBuilder &List, const MCSymbol *Begin, const MCSymbol *End)
181*9880d681SAndroid Build Coastguard Worker       : Locs(List.getLocs()) {
182*9880d681SAndroid Build Coastguard Worker     Locs.startEntry(Begin, End);
183*9880d681SAndroid Build Coastguard Worker   }
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker   /// Finalize the entry, deleting it if it's empty.
~EntryBuilder()186*9880d681SAndroid Build Coastguard Worker   ~EntryBuilder() { Locs.finalizeEntry(); }
187*9880d681SAndroid Build Coastguard Worker 
getStreamer()188*9880d681SAndroid Build Coastguard Worker   BufferByteStreamer getStreamer() { return Locs.getStreamer(); }
189*9880d681SAndroid Build Coastguard Worker };
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker } // namespace llvm
192*9880d681SAndroid Build Coastguard Worker 
193*9880d681SAndroid Build Coastguard Worker #endif
194