//===-- DWARFDebugMacro.cpp -----------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "DWARFDebugMacro.h"
#include "SymbolFileDWARF.h"

#include "lldb/Symbol/DebugMacros.h"

#include "DWARFDataExtractor.h"

using namespace lldb_private;
using namespace lldb_private::dwarf;
using namespace lldb_private::plugin::dwarf;

DWARFDebugMacroHeader
DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data,
                                   lldb::offset_t *offset) {
  DWARFDebugMacroHeader header;

  // Skip over the version field in header.
  header.m_version = debug_macro_data.GetU16(offset);

  uint8_t flags = debug_macro_data.GetU8(offset);
  header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0;

  if (flags & DEBUG_LINE_OFFSET_MASK) {
    if (header.m_offset_is_64_bit)
      header.m_debug_line_offset = debug_macro_data.GetU64(offset);
    else
      header.m_debug_line_offset = debug_macro_data.GetU32(offset);
  }

  // Skip over the operands table if it is present.
  if (flags & OPCODE_OPERANDS_TABLE_MASK)
    SkipOperandTable(debug_macro_data, offset);

  return header;
}

void DWARFDebugMacroHeader::SkipOperandTable(
    const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) {
  uint8_t entry_count = debug_macro_data.GetU8(offset);
  for (uint8_t i = 0; i < entry_count; i++) {
    // Skip over the opcode number.
    debug_macro_data.GetU8(offset);

    uint64_t operand_count = debug_macro_data.GetULEB128(offset);

    for (uint64_t j = 0; j < operand_count; j++) {
      // Skip over the operand form
      debug_macro_data.GetU8(offset);
    }
  }
}

void DWARFDebugMacroEntry::ReadMacroEntries(
    const DWARFDataExtractor &debug_macro_data,
    const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit,
    lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf,
    DebugMacrosSP &debug_macros_sp) {
  llvm::dwarf::MacroEntryType type =
      static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
  while (type != 0) {
    lldb::offset_t new_offset = 0, str_offset = 0;
    uint32_t line = 0;
    const char *macro_str = nullptr;
    uint32_t debug_line_file_idx = 0;

    switch (type) {
    case DW_MACRO_define:
    case DW_MACRO_undef:
      line = debug_macro_data.GetULEB128(offset);
      macro_str = debug_macro_data.GetCStr(offset);
      if (type == DW_MACRO_define)
        debug_macros_sp->AddMacroEntry(
            DebugMacroEntry::CreateDefineEntry(line, macro_str));
      else
        debug_macros_sp->AddMacroEntry(
            DebugMacroEntry::CreateUndefEntry(line, macro_str));
      break;
    case DW_MACRO_define_strp:
    case DW_MACRO_undef_strp:
      line = debug_macro_data.GetULEB128(offset);
      if (offset_is_64_bit)
        str_offset = debug_macro_data.GetU64(offset);
      else
        str_offset = debug_macro_data.GetU32(offset);
      macro_str = debug_str_data.GetCStr(&str_offset);
      if (type == DW_MACRO_define_strp)
        debug_macros_sp->AddMacroEntry(
            DebugMacroEntry::CreateDefineEntry(line, macro_str));
      else
        debug_macros_sp->AddMacroEntry(
            DebugMacroEntry::CreateUndefEntry(line, macro_str));
      break;
    case DW_MACRO_start_file:
      line = debug_macro_data.GetULEB128(offset);
      debug_line_file_idx = debug_macro_data.GetULEB128(offset);
      debug_macros_sp->AddMacroEntry(
          DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
      break;
    case DW_MACRO_end_file:
      // This operation has no operands.
      debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
      break;
    case DW_MACRO_import:
      if (offset_is_64_bit)
        new_offset = debug_macro_data.GetU64(offset);
      else
        new_offset = debug_macro_data.GetU32(offset);
      debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry(
          sym_file_dwarf->ParseDebugMacros(&new_offset)));
      break;
    default:
      // TODO: Add support for other standard operations.
      // TODO: Provide mechanism to hook handling of non-standard/extension
      // operands.
      return;
    }
    type = static_cast<llvm::dwarf::MacroEntryType>(
        debug_macro_data.GetU8(offset));
  }
}
