//=== AcceleratorRecordsSaver.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 "AcceleratorRecordsSaver.h"
#include "Utils.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/Support/DJB.h"

namespace llvm {
namespace dwarflinker_parallel {

static uint32_t hashFullyQualifiedName(CompileUnit &InputCU, DWARFDie &InputDIE,
                                       int ChildRecurseDepth = 0) {
  const char *Name = nullptr;
  CompileUnit *CU = &InputCU;
  std::optional<DWARFFormValue> RefVal;

  if (Error Err = finiteLoop([&]() -> Expected<bool> {
        if (const char *CurrentName = InputDIE.getName(DINameKind::ShortName))
          Name = CurrentName;

        if (!(RefVal = InputDIE.find(dwarf::DW_AT_specification)) &&
            !(RefVal = InputDIE.find(dwarf::DW_AT_abstract_origin)))
          return false;

        if (!RefVal->isFormClass(DWARFFormValue::FC_Reference))
          return false;

        std::optional<UnitEntryPairTy> RefDie = CU->resolveDIEReference(
            *RefVal, ResolveInterCUReferencesMode::Resolve);
        if (!RefDie)
          return false;

        if (!RefDie->DieEntry)
          return false;

        CU = RefDie->CU;
        InputDIE = RefDie->CU->getDIE(RefDie->DieEntry);
        return true;
      })) {
    consumeError(std::move(Err));
  }

  if (!Name && InputDIE.getTag() == dwarf::DW_TAG_namespace)
    Name = "(anonymous namespace)";

  DWARFDie ParentDie = InputDIE.getParent();
  if (!ParentDie.isValid() || ParentDie.getTag() == dwarf::DW_TAG_compile_unit)
    return djbHash(Name ? Name : "", djbHash(ChildRecurseDepth ? "" : "::"));

  return djbHash(
      (Name ? Name : ""),
      djbHash((Name ? "::" : ""),
              hashFullyQualifiedName(*CU, ParentDie, ++ChildRecurseDepth)));
}

void AcceleratorRecordsSaver::save(const DWARFDebugInfoEntry *InputDieEntry,
                                   DIE *OutDIE, AttributesInfo &AttrInfo,
                                   TypeEntry *TypeEntry) {
  if (GlobalData.getOptions().AccelTables.empty())
    return;

  DWARFDie InputDIE = InUnit.getDIE(InputDieEntry);

  // Look for short name recursively if short name is not known yet.
  if (AttrInfo.Name == nullptr)
    if (const char *ShortName = InputDIE.getShortName())
      AttrInfo.Name = GlobalData.getStringPool().insert(ShortName).first;

  switch (InputDieEntry->getTag()) {
  case dwarf::DW_TAG_array_type:
  case dwarf::DW_TAG_class_type:
  case dwarf::DW_TAG_enumeration_type:
  case dwarf::DW_TAG_pointer_type:
  case dwarf::DW_TAG_reference_type:
  case dwarf::DW_TAG_string_type:
  case dwarf::DW_TAG_structure_type:
  case dwarf::DW_TAG_subroutine_type:
  case dwarf::DW_TAG_typedef:
  case dwarf::DW_TAG_union_type:
  case dwarf::DW_TAG_ptr_to_member_type:
  case dwarf::DW_TAG_set_type:
  case dwarf::DW_TAG_subrange_type:
  case dwarf::DW_TAG_base_type:
  case dwarf::DW_TAG_const_type:
  case dwarf::DW_TAG_constant:
  case dwarf::DW_TAG_file_type:
  case dwarf::DW_TAG_namelist:
  case dwarf::DW_TAG_packed_type:
  case dwarf::DW_TAG_volatile_type:
  case dwarf::DW_TAG_restrict_type:
  case dwarf::DW_TAG_atomic_type:
  case dwarf::DW_TAG_interface_type:
  case dwarf::DW_TAG_unspecified_type:
  case dwarf::DW_TAG_shared_type:
  case dwarf::DW_TAG_immutable_type:
  case dwarf::DW_TAG_rvalue_reference_type: {
    if (!AttrInfo.IsDeclaration && AttrInfo.Name != nullptr &&
        !AttrInfo.Name->getKey().empty()) {
      uint32_t Hash = hashFullyQualifiedName(InUnit, InputDIE);

      uint64_t RuntimeLang =
          dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
              .value_or(0);

      bool ObjCClassIsImplementation =
          (RuntimeLang == dwarf::DW_LANG_ObjC ||
           RuntimeLang == dwarf::DW_LANG_ObjC_plus_plus) &&
          dwarf::toUnsigned(
              InputDIE.find(dwarf::DW_AT_APPLE_objc_complete_type))
              .value_or(0);

      saveTypeRecord(AttrInfo.Name, OutDIE, InputDieEntry->getTag(), Hash,
                     ObjCClassIsImplementation, TypeEntry);
    }
  } break;
  case dwarf::DW_TAG_namespace: {
    if (AttrInfo.Name == nullptr)
      AttrInfo.Name =
          GlobalData.getStringPool().insert("(anonymous namespace)").first;

    saveNamespaceRecord(AttrInfo.Name, OutDIE, InputDieEntry->getTag(),
                        TypeEntry);
  } break;
  case dwarf::DW_TAG_imported_declaration: {
    if (AttrInfo.Name != nullptr)
      saveNamespaceRecord(AttrInfo.Name, OutDIE, InputDieEntry->getTag(),
                          TypeEntry);
  } break;
  case dwarf::DW_TAG_compile_unit:
  case dwarf::DW_TAG_lexical_block: {
    // Nothing to do.
  } break;
  default:
    if (TypeEntry)
      // Do not store this kind of accelerator entries for type entries.
      return;

    if (AttrInfo.HasLiveAddress || AttrInfo.HasRanges) {
      if (AttrInfo.Name)
        saveNameRecord(AttrInfo.Name, OutDIE, InputDieEntry->getTag(),
                       InputDieEntry->getTag() ==
                           dwarf::DW_TAG_inlined_subroutine);

      // Look for mangled name recursively if mangled name is not known yet.
      if (!AttrInfo.MangledName)
        if (const char *LinkageName = InputDIE.getLinkageName())
          AttrInfo.MangledName =
              GlobalData.getStringPool().insert(LinkageName).first;

      if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)
        saveNameRecord(AttrInfo.MangledName, OutDIE, InputDieEntry->getTag(),
                       InputDieEntry->getTag() ==
                           dwarf::DW_TAG_inlined_subroutine);

      // Strip template parameters from the short name.
      if (AttrInfo.Name && AttrInfo.MangledName != AttrInfo.Name &&
          (InputDieEntry->getTag() != dwarf::DW_TAG_inlined_subroutine)) {
        if (std::optional<StringRef> Name =
                StripTemplateParameters(AttrInfo.Name->getKey())) {
          StringEntry *NameWithoutTemplateParams =
              GlobalData.getStringPool().insert(*Name).first;

          saveNameRecord(NameWithoutTemplateParams, OutDIE,
                         InputDieEntry->getTag(), true);
        }
      }

      if (AttrInfo.Name)
        saveObjC(InputDieEntry, OutDIE, AttrInfo);
    }
    break;
  }
}

void AcceleratorRecordsSaver::saveObjC(const DWARFDebugInfoEntry *InputDieEntry,
                                       DIE *OutDIE, AttributesInfo &AttrInfo) {
  std::optional<ObjCSelectorNames> Names =
      getObjCNamesIfSelector(AttrInfo.Name->getKey());
  if (!Names)
    return;

  StringEntry *Selector =
      GlobalData.getStringPool().insert(Names->Selector).first;
  saveNameRecord(Selector, OutDIE, InputDieEntry->getTag(), true);
  StringEntry *ClassName =
      GlobalData.getStringPool().insert(Names->ClassName).first;
  saveObjCNameRecord(ClassName, OutDIE, InputDieEntry->getTag());
  if (Names->ClassNameNoCategory) {
    StringEntry *ClassNameNoCategory =
        GlobalData.getStringPool().insert(*Names->ClassNameNoCategory).first;
    saveObjCNameRecord(ClassNameNoCategory, OutDIE, InputDieEntry->getTag());
  }
  if (Names->MethodNameNoCategory) {
    StringEntry *MethodNameNoCategory =
        GlobalData.getStringPool().insert(*Names->MethodNameNoCategory).first;
    saveNameRecord(MethodNameNoCategory, OutDIE, InputDieEntry->getTag(), true);
  }
}

void AcceleratorRecordsSaver::saveNameRecord(StringEntry *Name, DIE *OutDIE,
                                             dwarf::Tag Tag,
                                             bool AvoidForPubSections) {
  DwarfUnit::AccelInfo Info;

  Info.Type = DwarfUnit::AccelType::Name;
  Info.String = Name;
  Info.OutOffset = OutDIE->getOffset();
  Info.Tag = Tag;
  Info.AvoidForPubSections = AvoidForPubSections;

  OutUnit.getAsCompileUnit()->saveAcceleratorInfo(Info);
}
void AcceleratorRecordsSaver::saveNamespaceRecord(StringEntry *Name,
                                                  DIE *OutDIE, dwarf::Tag Tag,
                                                  TypeEntry *TypeEntry) {
  if (OutUnit.isCompileUnit()) {
    assert(TypeEntry == nullptr);
    DwarfUnit::AccelInfo Info;

    Info.Type = DwarfUnit::AccelType::Namespace;
    Info.String = Name;
    Info.OutOffset = OutDIE->getOffset();
    Info.Tag = Tag;

    OutUnit.getAsCompileUnit()->saveAcceleratorInfo(Info);
    return;
  }

  assert(TypeEntry != nullptr);
  TypeUnit::TypeUnitAccelInfo Info;
  Info.Type = DwarfUnit::AccelType::Namespace;
  Info.String = Name;
  Info.OutOffset = 0xbaddef;
  Info.Tag = Tag;
  Info.OutDIE = OutDIE;
  Info.TypeEntryBodyPtr = TypeEntry->getValue().load();

  OutUnit.getAsTypeUnit()->saveAcceleratorInfo(Info);
}

void AcceleratorRecordsSaver::saveObjCNameRecord(StringEntry *Name, DIE *OutDIE,
                                                 dwarf::Tag Tag) {
  DwarfUnit::AccelInfo Info;

  Info.Type = DwarfUnit::AccelType::ObjC;
  Info.String = Name;
  Info.OutOffset = OutDIE->getOffset();
  Info.Tag = Tag;
  Info.AvoidForPubSections = true;

  OutUnit.getAsCompileUnit()->saveAcceleratorInfo(Info);
}

void AcceleratorRecordsSaver::saveTypeRecord(StringEntry *Name, DIE *OutDIE,
                                             dwarf::Tag Tag,
                                             uint32_t QualifiedNameHash,
                                             bool ObjcClassImplementation,
                                             TypeEntry *TypeEntry) {
  if (OutUnit.isCompileUnit()) {
    assert(TypeEntry == nullptr);
    DwarfUnit::AccelInfo Info;

    Info.Type = DwarfUnit::AccelType::Type;
    Info.String = Name;
    Info.OutOffset = OutDIE->getOffset();
    Info.Tag = Tag;
    Info.QualifiedNameHash = QualifiedNameHash;
    Info.ObjcClassImplementation = ObjcClassImplementation;

    OutUnit.getAsCompileUnit()->saveAcceleratorInfo(Info);
    return;
  }

  assert(TypeEntry != nullptr);
  TypeUnit::TypeUnitAccelInfo Info;

  Info.Type = DwarfUnit::AccelType::Type;
  Info.String = Name;
  Info.OutOffset = 0xbaddef;
  Info.Tag = Tag;
  Info.QualifiedNameHash = QualifiedNameHash;
  Info.ObjcClassImplementation = ObjcClassImplementation;
  Info.OutDIE = OutDIE;
  Info.TypeEntryBodyPtr = TypeEntry->getValue().load();
  OutUnit.getAsTypeUnit()->saveAcceleratorInfo(Info);
}

} // end of namespace dwarflinker_parallel
} // namespace llvm
