//===- DebugLinesSubsection.h -----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
#define LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H

#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <vector>

namespace llvm {
namespace codeview {

class DebugChecksumsSubsection;
class DebugStringTableSubsection;

// Corresponds to the `CV_DebugSLinesHeader_t` structure.
struct LineFragmentHeader {
  support::ulittle32_t RelocOffset;  // Code offset of line contribution.
  support::ulittle16_t RelocSegment; // Code segment of line contribution.
  support::ulittle16_t Flags;        // See LineFlags enumeration.
  support::ulittle32_t CodeSize;     // Code size of this line contribution.
};

// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
struct LineBlockFragmentHeader {
  support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File
                                  // checksums buffer.  The checksum entry then
                                  // contains another offset into the string
                                  // table of the actual name.
  support::ulittle32_t NumLines;  // Number of lines
  support::ulittle32_t BlockSize; // Code size of block, in bytes.
  // The following two variable length arrays appear immediately after the
  // header.  The structure definitions follow.
  // LineNumberEntry   Lines[NumLines];
  // ColumnNumberEntry Columns[NumLines];
};

// Corresponds to `CV_Line_t` structure
struct LineNumberEntry {
  support::ulittle32_t Offset; // Offset to start of code bytes for line number
  support::ulittle32_t Flags;  // Start:24, End:7, IsStatement:1
};

// Corresponds to `CV_Column_t` structure
struct ColumnNumberEntry {
  support::ulittle16_t StartColumn;
  support::ulittle16_t EndColumn;
};

struct LineColumnEntry {
  support::ulittle32_t NameIndex;
  FixedStreamArray<LineNumberEntry> LineNumbers;
  FixedStreamArray<ColumnNumberEntry> Columns;
};

class LineColumnExtractor {
public:
  Error operator()(BinaryStreamRef Stream, uint32_t &Len,
                   LineColumnEntry &Item);

  const LineFragmentHeader *Header = nullptr;
};

class DebugLinesSubsectionRef final : public DebugSubsectionRef {
  friend class LineColumnExtractor;

  using LineInfoArray = VarStreamArray<LineColumnEntry, LineColumnExtractor>;
  using Iterator = LineInfoArray::Iterator;

public:
  DebugLinesSubsectionRef();

  static bool classof(const DebugSubsectionRef *S) {
    return S->kind() == DebugSubsectionKind::Lines;
  }

  Error initialize(BinaryStreamReader Reader);

  Iterator begin() const { return LinesAndColumns.begin(); }
  Iterator end() const { return LinesAndColumns.end(); }

  const LineFragmentHeader *header() const { return Header; }

  bool hasColumnInfo() const;

private:
  const LineFragmentHeader *Header = nullptr;
  LineInfoArray LinesAndColumns;
};

class DebugLinesSubsection final : public DebugSubsection {
  struct Block {
    Block(uint32_t ChecksumBufferOffset)
        : ChecksumBufferOffset(ChecksumBufferOffset) {}

    uint32_t ChecksumBufferOffset;
    std::vector<LineNumberEntry> Lines;
    std::vector<ColumnNumberEntry> Columns;
  };

public:
  DebugLinesSubsection(DebugChecksumsSubsection &Checksums,
                       DebugStringTableSubsection &Strings);

  static bool classof(const DebugSubsection *S) {
    return S->kind() == DebugSubsectionKind::Lines;
  }

  void createBlock(StringRef FileName);
  void addLineInfo(uint32_t Offset, const LineInfo &Line);
  void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line,
                            uint32_t ColStart, uint32_t ColEnd);

  uint32_t calculateSerializedSize() const override;
  Error commit(BinaryStreamWriter &Writer) const override;

  void setRelocationAddress(uint16_t Segment, uint32_t Offset);
  void setCodeSize(uint32_t Size);
  void setFlags(LineFlags Flags);

  bool hasColumnInfo() const;

private:
  DebugChecksumsSubsection &Checksums;
  uint32_t RelocOffset = 0;
  uint16_t RelocSegment = 0;
  uint32_t CodeSize = 0;
  LineFlags Flags = LF_None;
  std::vector<Block> Blocks;
};

} // end namespace codeview
} // end namespace llvm

#endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
