//===-- NSArray.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 "clang/AST/ASTContext.h"
#include "clang/Basic/TargetInfo.h"

#include "Cocoa.h"

#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"

#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

namespace lldb_private {
namespace formatters {
std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
NSArray_Additionals::GetAdditionalSummaries() {
  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
  return g_map;
}

std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
NSArray_Additionals::GetAdditionalSynthetics() {
  static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
      g_map;
  return g_map;
}

class NSArrayMSyntheticFrontEndBase : public SyntheticChildrenFrontEnd {
public:
  NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp);

  ~NSArrayMSyntheticFrontEndBase() override = default;

  llvm::Expected<uint32_t> CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override = 0;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;

protected:
  virtual lldb::addr_t GetDataAddress() = 0;

  virtual uint64_t GetUsedCount() = 0;

  virtual uint64_t GetOffset() = 0;

  virtual uint64_t GetSize() = 0;

  ExecutionContextRef m_exe_ctx_ref;
  uint8_t m_ptr_size = 8;
  CompilerType m_id_type;
};

template <typename D32, typename D64>
class GenericNSArrayMSyntheticFrontEnd : public NSArrayMSyntheticFrontEndBase {
public:
  GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

  ~GenericNSArrayMSyntheticFrontEnd() override;

  lldb::ChildCacheState Update() override;

protected:
  lldb::addr_t GetDataAddress() override;

  uint64_t GetUsedCount() override;

  uint64_t GetOffset() override;

  uint64_t GetSize() override;

private:
  D32 *m_data_32;
  D64 *m_data_64;
};

namespace Foundation1010 {
  namespace {
    struct DataDescriptor_32 {
      uint32_t _used;
      uint32_t _offset;
      uint32_t _size : 28;
      uint64_t _priv1 : 4;
      uint32_t _priv2;
      uint32_t _data;
    };

    struct DataDescriptor_64 {
      uint64_t _used;
      uint64_t _offset;
      uint64_t _size : 60;
      uint64_t _priv1 : 4;
      uint32_t _priv2;
      uint64_t _data;
    };
  }

  using NSArrayMSyntheticFrontEnd =
      GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}

namespace Foundation1428 {
  namespace {
    struct DataDescriptor_32 {
      uint32_t _used;
      uint32_t _offset;
      uint32_t _size;
      uint32_t _data;
    };

    struct DataDescriptor_64 {
      uint64_t _used;
      uint64_t _offset;
      uint64_t _size;
      uint64_t _data;
    };
  }

  using NSArrayMSyntheticFrontEnd =
      GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}

namespace Foundation1437 {
  template <typename PtrType>
  struct DataDescriptor {
    PtrType _cow;
    // __deque
    PtrType _data;
    uint32_t _offset;
    uint32_t _size;
    uint32_t _muts;
    uint32_t _used;
  };

  using NSArrayMSyntheticFrontEnd =
     GenericNSArrayMSyntheticFrontEnd<
        DataDescriptor<uint32_t>, DataDescriptor<uint64_t>>;

  template <typename DD>
  uint64_t
  __NSArrayMSize_Impl(lldb_private::Process &process,
                      lldb::addr_t valobj_addr, Status &error) {
    const lldb::addr_t start_of_descriptor =
    valobj_addr + process.GetAddressByteSize();
    DD descriptor = DD();
    process.ReadMemory(start_of_descriptor, &descriptor,
                       sizeof(descriptor), error);
    if (error.Fail()) {
      return 0;
    }
    return descriptor._used;
  }

  uint64_t
  __NSArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
                 Status &error) {
    if (process.GetAddressByteSize() == 4) {
      return __NSArrayMSize_Impl<DataDescriptor<uint32_t>>(process, valobj_addr,
                                                           error);
    } else {
      return __NSArrayMSize_Impl<DataDescriptor<uint64_t>>(process, valobj_addr,
                                                           error);
    }
  }

}

namespace CallStackArray {
struct DataDescriptor_32 {
  uint32_t _data;
  uint32_t _used;
  uint32_t _offset;
  const uint32_t _size = 0;
};

struct DataDescriptor_64 {
  uint64_t _data;
  uint64_t _used;
  uint64_t _offset;
  const uint64_t _size = 0;
};

using NSCallStackArraySyntheticFrontEnd =
    GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
} // namespace CallStackArray

template <typename D32, typename D64, bool Inline>
class GenericNSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

  ~GenericNSArrayISyntheticFrontEnd() override;

  llvm::Expected<uint32_t> CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;

private:
  ExecutionContextRef m_exe_ctx_ref;
  uint8_t m_ptr_size = 8;

  D32 *m_data_32;
  D64 *m_data_64;
  CompilerType m_id_type;
};

namespace Foundation1300 {
    struct IDD32 {
        uint32_t used;
        uint32_t list;
    };

    struct IDD64 {
        uint64_t used;
        uint64_t list;
    };

    using NSArrayISyntheticFrontEnd =
        GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>;
}

namespace Foundation1430 {
    using NSArrayISyntheticFrontEnd =
        Foundation1428::NSArrayMSyntheticFrontEnd;
}

namespace Foundation1436 {
    struct IDD32 {
        uint32_t used;
        uint32_t list; // in Inline cases, this is the first element
    };

    struct IDD64 {
        uint64_t used;
        uint64_t list; // in Inline cases, this is the first element
    };

    using NSArrayI_TransferSyntheticFrontEnd =
        GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, false>;

    using NSArrayISyntheticFrontEnd =
        GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>;

    using NSFrozenArrayMSyntheticFrontEnd =
        Foundation1437::NSArrayMSyntheticFrontEnd;

    uint64_t
    __NSFrozenArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
                         Status &error) {
      return Foundation1437::__NSArrayMSize(process, valobj_addr, error);
    }
}

namespace ConstantArray {

struct ConstantArray32 {
  uint64_t used;
  uint32_t list;
};

struct ConstantArray64 {
  uint64_t used;
  uint64_t list;
};

using NSConstantArraySyntheticFrontEnd =
    GenericNSArrayISyntheticFrontEnd<ConstantArray32, ConstantArray64, false>;
} // namespace ConstantArray

class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

  ~NSArray0SyntheticFrontEnd() override = default;

  llvm::Expected<uint32_t> CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

  bool MightHaveChildren() override;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
};

class NSArray1SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  NSArray1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

  ~NSArray1SyntheticFrontEnd() override = default;

  llvm::Expected<uint32_t> CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
};
} // namespace formatters
} // namespace lldb_private

bool lldb_private::formatters::NSArraySummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  static constexpr llvm::StringLiteral g_TypeHint("NSArray");

  ProcessSP process_sp = valobj.GetProcessSP();
  if (!process_sp)
    return false;

  ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);

  if (!runtime)
    return false;

  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
      runtime->GetClassDescriptor(valobj));

  if (!descriptor || !descriptor->IsValid())
    return false;

  uint32_t ptr_size = process_sp->GetAddressByteSize();

  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);

  if (!valobj_addr)
    return false;

  uint64_t value = 0;

  ConstString class_name(descriptor->GetClassName());

  static const ConstString g_NSArrayI("__NSArrayI");
  static const ConstString g_NSArrayM("__NSArrayM");
  static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
  static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
  static const ConstString g_NSArray0("__NSArray0");
  static const ConstString g_NSArray1("__NSSingleObjectArrayI");
  static const ConstString g_NSArrayCF("__NSCFArray");
  static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
  static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
  static const ConstString g_NSCallStackArray("_NSCallStackArray");
  static const ConstString g_NSConstantArray("NSConstantArray");

  if (class_name.IsEmpty())
    return false;

  if (class_name == g_NSArrayI) {
    Status error;
    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
                                                      ptr_size, 0, error);
    if (error.Fail())
      return false;
  } else if (class_name == g_NSConstantArray) {
    Status error;
    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 8,
                                                      0, error);
    if (error.Fail())
      return false;
  } else if (class_name == g_NSArrayM) {
    AppleObjCRuntime *apple_runtime =
    llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
    Status error;
    if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
      value = Foundation1437::__NSArrayMSize(*process_sp, valobj_addr, error);
    } else {
      value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
                                                        ptr_size, 0, error);
    }
    if (error.Fail())
      return false;
  } else if (class_name == g_NSArrayI_Transfer) {
    Status error;
    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
                                                      ptr_size, 0, error);
    if (error.Fail())
      return false;
  } else if (class_name == g_NSFrozenArrayM) {
    Status error;
    value = Foundation1436::__NSFrozenArrayMSize(*process_sp, valobj_addr, error);
    if (error.Fail())
      return false;
  } else if (class_name == g_NSArrayMLegacy) {
    Status error;
    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
                                                      ptr_size, 0, error);
    if (error.Fail())
      return false;
  } else if (class_name == g_NSArrayMImmutable) {
    Status error;
    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
                                                      ptr_size, 0, error);
    if (error.Fail())
      return false;
  } else if (class_name == g_NSArray0) {
    value = 0;
  } else if (class_name == g_NSArray1) {
    value = 1;
  } else if (class_name == g_NSArrayCF || class_name == g_NSCallStackArray) {
    // __NSCFArray and _NSCallStackArray store the number of elements as a
    // pointer-sized value at offset `2 * ptr_size`.
    Status error;
    value = process_sp->ReadUnsignedIntegerFromMemory(
        valobj_addr + 2 * ptr_size, ptr_size, 0, error);
    if (error.Fail())
      return false;
  } else {
    auto &map(NSArray_Additionals::GetAdditionalSummaries());
    auto iter = map.find(class_name), end = map.end();
    if (iter != end)
      return iter->second(valobj, stream, options);
    else
      return false;
  }

  llvm::StringRef prefix, suffix;
  if (Language *language = Language::FindPlugin(options.GetLanguage()))
    std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);

  stream << prefix;
  stream.Printf("%" PRIu64 " %s%s", value, "element", value == 1 ? "" : "s");
  stream << suffix;
  return true;
}

lldb_private::formatters::NSArrayMSyntheticFrontEndBase::
    NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_id_type() {
  if (valobj_sp) {
    TypeSystemClangSP scratch_ts_sp = ScratchTypeSystemClang::GetForTarget(
        *valobj_sp->GetExecutionContextRef().GetTargetSP());
    if (scratch_ts_sp)
      m_id_type = CompilerType(
          scratch_ts_sp->weak_from_this(),
          scratch_ts_sp->getASTContext().ObjCBuiltinIdTy.getAsOpaquePtr());
    if (valobj_sp->GetProcessSP())
      m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
  }
}

template <typename D32, typename D64>
lldb_private::formatters::
  GenericNSArrayMSyntheticFrontEnd<D32, D64>::
    GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
    : NSArrayMSyntheticFrontEndBase(valobj_sp), m_data_32(nullptr),
      m_data_64(nullptr) {}

llvm::Expected<uint32_t> lldb_private::formatters::
    NSArrayMSyntheticFrontEndBase::CalculateNumChildren() {
  return GetUsedCount();
}

lldb::ValueObjectSP
lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetChildAtIndex(
    uint32_t idx) {
  if (idx >= CalculateNumChildrenIgnoringErrors())
    return lldb::ValueObjectSP();
  lldb::addr_t object_at_idx = GetDataAddress();
  size_t pyhs_idx = idx;
  pyhs_idx += GetOffset();
  if (GetSize() <= pyhs_idx)
    pyhs_idx -= GetSize();
  object_at_idx += (pyhs_idx * m_ptr_size);
  StreamString idx_name;
  idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
  return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
                                      m_exe_ctx_ref, m_id_type);
}

template <typename D32, typename D64>
lldb::ChildCacheState
lldb_private::formatters::GenericNSArrayMSyntheticFrontEnd<D32, D64>::Update() {
  ValueObjectSP valobj_sp = m_backend.GetSP();
  m_ptr_size = 0;
  delete m_data_32;
  m_data_32 = nullptr;
  delete m_data_64;
  m_data_64 = nullptr;
  if (!valobj_sp)
    return lldb::ChildCacheState::eRefetch;
  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
  Status error;
  error.Clear();
  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
  if (!process_sp)
    return lldb::ChildCacheState::eRefetch;
  m_ptr_size = process_sp->GetAddressByteSize();
  uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
  if (m_ptr_size == 4) {
    m_data_32 = new D32();
    process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
                           error);
  } else {
    m_data_64 = new D64();
    process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
                           error);
  }

  return error.Success() ? lldb::ChildCacheState::eReuse
                         : lldb::ChildCacheState::eRefetch;
}

llvm::Expected<size_t> lldb_private::formatters::NSArrayMSyntheticFrontEndBase::
    GetIndexOfChildWithName(ConstString name) {
  auto optional_idx = ExtractIndexFromString(name.AsCString());
  if (!optional_idx) {
    return llvm::createStringError("Type has no child named '%s'",
                                   name.AsCString());
  }
  uint32_t idx = *optional_idx;
  if (idx >= CalculateNumChildrenIgnoringErrors())
    return llvm::createStringError("Type has no child named '%s'",
                                   name.AsCString());
  return idx;
}

template <typename D32, typename D64>
lldb_private::formatters::GenericNSArrayMSyntheticFrontEnd<D32, D64>::
    GenericNSArrayMSyntheticFrontEnd::~GenericNSArrayMSyntheticFrontEnd() {
  delete m_data_32;
  m_data_32 = nullptr;
  delete m_data_64;
  m_data_64 = nullptr;
}

template <typename D32, typename D64>
lldb::addr_t
lldb_private::formatters::
  GenericNSArrayMSyntheticFrontEnd<D32, D64>::
    GenericNSArrayMSyntheticFrontEnd::GetDataAddress() {
  if (!m_data_32 && !m_data_64)
    return LLDB_INVALID_ADDRESS;
  return m_data_32 ? m_data_32->_data : m_data_64->_data;
}

template <typename D32, typename D64>
uint64_t
lldb_private::formatters::
  GenericNSArrayMSyntheticFrontEnd<D32, D64>::
    GenericNSArrayMSyntheticFrontEnd::GetUsedCount() {
  if (!m_data_32 && !m_data_64)
    return 0;
  return m_data_32 ? m_data_32->_used : m_data_64->_used;
}

template <typename D32, typename D64>
uint64_t
lldb_private::formatters::
  GenericNSArrayMSyntheticFrontEnd<D32, D64>::
    GenericNSArrayMSyntheticFrontEnd::GetOffset() {
  if (!m_data_32 && !m_data_64)
    return 0;
  return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
}

template <typename D32, typename D64>
uint64_t
lldb_private::formatters::
  GenericNSArrayMSyntheticFrontEnd<D32, D64>::
    GenericNSArrayMSyntheticFrontEnd::GetSize() {
  if (!m_data_32 && !m_data_64)
    return 0;
  return m_data_32 ? m_data_32->_size : m_data_64->_size;
}

template <typename D32, typename D64, bool Inline>
lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
    GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(),
      m_data_32(nullptr), m_data_64(nullptr) {
  if (valobj_sp) {
    CompilerType type = valobj_sp->GetCompilerType();
    if (type) {
      TypeSystemClangSP scratch_ts_sp = ScratchTypeSystemClang::GetForTarget(
          *valobj_sp->GetExecutionContextRef().GetTargetSP());
      if (scratch_ts_sp)
        m_id_type = scratch_ts_sp->GetType(
            scratch_ts_sp->getASTContext().ObjCBuiltinIdTy);
    }
  }
}

template <typename D32, typename D64, bool Inline>
lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
    GenericNSArrayISyntheticFrontEnd::~GenericNSArrayISyntheticFrontEnd() {
  delete m_data_32;
  m_data_32 = nullptr;
  delete m_data_64;
  m_data_64 = nullptr;
}

template <typename D32, typename D64, bool Inline>
llvm::Expected<size_t>
lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<
    D32, D64, Inline>::GetIndexOfChildWithName(ConstString name) {
  auto optional_idx = ExtractIndexFromString(name.AsCString());
  if (!optional_idx) {
    return llvm::createStringError("Type has no child named '%s'",
                                   name.AsCString());
  }
  uint32_t idx = *optional_idx;
  if (idx >= CalculateNumChildrenIgnoringErrors())
    return llvm::createStringError("Type has no child named '%s'",
                                   name.AsCString());
  return idx;
}

template <typename D32, typename D64, bool Inline>
llvm::Expected<uint32_t>
lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<
    D32, D64, Inline>::CalculateNumChildren() {
  return m_data_32 ? m_data_32->used : m_data_64->used;
}

template <typename D32, typename D64, bool Inline>
lldb::ChildCacheState
lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64,
                                                           Inline>::Update() {
  ValueObjectSP valobj_sp = m_backend.GetSP();
  m_ptr_size = 0;
  delete m_data_32;
  m_data_32 = nullptr;
  delete m_data_64;
  m_data_64 = nullptr;
  if (!valobj_sp)
    return lldb::ChildCacheState::eRefetch;
  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
  Status error;
  error.Clear();
  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
  if (!process_sp)
    return lldb::ChildCacheState::eRefetch;
  m_ptr_size = process_sp->GetAddressByteSize();
  uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
  if (m_ptr_size == 4) {
    m_data_32 = new D32();
    process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
                           error);
  } else {
    m_data_64 = new D64();
    process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
                           error);
  }

  return error.Success() ? lldb::ChildCacheState::eReuse
                         : lldb::ChildCacheState::eRefetch;
}

template <typename D32, typename D64, bool Inline>
lldb::ValueObjectSP
lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
  GetChildAtIndex(uint32_t idx) {
  if (idx >= CalculateNumChildrenIgnoringErrors())
    return lldb::ValueObjectSP();
  lldb::addr_t object_at_idx;
  if (Inline) {
    object_at_idx = m_backend.GetSP()->GetValueAsUnsigned(0) + m_ptr_size;
    object_at_idx += m_ptr_size == 4 ? sizeof(D32) : sizeof(D64); // skip the data header
    object_at_idx -= m_ptr_size; // we treat the last entry in the data header as the first pointer
  } else {
    object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
  }
  object_at_idx += (idx * m_ptr_size);

  ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
  if (!process_sp)
    return lldb::ValueObjectSP();
  Status error;
  if (error.Fail())
    return lldb::ValueObjectSP();
  StreamString idx_name;
  idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
  return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
                                      m_exe_ctx_ref, m_id_type);
}

lldb_private::formatters::NSArray0SyntheticFrontEnd::NSArray0SyntheticFrontEnd(
    lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp) {}

llvm::Expected<size_t>
lldb_private::formatters::NSArray0SyntheticFrontEnd::GetIndexOfChildWithName(
    ConstString name) {
  return UINT32_MAX;
}

llvm::Expected<uint32_t>
lldb_private::formatters::NSArray0SyntheticFrontEnd::CalculateNumChildren() {
  return 0;
}

lldb::ChildCacheState
lldb_private::formatters::NSArray0SyntheticFrontEnd::Update() {
  return lldb::ChildCacheState::eRefetch;
}

bool lldb_private::formatters::NSArray0SyntheticFrontEnd::MightHaveChildren() {
  return false;
}

lldb::ValueObjectSP
lldb_private::formatters::NSArray0SyntheticFrontEnd::GetChildAtIndex(
    uint32_t idx) {
  return lldb::ValueObjectSP();
}

lldb_private::formatters::NSArray1SyntheticFrontEnd::NSArray1SyntheticFrontEnd(
    lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp.get()) {}

llvm::Expected<size_t>
lldb_private::formatters::NSArray1SyntheticFrontEnd::GetIndexOfChildWithName(
    ConstString name) {
  static const ConstString g_zero("[0]");

  if (name == g_zero)
    return 0;

  return UINT32_MAX;
}

llvm::Expected<uint32_t>
lldb_private::formatters::NSArray1SyntheticFrontEnd::CalculateNumChildren() {
  return 1;
}

lldb::ChildCacheState
lldb_private::formatters::NSArray1SyntheticFrontEnd::Update() {
  return lldb::ChildCacheState::eRefetch;
}

lldb::ValueObjectSP
lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex(
    uint32_t idx) {
  static const ConstString g_zero("[0]");

  if (idx == 0) {
    TypeSystemClangSP scratch_ts_sp =
        ScratchTypeSystemClang::GetForTarget(*m_backend.GetTargetSP());
    if (scratch_ts_sp) {
      CompilerType id_type(scratch_ts_sp->GetBasicType(lldb::eBasicTypeObjCID));
      return m_backend.GetSyntheticChildAtOffset(
          m_backend.GetProcessSP()->GetAddressByteSize(), id_type, true,
          g_zero);
    }
  }
  return lldb::ValueObjectSP();
}

SyntheticChildrenFrontEnd *
lldb_private::formatters::NSArraySyntheticFrontEndCreator(
    CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
  if (!process_sp)
    return nullptr;
  AppleObjCRuntime *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(
      ObjCLanguageRuntime::Get(*process_sp));
  if (!runtime)
    return nullptr;

  CompilerType valobj_type(valobj_sp->GetCompilerType());
  Flags flags(valobj_type.GetTypeInfo());

  if (flags.IsClear(eTypeIsPointer)) {
    Status error;
    valobj_sp = valobj_sp->AddressOf(error);
    if (error.Fail() || !valobj_sp)
      return nullptr;
  }

  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
      runtime->GetClassDescriptor(*valobj_sp));

  if (!descriptor || !descriptor->IsValid())
    return nullptr;

  ConstString class_name(descriptor->GetClassName());

  static const ConstString g_NSArrayI("__NSArrayI");
  static const ConstString g_NSConstantArray("NSConstantArray");
  static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
  static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
  static const ConstString g_NSArrayM("__NSArrayM");
  static const ConstString g_NSArray0("__NSArray0");
  static const ConstString g_NSArray1("__NSSingleObjectArrayI");
  static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
  static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
  static const ConstString g_NSCallStackArray("_NSCallStackArray");

  if (class_name.IsEmpty())
    return nullptr;

  if (class_name == g_NSArrayI) {
    if (runtime->GetFoundationVersion() >= 1436)
      return (new Foundation1436::NSArrayISyntheticFrontEnd(valobj_sp));
    if (runtime->GetFoundationVersion() >= 1430)
      return (new Foundation1430::NSArrayISyntheticFrontEnd(valobj_sp));
    return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp));
  } else if (class_name == g_NSArrayI_Transfer) {
      return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp));
  } else if (class_name == g_NSConstantArray) {
    return new ConstantArray::NSConstantArraySyntheticFrontEnd(valobj_sp);
  } else if (class_name == g_NSFrozenArrayM) {
    return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp));
  } else if (class_name == g_NSArray0) {
    return (new NSArray0SyntheticFrontEnd(valobj_sp));
  } else if (class_name == g_NSArray1) {
    return (new NSArray1SyntheticFrontEnd(valobj_sp));
  } else if (class_name == g_NSArrayM) {
    if (runtime->GetFoundationVersion() >= 1437)
      return (new Foundation1437::NSArrayMSyntheticFrontEnd(valobj_sp));
    if (runtime->GetFoundationVersion() >= 1428)
      return (new Foundation1428::NSArrayMSyntheticFrontEnd(valobj_sp));
    if (runtime->GetFoundationVersion() >= 1100)
      return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp));
  } else if (class_name == g_NSCallStackArray) {
    return (new CallStackArray::NSCallStackArraySyntheticFrontEnd(valobj_sp));
  } else {
    auto &map(NSArray_Additionals::GetAdditionalSynthetics());
    auto iter = map.find(class_name), end = map.end();
    if (iter != end)
      return iter->second(synth, valobj_sp);
  }

  return nullptr;
}
