LCOV - code coverage report
Current view: top level - lib/CodeGen/AsmPrinter - DebugLocStream.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 28 30 93.3 %
Date: 2018-10-20 13:21:21 Functions: 1 3 33.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13