//===- DWARFDebugMacro.h ----------------------------------------*- 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_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H

#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include <cstdint>

namespace llvm {

class raw_ostream;

class DWARFDebugMacro {
  /// DWARFv5 section 6.3.1 Macro Information Header.
  enum HeaderFlagMask {
#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_##NAME = ID,
#include "llvm/BinaryFormat/Dwarf.def"
  };
  struct MacroHeader {
    /// Macro version information number.
    uint16_t Version = 0;

    /// The bits of the flags field are interpreted as a set of flags, some of
    /// which may indicate that additional fields follow. The following flags,
    /// beginning with the least significant bit, are defined:
    /// offset_size_flag:
    ///   If the offset_size_flag is zero, the header is for a 32-bit DWARF
    ///   format macro section and all offsets are 4 bytes long; if it is one,
    ///   the header is for a 64-bit DWARF format macro section and all offsets
    ///   are 8 bytes long.
    /// debug_line_offset_flag:
    ///   If the debug_line_offset_flag is one, the debug_line_offset field (see
    ///   below) is present. If zero, that field is omitted.
    /// opcode_operands_table_flag:
    ///   If the opcode_operands_table_flag is one, the opcode_operands_table
    ///   field (see below) is present. If zero, that field is omitted.
    uint8_t Flags = 0;

    /// debug_line_offset
    ///   An offset in the .debug_line section of the beginning of the line
    ///   number information in the containing compilation unit, encoded as a
    ///   4-byte offset for a 32-bit DWARF format macro section and an 8-byte
    ///   offset for a 64-bit DWARF format macro section.
    uint64_t DebugLineOffset;

    /// Print the macro header from the debug_macro section.
    void dumpMacroHeader(raw_ostream &OS) const;

    /// Parse the debug_macro header.
    Error parseMacroHeader(DWARFDataExtractor Data, uint64_t *Offset);

    /// Get the DWARF format according to the flags.
    dwarf::DwarfFormat getDwarfFormat() const;

    /// Get the size of a reference according to the DWARF format.
    uint8_t getOffsetByteSize() const;
  };

  /// A single macro entry within a macro list.
  struct Entry {
    /// The type of the macro entry.
    uint32_t Type;
    union {
      /// The source line where the macro is defined.
      uint64_t Line;
      /// Vendor extension constant value.
      uint64_t ExtConstant;
      /// Macro unit import offset.
      uint64_t ImportOffset;
    };

    union {
      /// The string (name, value) of the macro entry.
      const char *MacroStr;
      // An unsigned integer indicating the identity of the source file.
      uint64_t File;
      /// Vendor extension string.
      const char *ExtStr;
    };
  };

  struct MacroList {
    // A value 0 in the `Header.Version` field indicates that we're parsing
    // a macinfo[.dwo] section which doesn't have header itself, hence
    // for that case other fields in the `Header` are uninitialized.
    MacroHeader Header;
    SmallVector<Entry, 4> Macros;
    uint64_t Offset;

    /// Whether or not this is a .debug_macro section.
    bool IsDebugMacro;
  };

  /// A list of all the macro entries in the debug_macinfo section.
  std::vector<MacroList> MacroLists;

public:
  DWARFDebugMacro() = default;

  /// Print the macro list found within the debug_macinfo/debug_macro section.
  void dump(raw_ostream &OS) const;

  Error parseMacro(DWARFUnitVector::compile_unit_range Units,
                   DataExtractor StringExtractor,
                   DWARFDataExtractor MacroData) {
    return parseImpl(Units, StringExtractor, MacroData, /*IsMacro=*/true);
  }

  Error parseMacinfo(DWARFDataExtractor MacroData) {
    return parseImpl(None, None, MacroData, /*IsMacro=*/false);
  }

  /// Return whether the section has any entries.
  bool empty() const { return MacroLists.empty(); }

private:
  /// Parse the debug_macinfo/debug_macro section accessible via the 'MacroData'
  /// parameter.
  Error parseImpl(Optional<DWARFUnitVector::compile_unit_range> Units,
                  Optional<DataExtractor> StringExtractor,
                  DWARFDataExtractor Data, bool IsMacro);
};

} // end namespace llvm

#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
