//===--- lib/CodeGen/DebugLocStream.h - DWARF debug_loc stream --*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCSTREAM_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCSTREAM_H

#include "ByteStreamer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"

namespace llvm {

class AsmPrinter;
class DbgVariable;
class DwarfCompileUnit;
class MachineInstr;
class MCSymbol;

/// Byte stream of .debug_loc entries.
///
/// Stores a unified stream of .debug_loc entries.  There's \a List for each
/// variable/inlined-at pair, and an \a Entry for each \a DebugLocEntry.
///
/// FIXME: Do we need all these temp symbols?
/// FIXME: Why not output directly to the output stream?
class DebugLocStream {
public:
  struct List {
    DwarfCompileUnit *CU;
    MCSymbol *Label = nullptr;
    size_t EntryOffset;
    List(DwarfCompileUnit *CU, size_t EntryOffset)
        : CU(CU), EntryOffset(EntryOffset) {}
  };
  struct Entry {
    const MCSymbol *Begin;
    const MCSymbol *End;
    size_t ByteOffset;
    size_t CommentOffset;
  };

private:
  SmallVector<List, 4> Lists;
  SmallVector<Entry, 32> Entries;
  SmallString<256> DWARFBytes;
  std::vector<std::string> Comments;
  MCSymbol *Sym;

  /// Only verbose textual output needs comments.  This will be set to
  /// true for that case, and false otherwise.
  bool GenerateComments;

public:
  DebugLocStream(bool GenerateComments) : GenerateComments(GenerateComments) { }
  size_t getNumLists() const { return Lists.size(); }
  const List &getList(size_t LI) const { return Lists[LI]; }
  ArrayRef<List> getLists() const { return Lists; }
  MCSymbol *getSym() const {
    return Sym;
  }
  void setSym(MCSymbol *Sym) {
    this->Sym = Sym;
  }

  class ListBuilder;
  class EntryBuilder;

private:
  /// Start a new .debug_loc entry list.
  ///
  /// Start a new .debug_loc entry list.  Return the new list's index so it can
  /// be retrieved later via \a getList().
  ///
  /// Until the next call, \a startEntry() will add entries to this list.
  size_t startList(DwarfCompileUnit *CU) {
    size_t LI = Lists.size();
    Lists.emplace_back(CU, Entries.size());
    return LI;
  }

  /// Finalize a .debug_loc entry list.
  ///
  /// If there are no entries in this list, delete it outright.  Otherwise,
  /// create a label with \a Asm.
  ///
  /// \return false iff the list is deleted.
  bool finalizeList(AsmPrinter &Asm);

  /// Start a new .debug_loc entry.
  ///
  /// Until the next call, bytes added to the stream will be added to this
  /// entry.
  void startEntry(const MCSymbol *BeginSym, const MCSymbol *EndSym) {
    Entries.push_back({BeginSym, EndSym, DWARFBytes.size(), Comments.size()});
  }

  /// Finalize a .debug_loc entry, deleting if it's empty.
  void finalizeEntry();

public:
  BufferByteStreamer getStreamer() {
    return BufferByteStreamer(DWARFBytes, Comments, GenerateComments);
  }

  ArrayRef<Entry> getEntries(const List &L) const {
    size_t LI = getIndex(L);
    return makeArrayRef(Entries)
        .slice(Lists[LI].EntryOffset, getNumEntries(LI));
  }

  ArrayRef<char> getBytes(const Entry &E) const {
    size_t EI = getIndex(E);
    return makeArrayRef(DWARFBytes.begin(), DWARFBytes.end())
        .slice(Entries[EI].ByteOffset, getNumBytes(EI));
  }
  ArrayRef<std::string> getComments(const Entry &E) const {
    size_t EI = getIndex(E);
    return makeArrayRef(Comments)
        .slice(Entries[EI].CommentOffset, getNumComments(EI));
  }

private:
  size_t getIndex(const List &L) const {
    assert(&Lists.front() <= &L && &L <= &Lists.back() &&
           "Expected valid list");
    return &L - &Lists.front();
  }
  size_t getIndex(const Entry &E) const {
    assert(&Entries.front() <= &E && &E <= &Entries.back() &&
           "Expected valid entry");
    return &E - &Entries.front();
  }
  size_t getNumEntries(size_t LI) const {
    if (LI + 1 == Lists.size())
      return Entries.size() - Lists[LI].EntryOffset;
    return Lists[LI + 1].EntryOffset - Lists[LI].EntryOffset;
  }
  size_t getNumBytes(size_t EI) const {
    if (EI + 1 == Entries.size())
      return DWARFBytes.size() - Entries[EI].ByteOffset;
    return Entries[EI + 1].ByteOffset - Entries[EI].ByteOffset;
  }
  size_t getNumComments(size_t EI) const {
    if (EI + 1 == Entries.size())
      return Comments.size() - Entries[EI].CommentOffset;
    return Entries[EI + 1].CommentOffset - Entries[EI].CommentOffset;
  }
};

/// Builder for DebugLocStream lists.
class DebugLocStream::ListBuilder {
  DebugLocStream &Locs;
  AsmPrinter &Asm;
  DbgVariable &V;
  const MachineInstr &MI;
  size_t ListIndex;
  Optional<uint8_t> TagOffset;

public:
  ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm,
              DbgVariable &V, const MachineInstr &MI)
      : Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)),
        TagOffset(None) {}

  void setTagOffset(uint8_t TO) {
    TagOffset = TO;
  }

  /// Finalize the list.
  ///
  /// If the list is empty, delete it.  Otherwise, finalize it by creating a
  /// temp symbol in \a Asm and setting up the \a DbgVariable.
  ~ListBuilder();

  DebugLocStream &getLocs() { return Locs; }
};

/// Builder for DebugLocStream entries.
class DebugLocStream::EntryBuilder {
  DebugLocStream &Locs;

public:
  EntryBuilder(ListBuilder &List, const MCSymbol *Begin, const MCSymbol *End)
      : Locs(List.getLocs()) {
    Locs.startEntry(Begin, End);
  }

  /// Finalize the entry, deleting it if it's empty.
  ~EntryBuilder() { Locs.finalizeEntry(); }

  BufferByteStreamer getStreamer() { return Locs.getStreamer(); }
};

} // namespace llvm

#endif
