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

#include "Plugins/SymbolFile/DWARF/AppleDWARFIndex.h"
#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"

#include "lldb/Core/Module.h"
#include "lldb/Symbol/Function.h"

using namespace lldb_private;
using namespace lldb;

std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
    Module &module, DWARFDataExtractor apple_names,
    DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types,
    DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) {
  auto apple_names_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
      apple_names, debug_str, ".apple_names");
  if (!apple_names_table_up->IsValid())
    apple_names_table_up.reset();

  auto apple_namespaces_table_up =
      std::make_unique<DWARFMappedHash::MemoryTable>(
          apple_namespaces, debug_str, ".apple_namespaces");
  if (!apple_namespaces_table_up->IsValid())
    apple_namespaces_table_up.reset();

  auto apple_types_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
      apple_types, debug_str, ".apple_types");
  if (!apple_types_table_up->IsValid())
    apple_types_table_up.reset();

  auto apple_objc_table_up = std::make_unique<DWARFMappedHash::MemoryTable>(
      apple_objc, debug_str, ".apple_objc");
  if (!apple_objc_table_up->IsValid())
    apple_objc_table_up.reset();

  if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
      apple_objc_table_up)
    return std::make_unique<AppleDWARFIndex>(
        module, std::move(apple_names_table_up),
        std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
        std::move(apple_objc_table_up));

  return nullptr;
}

void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
  if (m_apple_names_up)
    m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
}

void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
                                         DIEArray &offsets) {
  if (!m_apple_names_up)
    return;

  DWARFMappedHash::DIEInfoArray hash_data;
  if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
}

void AppleDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
                                         DIEArray &offsets) {
  if (!m_apple_names_up)
    return;

  DWARFMappedHash::DIEInfoArray hash_data;
  if (m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(),
                                             cu.GetNextUnitOffset(), hash_data))
    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
}

void AppleDWARFIndex::GetObjCMethods(ConstString class_name,
                                     DIEArray &offsets) {
  if (m_apple_objc_up)
    m_apple_objc_up->FindByName(class_name.GetStringRef(), offsets);
}

void AppleDWARFIndex::GetCompleteObjCClass(ConstString class_name,
                                           bool must_be_implementation,
                                           DIEArray &offsets) {
  if (m_apple_types_up) {
    m_apple_types_up->FindCompleteObjCClassByName(
        class_name.GetStringRef(), offsets, must_be_implementation);
  }
}

void AppleDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
  if (m_apple_types_up)
    m_apple_types_up->FindByName(name.GetStringRef(), offsets);
}

void AppleDWARFIndex::GetTypes(const DWARFDeclContext &context,
                               DIEArray &offsets) {
  if (!m_apple_types_up)
    return;

  Log *log = LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
                                          DWARF_LOG_LOOKUPS);
  const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom(
      DWARFMappedHash::eAtomTypeTag);
  const bool has_qualified_name_hash =
      m_apple_types_up->GetHeader().header_data.ContainsAtom(
          DWARFMappedHash::eAtomTypeQualNameHash);

  const ConstString type_name(context[0].name);
  const dw_tag_t tag = context[0].tag;
  if (has_tag && has_qualified_name_hash) {
    const char *qualified_name = context.GetQualifiedName();
    const uint32_t qualified_name_hash = llvm::djbHash(qualified_name);
    if (log)
      m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()");
    m_apple_types_up->FindByNameAndTagAndQualifiedNameHash(
        type_name.GetStringRef(), tag, qualified_name_hash, offsets);
    return;
  }

  if (has_tag) {
    // When searching for a scoped type (for example,
    // "std::vector<int>::const_iterator") searching for the innermost
    // name alone ("const_iterator") could yield many false
    // positives. By searching for the parent type ("vector<int>")
    // first we can avoid extracting type DIEs from object files that
    // would fail the filter anyway.
    if (!has_qualified_name_hash && (context.GetSize() > 1) &&
        (context[1].tag == DW_TAG_class_type ||
         context[1].tag == DW_TAG_structure_type)) {
      DIEArray class_matches;
      m_apple_types_up->FindByName(context[1].name, class_matches);
      if (class_matches.empty())
        return;
    }

    if (log)
      m_module.LogMessage(log, "FindByNameAndTag()");
    m_apple_types_up->FindByNameAndTag(type_name.GetStringRef(), tag, offsets);
    return;
  }

  m_apple_types_up->FindByName(type_name.GetStringRef(), offsets);
}

void AppleDWARFIndex::GetNamespaces(ConstString name, DIEArray &offsets) {
  if (m_apple_namespaces_up)
    m_apple_namespaces_up->FindByName(name.GetStringRef(), offsets);
}

void AppleDWARFIndex::GetFunctions(ConstString name, SymbolFileDWARF &dwarf,
                                   const CompilerDeclContext &parent_decl_ctx,
                                   uint32_t name_type_mask,
                                   std::vector<DWARFDIE> &dies) {
  DIEArray offsets;
  m_apple_names_up->FindByName(name.GetStringRef(), offsets);
  for (const DIERef &die_ref : offsets) {
    ProcessFunctionDIE(name.GetStringRef(), die_ref, dwarf, parent_decl_ctx,
                       name_type_mask, dies);
  }
}

void AppleDWARFIndex::GetFunctions(const RegularExpression &regex,
                                   DIEArray &offsets) {
  if (!m_apple_names_up)
    return;

  DWARFMappedHash::DIEInfoArray hash_data;
  if (m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data))
    DWARFMappedHash::ExtractDIEArray(hash_data, offsets);
}

void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref,
                                          llvm::StringRef name) {
  m_module.ReportErrorIfModifyDetected(
      "the DWARF debug information has been modified (accelerator table had "
      "bad die 0x%8.8x for '%s')\n",
      ref.die_offset(), name.str().c_str());
}

void AppleDWARFIndex::Dump(Stream &s) {
  if (m_apple_names_up)
    s.PutCString(".apple_names index present\n");
  if (m_apple_namespaces_up)
    s.PutCString(".apple_namespaces index present\n");
  if (m_apple_types_up)
    s.PutCString(".apple_types index present\n");
  if (m_apple_objc_up)
    s.PutCString(".apple_objc index present\n");
  // TODO: Dump index contents
}
