10b57cec5SDimitry Andric //===- llvm/CodeGen/DwarfFile.h - Dwarf Debug Framework ---------*- 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_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H
100b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "DwarfStringPool.h"
130b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
140b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h"
170b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
180b57cec5SDimitry Andric #include <map>
190b57cec5SDimitry Andric #include <memory>
200b57cec5SDimitry Andric #include <utility>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric class AsmPrinter;
250b57cec5SDimitry Andric class DbgEntity;
260b57cec5SDimitry Andric class DbgVariable;
270b57cec5SDimitry Andric class DbgLabel;
28e8d8bef9SDimitry Andric class DINode;
2906c3fb27SDimitry Andric class DILocalScope;
300b57cec5SDimitry Andric class DwarfCompileUnit;
310b57cec5SDimitry Andric class DwarfUnit;
320b57cec5SDimitry Andric class LexicalScope;
330b57cec5SDimitry Andric class MCSection;
34e8d8bef9SDimitry Andric class MDNode;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric // Data structure to hold a range for range lists.
378bcb0991SDimitry Andric struct RangeSpan {
388bcb0991SDimitry Andric   const MCSymbol *Begin;
398bcb0991SDimitry Andric   const MCSymbol *End;
400b57cec5SDimitry Andric };
410b57cec5SDimitry Andric 
42480093f4SDimitry Andric struct RangeSpanList {
430b57cec5SDimitry Andric   // Index for locating within the debug_range section this particular span.
44480093f4SDimitry Andric   MCSymbol *Label;
450b57cec5SDimitry Andric   const DwarfCompileUnit *CU;
460b57cec5SDimitry Andric   // List of ranges.
470b57cec5SDimitry Andric   SmallVector<RangeSpan, 2> Ranges;
480b57cec5SDimitry Andric };
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric class DwarfFile {
510b57cec5SDimitry Andric   // Target of Dwarf emission, used for sizing of abbreviations.
520b57cec5SDimitry Andric   AsmPrinter *Asm;
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   BumpPtrAllocator AbbrevAllocator;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   // Used to uniquely define abbreviations.
570b57cec5SDimitry Andric   DIEAbbrevSet Abbrevs;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   // A pointer to all units in the section.
600b57cec5SDimitry Andric   SmallVector<std::unique_ptr<DwarfCompileUnit>, 1> CUs;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   DwarfStringPool StrPool;
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   // List of range lists for a given compile unit, separate from the ranges for
650b57cec5SDimitry Andric   // the CU itself.
660b57cec5SDimitry Andric   SmallVector<RangeSpanList, 1> CURangeLists;
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   /// DWARF v5: The symbol that designates the start of the contribution to
690b57cec5SDimitry Andric   /// the string offsets table. The contribution is shared by all units.
700b57cec5SDimitry Andric   MCSymbol *StringOffsetsStartSym = nullptr;
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric   /// DWARF v5: The symbol that designates the base of the range list table.
730b57cec5SDimitry Andric   /// The table is shared by all units.
740b57cec5SDimitry Andric   MCSymbol *RnglistsTableBaseSym = nullptr;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   /// The variables of a lexical scope.
770b57cec5SDimitry Andric   struct ScopeVars {
780b57cec5SDimitry Andric     /// We need to sort Args by ArgNo and check for duplicates. This could also
790b57cec5SDimitry Andric     /// be implemented as a list or vector + std::lower_bound().
800b57cec5SDimitry Andric     std::map<unsigned, DbgVariable *> Args;
810b57cec5SDimitry Andric     SmallVector<DbgVariable *, 8> Locals;
820b57cec5SDimitry Andric   };
830b57cec5SDimitry Andric   /// Collection of DbgVariables of each lexical scope.
840b57cec5SDimitry Andric   DenseMap<LexicalScope *, ScopeVars> ScopeVariables;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   /// Collection of DbgLabels of each lexical scope.
870b57cec5SDimitry Andric   using LabelList = SmallVector<DbgLabel *, 4>;
880b57cec5SDimitry Andric   DenseMap<LexicalScope *, LabelList> ScopeLabels;
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   // Collection of abstract subprogram DIEs.
9106c3fb27SDimitry Andric   DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
920b57cec5SDimitry Andric   DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   /// Maps MDNodes for type system with the corresponding DIEs. These DIEs can
950b57cec5SDimitry Andric   /// be shared across CUs, that is why we keep the map here instead
960b57cec5SDimitry Andric   /// of in DwarfCompileUnit.
970b57cec5SDimitry Andric   DenseMap<const MDNode *, DIE *> DITypeNodeToDieMap;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric public:
1000b57cec5SDimitry Andric   DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA);
1010b57cec5SDimitry Andric 
getUnits()1020b57cec5SDimitry Andric   const SmallVectorImpl<std::unique_ptr<DwarfCompileUnit>> &getUnits() {
1030b57cec5SDimitry Andric     return CUs;
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   std::pair<uint32_t, RangeSpanList *> addRange(const DwarfCompileUnit &CU,
1070b57cec5SDimitry Andric                                                 SmallVector<RangeSpan, 2> R);
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   /// getRangeLists - Get the vector of range lists.
getRangeLists()1100b57cec5SDimitry Andric   const SmallVectorImpl<RangeSpanList> &getRangeLists() const {
1110b57cec5SDimitry Andric     return CURangeLists;
1120b57cec5SDimitry Andric   }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   /// Compute the size and offset of a DIE given an incoming Offset.
1150b57cec5SDimitry Andric   unsigned computeSizeAndOffset(DIE &Die, unsigned Offset);
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   /// Compute the size and offset of all the DIEs.
1180b57cec5SDimitry Andric   void computeSizeAndOffsets();
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   /// Compute the size and offset of all the DIEs in the given unit.
1210b57cec5SDimitry Andric   /// \returns The size of the root DIE.
1220b57cec5SDimitry Andric   unsigned computeSizeAndOffsetsForUnit(DwarfUnit *TheU);
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   /// Add a unit to the list of CUs.
1250b57cec5SDimitry Andric   void addUnit(std::unique_ptr<DwarfCompileUnit> U);
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   /// Emit all of the units to the section listed with the given
1280b57cec5SDimitry Andric   /// abbreviation section.
1290b57cec5SDimitry Andric   void emitUnits(bool UseOffsets);
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   /// Emit the given unit to its section.
1320b57cec5SDimitry Andric   void emitUnit(DwarfUnit *TheU, bool UseOffsets);
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   /// Emit a set of abbreviations to the specific section.
1350b57cec5SDimitry Andric   void emitAbbrevs(MCSection *);
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   /// Emit all of the strings to the section given. If OffsetSection is
1380b57cec5SDimitry Andric   /// non-null, emit a table of string offsets to it. If UseRelativeOffsets
1390b57cec5SDimitry Andric   /// is false, emit absolute offsets to the strings. Otherwise, emit
1400b57cec5SDimitry Andric   /// relocatable references to the strings if they are supported by the target.
1410b57cec5SDimitry Andric   void emitStrings(MCSection *StrSection, MCSection *OffsetSection = nullptr,
1420b57cec5SDimitry Andric                    bool UseRelativeOffsets = false);
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   /// Returns the string pool.
getStringPool()1450b57cec5SDimitry Andric   DwarfStringPool &getStringPool() { return StrPool; }
1460b57cec5SDimitry Andric 
getStringOffsetsStartSym()1470b57cec5SDimitry Andric   MCSymbol *getStringOffsetsStartSym() const { return StringOffsetsStartSym; }
setStringOffsetsStartSym(MCSymbol * Sym)1480b57cec5SDimitry Andric   void setStringOffsetsStartSym(MCSymbol *Sym) { StringOffsetsStartSym = Sym; }
1490b57cec5SDimitry Andric 
getRnglistsTableBaseSym()1500b57cec5SDimitry Andric   MCSymbol *getRnglistsTableBaseSym() const { return RnglistsTableBaseSym; }
setRnglistsTableBaseSym(MCSymbol * Sym)1510b57cec5SDimitry Andric   void setRnglistsTableBaseSym(MCSymbol *Sym) { RnglistsTableBaseSym = Sym; }
1520b57cec5SDimitry Andric 
1535f757f3fSDimitry Andric   void addScopeVariable(LexicalScope *LS, DbgVariable *Var);
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   void addScopeLabel(LexicalScope *LS, DbgLabel *Label);
1560b57cec5SDimitry Andric 
getScopeVariables()1570b57cec5SDimitry Andric   DenseMap<LexicalScope *, ScopeVars> &getScopeVariables() {
1580b57cec5SDimitry Andric     return ScopeVariables;
1590b57cec5SDimitry Andric   }
1600b57cec5SDimitry Andric 
getScopeLabels()1610b57cec5SDimitry Andric   DenseMap<LexicalScope *, LabelList> &getScopeLabels() {
1620b57cec5SDimitry Andric     return ScopeLabels;
1630b57cec5SDimitry Andric   }
1640b57cec5SDimitry Andric 
getAbstractScopeDIEs()16506c3fb27SDimitry Andric   DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {
16606c3fb27SDimitry Andric     return AbstractLocalScopeDIEs;
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric 
getAbstractEntities()1690b57cec5SDimitry Andric   DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
1700b57cec5SDimitry Andric     return AbstractEntities;
1710b57cec5SDimitry Andric   }
1720b57cec5SDimitry Andric 
insertDIE(const MDNode * TypeMD,DIE * Die)1730b57cec5SDimitry Andric   void insertDIE(const MDNode *TypeMD, DIE *Die) {
1740b57cec5SDimitry Andric     DITypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
1750b57cec5SDimitry Andric   }
1760b57cec5SDimitry Andric 
getDIE(const MDNode * TypeMD)1770b57cec5SDimitry Andric   DIE *getDIE(const MDNode *TypeMD) {
1780b57cec5SDimitry Andric     return DITypeNodeToDieMap.lookup(TypeMD);
1790b57cec5SDimitry Andric   }
1800b57cec5SDimitry Andric };
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric } // end namespace llvm
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H
185