[Lldb-commits] [lldb] r310959 - Update NSArray/NSDictionary/NSSet formatters to handle new

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Tue Aug 15 14:23:14 PDT 2017


Author: jmolenda
Date: Tue Aug 15 14:23:14 2017
New Revision: 310959

URL: http://llvm.org/viewvc/llvm-project?rev=310959&view=rev
Log:
Update NSArray/NSDictionary/NSSet formatters to handle new
macOS 10.13 - High Sierra - internal layouts.  Patch by 
Sean Callanan.

<rdar://problem/33282015>

Modified:
    lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp
    lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp
    lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp

Modified: lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp?rev=310959&r1=310958&r2=310959&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp Tue Aug 15 14:23:14 2017
@@ -48,11 +48,11 @@ NSArray_Additionals::GetAdditionalSynthe
   return g_map;
 }
 
-class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+class NSArrayMSyntheticFrontEndBase : public SyntheticChildrenFrontEnd {
 public:
-  NSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+  NSArrayMSyntheticFrontEndBase(lldb::ValueObjectSP valobj_sp);
 
-  ~NSArrayMSyntheticFrontEnd() override = default;
+  ~NSArrayMSyntheticFrontEndBase() override = default;
 
   size_t CalculateNumChildren() override;
 
@@ -78,11 +78,12 @@ protected:
   CompilerType m_id_type;
 };
 
-class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd {
+template <typename D32, typename D64>
+class GenericNSArrayMSyntheticFrontEnd : public NSArrayMSyntheticFrontEndBase {
 public:
-  NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp);
+  GenericNSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-  ~NSArrayMSyntheticFrontEnd_109() override;
+  ~GenericNSArrayMSyntheticFrontEnd() override;
 
   bool Update() override;
 
@@ -96,6 +97,11 @@ protected:
   uint64_t GetSize() override;
 
 private:
+  D32 *m_data_32;
+  D64 *m_data_64;
+};
+  
+namespace Foundation109 {
   struct DataDescriptor_32 {
     uint32_t _used;
     uint32_t _priv1 : 2;
@@ -105,7 +111,7 @@ private:
     uint32_t _priv3;
     uint32_t _data;
   };
-
+  
   struct DataDescriptor_64 {
     uint64_t _used;
     uint64_t _priv1 : 2;
@@ -115,29 +121,12 @@ private:
     uint32_t _priv3;
     uint64_t _data;
   };
-
-  DataDescriptor_32 *m_data_32;
-  DataDescriptor_64 *m_data_64;
+  
+  using NSArrayMSyntheticFrontEnd =
+      GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
 };
-
-class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd {
-public:
-  NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp);
-
-  ~NSArrayMSyntheticFrontEnd_1010() override;
-
-  bool Update() override;
-
-protected:
-  lldb::addr_t GetDataAddress() override;
-
-  uint64_t GetUsedCount() override;
-
-  uint64_t GetOffset() override;
-
-  uint64_t GetSize() override;
-
-private:
+  
+namespace Foundation1010 {
   struct DataDescriptor_32 {
     uint32_t _used;
     uint32_t _offset;
@@ -146,7 +135,7 @@ private:
     uint32_t _priv2;
     uint32_t _data;
   };
-
+  
   struct DataDescriptor_64 {
     uint64_t _used;
     uint64_t _offset;
@@ -155,52 +144,86 @@ private:
     uint32_t _priv2;
     uint64_t _data;
   };
-
-  DataDescriptor_32 *m_data_32;
-  DataDescriptor_64 *m_data_64;
+  
+  using NSArrayMSyntheticFrontEnd =
+      GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
 };
-
-class NSArrayMSyntheticFrontEnd_1400 : public NSArrayMSyntheticFrontEnd {
-public:
-  NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp);
-
-  ~NSArrayMSyntheticFrontEnd_1400() override;
-
-  bool Update() override;
-
-protected:
-  lldb::addr_t GetDataAddress() override;
-
-  uint64_t GetUsedCount() override;
-
-  uint64_t GetOffset() override;
-
-  uint64_t GetSize() override;
-
-private:
+  
+namespace Foundation1428 {
   struct DataDescriptor_32 {
-    uint32_t used;
-    uint32_t offset;
-    uint32_t size;
-    uint32_t list;
+    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 list;
+    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;
+    union {
+      PtrType _mutations;
+      struct {
+        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);
+    }
+  }
 
-  DataDescriptor_32 *m_data_32;
-  DataDescriptor_64 *m_data_64;
 };
 
-class NSArrayISyntheticFrontEnd_1300 : public SyntheticChildrenFrontEnd {
+template <typename D32, typename D64, bool Inline>
+class GenericNSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
-  NSArrayISyntheticFrontEnd_1300(lldb::ValueObjectSP valobj_sp);
+  GenericNSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-  ~NSArrayISyntheticFrontEnd_1300() override = default;
+  ~GenericNSArrayISyntheticFrontEnd() override;
 
   size_t CalculateNumChildren() override;
 
@@ -215,48 +238,57 @@ public:
 private:
   ExecutionContextRef m_exe_ctx_ref;
   uint8_t m_ptr_size;
-  uint64_t m_items;
-  lldb::addr_t m_data_ptr;
+    
+  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>;
+};
 
-class NSArrayISyntheticFrontEnd_1400 : public SyntheticChildrenFrontEnd {
-public:
-  NSArrayISyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp);
-
-  ~NSArrayISyntheticFrontEnd_1400() override;
-
-  size_t CalculateNumChildren() override;
-
-  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
-
-  bool Update() override;
-
-  bool MightHaveChildren() override;
-
-  size_t GetIndexOfChildWithName(const ConstString &name) override;
-
-private:
-  ExecutionContextRef m_exe_ctx_ref;
-  uint8_t m_ptr_size;
-
-  struct DataDescriptor_32 {
-    uint32_t used;
-    uint32_t offset;
-    uint32_t size;
-    uint32_t list;
-  };
-
-  struct DataDescriptor_64 {
-    uint64_t used;
-    uint64_t offset;
-    uint64_t size;
-    uint64_t list;
-  };
+namespace Foundation1430 {
+    using NSArrayISyntheticFrontEnd =
+        Foundation1428::NSArrayMSyntheticFrontEnd;
+};
 
-  DataDescriptor_32 *m_data_32;
-  DataDescriptor_64 *m_data_64;
-  CompilerType m_id_type;
+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);
+    }
 };
 
 class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
@@ -329,6 +361,8 @@ bool lldb_private::formatters::NSArraySu
 
   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");
@@ -345,11 +379,28 @@ bool lldb_private::formatters::NSArraySu
     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,
@@ -395,7 +446,7 @@ bool lldb_private::formatters::NSArraySu
   return true;
 }
 
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontEndBase(
     lldb::ValueObjectSP valobj_sp)
     : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
       m_id_type() {
@@ -411,28 +462,20 @@ lldb_private::formatters::NSArrayMSynthe
   }
 }
 
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
-    NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp)
-    : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
-      m_data_64(nullptr) {}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
-    NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp)
-    : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
-      m_data_64(nullptr) {}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::
-    NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp)
-    : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
+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) {}
 
 size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren() {
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::CalculateNumChildren() {
   return GetUsedCount();
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetChildAtIndex(
     size_t idx) {
   if (idx >= CalculateNumChildren())
     return lldb::ValueObjectSP();
@@ -448,38 +491,10 @@ lldb_private::formatters::NSArrayMSynthe
                                       m_exe_ctx_ref, m_id_type);
 }
 
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::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 false;
-  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-  Status error;
-  error.Clear();
-  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
-  if (!process_sp)
-    return false;
-  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 DataDescriptor_32();
-    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
-                           error);
-  } else {
-    m_data_64 = new DataDescriptor_64();
-    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
-                           error);
-  }
-  if (error.Fail())
-    return false;
-  return false;
-}
-
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update() {
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::
+  GenericNSArrayMSyntheticFrontEnd<D32, D64>::Update() {
   ValueObjectSP valobj_sp = m_backend.GetSP();
   m_ptr_size = 0;
   delete m_data_32;
@@ -497,12 +512,12 @@ bool lldb_private::formatters::NSArrayMS
   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 DataDescriptor_32();
-    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+    m_data_32 = new D32();
+    process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
                            error);
   } else {
-    m_data_64 = new DataDescriptor_64();
-    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+    m_data_64 = new D64();
+    process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
                            error);
   }
   if (error.Fail())
@@ -510,43 +525,13 @@ bool lldb_private::formatters::NSArrayMS
   return false;
 }
 
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::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 false;
-  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-  Status error;
-  error.Clear();
-  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
-  if (!process_sp)
-    return false;
-  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 DataDescriptor_32();
-    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
-                           error);
-  } else {
-    m_data_64 = new DataDescriptor_64();
-    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
-                           error);
-  }
-  if (error.Fail())
-    return false;
-  return false;
-}
-
-bool lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren() {
+bool
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::MightHaveChildren() {
   return true;
 }
 
 size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName(
+lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetIndexOfChildWithName(
     const ConstString &name) {
   const char *item_name = name.GetCString();
   uint32_t idx = ExtractIndexFromString(item_name);
@@ -555,187 +540,59 @@ lldb_private::formatters::NSArrayMSynthe
   return idx;
 }
 
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
-    ~NSArrayMSyntheticFrontEnd_109() {
+template <typename D32, typename D64>
+lldb_private::formatters::
+  GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+    ~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::NSArrayMSyntheticFrontEnd_109::GetDataAddress() {
+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::NSArrayMSyntheticFrontEnd_109::GetUsedCount() {
+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;
 }
 
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetOffset() {
-  if (!m_data_32 && !m_data_64)
-    return 0;
-  return m_data_32 ? m_data_32->_offset : m_data_64->_offset;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize() {
-  if (!m_data_32 && !m_data_64)
-    return 0;
-  return m_data_32 ? m_data_32->_size : m_data_64->_size;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
-    ~NSArrayMSyntheticFrontEnd_1010() {
-  delete m_data_32;
-  m_data_32 = nullptr;
-  delete m_data_64;
-  m_data_64 = nullptr;
-}
-
-lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::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::NSArrayMSyntheticFrontEnd_1010::GetUsedCount() {
-  if (!m_data_32 && !m_data_64)
-    return 0;
-  return m_data_32 ? m_data_32->_used : m_data_64->_used;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetOffset() {
+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;
 }
 
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize() {
-  if (!m_data_32 && !m_data_64)
-    return 0;
-  return m_data_32 ? m_data_32->_size : m_data_64->_size;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::
-    ~NSArrayMSyntheticFrontEnd_1400() {
-  delete m_data_32;
-  m_data_32 = nullptr;
-  delete m_data_64;
-  m_data_64 = nullptr;
-}
-
-lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetDataAddress() {
-  if (!m_data_32 && !m_data_64)
-    return LLDB_INVALID_ADDRESS;
-  return m_data_32 ? m_data_32->list : m_data_64->list;
-}
-
+template <typename D32, typename D64>
 uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetUsedCount() {
+lldb_private::formatters::
+  GenericNSArrayMSyntheticFrontEnd<D32, D64>::
+    GenericNSArrayMSyntheticFrontEnd::GetSize() {
   if (!m_data_32 && !m_data_64)
     return 0;
-  return m_data_32 ? m_data_32->used : m_data_64->used;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetOffset() {
-  if (!m_data_32 && !m_data_64)
-    return 0;
-  return m_data_32 ? m_data_32->offset : m_data_64->offset;
-}
-
-uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetSize() {
-  if (!m_data_32 && !m_data_64)
-    return 0;
-  return m_data_32 ? m_data_32->size : m_data_64->size;
-}
-
-
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::NSArrayISyntheticFrontEnd_1300(
-    lldb::ValueObjectSP valobj_sp)
-    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
-      m_items(0), m_data_ptr(0) {
-  if (valobj_sp) {
-    CompilerType type = valobj_sp->GetCompilerType();
-    if (type) {
-      ClangASTContext *ast = valobj_sp->GetExecutionContextRef()
-                                 .GetTargetSP()
-                                 ->GetScratchClangASTContext();
-      if (ast)
-        m_id_type = CompilerType(ast->getASTContext(),
-                                 ast->getASTContext()->ObjCBuiltinIdTy);
-    }
-  }
-}
-
-size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetIndexOfChildWithName(
-    const ConstString &name) {
-  const char *item_name = name.GetCString();
-  uint32_t idx = ExtractIndexFromString(item_name);
-  if (idx < UINT32_MAX && idx >= CalculateNumChildren())
-    return UINT32_MAX;
-  return idx;
-}
-
-size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::CalculateNumChildren() {
-  return m_items;
-}
-
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::Update() {
-  m_ptr_size = 0;
-  m_items = 0;
-  m_data_ptr = 0;
-  ValueObjectSP valobj_sp = m_backend.GetSP();
-  if (!valobj_sp)
-    return false;
-  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-  Status error;
-  error.Clear();
-  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
-  if (!process_sp)
-    return false;
-  m_ptr_size = process_sp->GetAddressByteSize();
-  uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
-  m_items = process_sp->ReadPointerFromMemory(data_location, error);
-  if (error.Fail())
-    return false;
-  m_data_ptr = data_location + m_ptr_size;
-  return false;
-}
-
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::MightHaveChildren() {
-  return true;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetChildAtIndex(
-    size_t idx) {
-  if (idx >= CalculateNumChildren())
-    return lldb::ValueObjectSP();
-  lldb::addr_t object_at_idx = m_data_ptr;
-  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);
+  return m_data_32 ? m_data_32->_size : m_data_64->_size;
 }
 
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::NSArrayISyntheticFrontEnd_1400(
+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_ptr_size(8),
       m_data_32(nullptr), m_data_64(nullptr) {
@@ -752,16 +609,19 @@ lldb_private::formatters::NSArrayISynthe
   }
 }
 
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::~NSArrayISyntheticFrontEnd_1400() {
+template <typename D32, typename D64, bool Inline>
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+  ~GenericNSArrayISyntheticFrontEnd() {
   delete m_data_32;
   m_data_32 = nullptr;
   delete m_data_64;
   m_data_64 = nullptr;
 }
 
+template <typename D32, typename D64, bool Inline>
 size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetIndexOfChildWithName(
-    const ConstString &name) {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+  GetIndexOfChildWithName(const ConstString &name) {
   const char *item_name = name.GetCString();
   uint32_t idx = ExtractIndexFromString(item_name);
   if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -769,12 +629,17 @@ lldb_private::formatters::NSArrayISynthe
   return idx;
 }
 
+template <typename D32, typename D64, bool Inline>
 size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::CalculateNumChildren() {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+  CalculateNumChildren() {
   return m_data_32 ? m_data_32->used : m_data_64->used;
 }
 
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() {
+template <typename D32, typename D64, bool Inline>
+bool
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+  Update() {
   ValueObjectSP valobj_sp = m_backend.GetSP();
   m_ptr_size = 0;
   delete m_data_32;
@@ -792,12 +657,12 @@ bool lldb_private::formatters::NSArrayIS
   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 DataDescriptor_32();
-    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+    m_data_32 = new D32();
+    process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
                            error);
   } else {
-    m_data_64 = new DataDescriptor_64();
-    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+    m_data_64 = new D64();
+    process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
                            error);
   }
   if (error.Fail())
@@ -805,17 +670,29 @@ bool lldb_private::formatters::NSArrayIS
   return false;
 }
 
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::MightHaveChildren() {
+template <typename D32, typename D64, bool Inline>
+bool
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+  MightHaveChildren() {
   return true;
 }
 
+template <typename D32, typename D64, bool Inline>
 lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetChildAtIndex(
-    size_t idx) {
+lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
+  GetChildAtIndex(size_t idx) {
   if (idx >= CalculateNumChildren())
     return lldb::ValueObjectSP();
-  lldb::addr_t object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
+  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();
@@ -933,6 +810,8 @@ lldb_private::formatters::NSArraySynthet
   ConstString class_name(descriptor->GetClassName());
 
   static const ConstString g_NSArrayI("__NSArrayI");
+  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");
@@ -943,21 +822,30 @@ lldb_private::formatters::NSArraySynthet
     return nullptr;
 
   if (class_name == g_NSArrayI) {
-      if (runtime->GetFoundationVersion() >= 1400)
-        return (new NSArrayISyntheticFrontEnd_1400(valobj_sp));
-      else
-        return (new NSArrayISyntheticFrontEnd_1300(valobj_sp));
+    if (runtime->GetFoundationVersion() >= 1436)
+      return (new Foundation1436::NSArrayISyntheticFrontEnd(valobj_sp));
+    if (runtime->GetFoundationVersion() >= 1430)
+      return (new Foundation1430::NSArrayISyntheticFrontEnd(valobj_sp));
+    else
+      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_NSArray0) {
+  } 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() >= 1400)
-      return (new NSArrayMSyntheticFrontEnd_1400(valobj_sp));
+    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 NSArrayMSyntheticFrontEnd_1010(valobj_sp));
+      return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp));
     else
-      return (new NSArrayMSyntheticFrontEnd_109(valobj_sp));
+      return (new Foundation109::NSArrayMSyntheticFrontEnd(valobj_sp));
   } else {
     auto &map(NSArray_Additionals::GetAdditionalSynthetics());
     auto iter = map.find(class_name), end = map.end();

Modified: lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp?rev=310959&r1=310958&r2=310959&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp Tue Aug 15 14:23:14 2017
@@ -165,11 +165,12 @@ private:
   ValueObjectSP m_pair;
 };
 
-class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+template <typename D32, typename D64>
+class GenericNSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
-  NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+  GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-  ~NSDictionaryMSyntheticFrontEnd() override;
+  ~GenericNSDictionaryMSyntheticFrontEnd() override;
 
   size_t CalculateNumChildren() override;
 
@@ -182,20 +183,6 @@ public:
   size_t GetIndexOfChildWithName(const ConstString &name) override;
 
 private:
-  struct DataDescriptor_32 {
-    uint32_t used : 26;
-    uint32_t kvo : 1;
-    uint32_t size;
-    uint32_t buffer;
-  };
-
-  struct DataDescriptor_64 {
-    uint64_t used : 58;
-    uint32_t kvo : 1;
-    uint64_t size;
-    uint64_t buffer;
-  };
-
   struct DictionaryItemDescriptor {
     lldb::addr_t key_ptr;
     lldb::addr_t val_ptr;
@@ -205,60 +192,168 @@ private:
   ExecutionContextRef m_exe_ctx_ref;
   uint8_t m_ptr_size;
   lldb::ByteOrder m_order;
-  DataDescriptor_32 *m_data_32;
-  DataDescriptor_64 *m_data_64;
+  D32 *m_data_32;
+  D64 *m_data_64;
   CompilerType m_pair_type;
   std::vector<DictionaryItemDescriptor> m_children;
 };
-
-class NSDictionaryMLegacySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
-public:
-  NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
-
-  ~NSDictionaryMLegacySyntheticFrontEnd() override;
-
-  size_t CalculateNumChildren() override;
-
-  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
-
-  bool Update() override;
-
-  bool MightHaveChildren() override;
-
-  size_t GetIndexOfChildWithName(const ConstString &name) override;
-
-private:
+  
+namespace Foundation1100 {
+  class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+  public:
+    NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+    
+    ~NSDictionaryMSyntheticFrontEnd() override;
+    
+    size_t CalculateNumChildren() override;
+    
+    lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+    
+    bool Update() override;
+    
+    bool MightHaveChildren() override;
+    
+    size_t GetIndexOfChildWithName(const ConstString &name) override;
+    
+  private:
+    struct DataDescriptor_32 {
+      uint32_t _used : 26;
+      uint32_t _kvo : 1;
+      uint32_t _size;
+      uint32_t _mutations;
+      uint32_t _objs_addr;
+      uint32_t _keys_addr;
+    };
+    
+    struct DataDescriptor_64 {
+      uint64_t _used : 58;
+      uint32_t _kvo : 1;
+      uint64_t _size;
+      uint64_t _mutations;
+      uint64_t _objs_addr;
+      uint64_t _keys_addr;
+    };
+    
+    struct DictionaryItemDescriptor {
+      lldb::addr_t key_ptr;
+      lldb::addr_t val_ptr;
+      lldb::ValueObjectSP valobj_sp;
+    };
+    
+    ExecutionContextRef m_exe_ctx_ref;
+    uint8_t m_ptr_size;
+    lldb::ByteOrder m_order;
+    DataDescriptor_32 *m_data_32;
+    DataDescriptor_64 *m_data_64;
+    CompilerType m_pair_type;
+    std::vector<DictionaryItemDescriptor> m_children;
+  };
+};
+  
+namespace Foundation1428 {
   struct DataDescriptor_32 {
     uint32_t _used : 26;
     uint32_t _kvo : 1;
     uint32_t _size;
-    uint32_t _mutations;
-    uint32_t _objs_addr;
-    uint32_t _keys_addr;
+    uint32_t _buffer;
+    uint64_t GetSize() { return _size; }
   };
-
+  
   struct DataDescriptor_64 {
     uint64_t _used : 58;
     uint32_t _kvo : 1;
     uint64_t _size;
-    uint64_t _mutations;
-    uint64_t _objs_addr;
-    uint64_t _keys_addr;
+    uint64_t _buffer;
+    uint64_t GetSize() { return _size; }
   };
-
-  struct DictionaryItemDescriptor {
-    lldb::addr_t key_ptr;
-    lldb::addr_t val_ptr;
-    lldb::ValueObjectSP valobj_sp;
+  
+  
+  
+  using NSDictionaryMSyntheticFrontEnd =
+    GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+};
+  
+namespace Foundation1437 {
+  static const uint64_t NSDictionaryCapacities[] = {
+      0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
+      2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
+      214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
+      6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
+      111638519, 180634607, 292272623, 472907251
+  };
+  
+  static const size_t NSDictionaryNumSizeBuckets = sizeof(NSDictionaryCapacities) / sizeof(uint64_t);
+  
+  struct DataDescriptor_32 {
+    uint32_t _buffer;
+    union {
+      struct {
+        uint32_t _mutations;
+      };
+      struct {
+        uint32_t _muts;
+        uint32_t _used:25;
+        uint32_t _kvo:1;
+        uint32_t _szidx:6;
+      };
+    };
+    
+    uint64_t GetSize() {
+      return (_szidx) >= NSDictionaryNumSizeBuckets ?
+          0 : NSDictionaryCapacities[_szidx];
+    }
+  };
+  
+  struct DataDescriptor_64 {
+    uint64_t _buffer;
+    union {
+      struct {
+        uint64_t _mutations;
+      };
+      struct {
+        uint32_t _muts;
+        uint32_t _used:25;
+        uint32_t _kvo:1;
+        uint32_t _szidx:6;
+      };
+    };
+    
+    uint64_t GetSize() {
+      return (_szidx) >= NSDictionaryNumSizeBuckets ?
+          0 : NSDictionaryCapacities[_szidx];
+    }
   };
+  
+  using NSDictionaryMSyntheticFrontEnd =
+    GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+  
+  template <typename DD>
+  uint64_t
+  __NSDictionaryMSize_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
+  __NSDictionaryMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+               Status &error) {
+    if (process.GetAddressByteSize() == 4) {
+      return __NSDictionaryMSize_Impl<DataDescriptor_32>(process, valobj_addr,
+                                                         error);
+    } else {
+      return __NSDictionaryMSize_Impl<DataDescriptor_64>(process, valobj_addr,
+                                                         error);
+    }
+  }
 
-  ExecutionContextRef m_exe_ctx_ref;
-  uint8_t m_ptr_size;
-  lldb::ByteOrder m_order;
-  DataDescriptor_32 *m_data_32;
-  DataDescriptor_64 *m_data_64;
-  CompilerType m_pair_type;
-  std::vector<DictionaryItemDescriptor> m_children;
 };
 } // namespace formatters
 } // namespace lldb_private
@@ -313,12 +408,19 @@ bool lldb_private::formatters::NSDiction
       return false;
     value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
   } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) {
+    AppleObjCRuntime *apple_runtime =
+    llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
     Status error;
-    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
-                                                      ptr_size, 0, error);
+    if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
+      value = Foundation1437::__NSDictionaryMSize(*process_sp, valobj_addr,
+                                                  error);
+    } else {
+      value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                        ptr_size, 0, error);
+      value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+    }
     if (error.Fail())
       return false;
-    value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
   } else if (class_name == g_Dictionary1) {
     value = 1;
   }
@@ -396,13 +498,15 @@ lldb_private::formatters::NSDictionarySy
   if (class_name == g_DictionaryI) {
     return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_DictionaryM) {
-    if (runtime->GetFoundationVersion() > 1400) {
-      return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+    if (runtime->GetFoundationVersion() >= 1437) {
+      return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp));
+    } else if (runtime->GetFoundationVersion() >= 1428) {
+      return (new Foundation1428::NSDictionaryMSyntheticFrontEnd(valobj_sp));
     } else {
-      return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp));
+      return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
     }
   } else if (class_name == g_DictionaryMLegacy) {
-      return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp));
+      return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_Dictionary1) {
     return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
   } else {
@@ -641,22 +745,25 @@ lldb_private::formatters::NSDictionary1S
   return m_pair;
 }
 
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
-    NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+template <typename D32, typename D64>
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+    GenericNSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
     : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
       m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
       m_pair_type() {}
 
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
-    ~NSDictionaryMSyntheticFrontEnd() {
+template <typename D32, typename D64>
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+    ~GenericNSDictionaryMSyntheticFrontEnd() {
   delete m_data_32;
   m_data_32 = nullptr;
   delete m_data_64;
   m_data_64 = nullptr;
 }
 
-size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
-    GetIndexOfChildWithName(const ConstString &name) {
+template <typename D32, typename D64>
+size_t
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::    GetIndexOfChildWithName(const ConstString &name) {
   const char *item_name = name.GetCString();
   uint32_t idx = ExtractIndexFromString(item_name);
   if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -664,14 +771,18 @@ size_t lldb_private::formatters::NSDicti
   return idx;
 }
 
-size_t lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
-    CalculateNumChildren() {
+template <typename D32, typename D64>
+size_t
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::CalculateNumChildren() {
   if (!m_data_32 && !m_data_64)
     return 0;
-  return (m_data_32 ? m_data_32->used : m_data_64->used);
+  return (m_data_32 ? m_data_32->_used : m_data_64->_used);
 }
 
-bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+  Update() {
   m_children.clear();
   ValueObjectSP valobj_sp = m_backend.GetSP();
   m_ptr_size = 0;
@@ -691,12 +802,12 @@ bool lldb_private::formatters::NSDiction
   m_order = process_sp->GetByteOrder();
   uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
   if (m_ptr_size == 4) {
-    m_data_32 = new DataDescriptor_32();
-    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+    m_data_32 = new D32();
+    process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
                            error);
   } else {
-    m_data_64 = new DataDescriptor_64();
-    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+    m_data_64 = new D64();
+    process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
                            error);
   }
   if (error.Fail())
@@ -704,24 +815,28 @@ bool lldb_private::formatters::NSDiction
   return false;
 }
 
-bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
     MightHaveChildren() {
   return true;
 }
 
+template <typename D32, typename D64>
 lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(
+lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>::
+    GetChildAtIndex(
     size_t idx) {
   lldb::addr_t m_keys_ptr;
   lldb::addr_t m_values_ptr;
   if (m_data_32) {
-    uint32_t size = m_data_32->size;
-    m_keys_ptr = m_data_32->buffer;
-    m_values_ptr = m_data_32->buffer + (m_ptr_size * size);
+    uint32_t size = m_data_32->GetSize();
+    m_keys_ptr = m_data_32->_buffer;
+    m_values_ptr = m_data_32->_buffer + (m_ptr_size * size);
   } else {
-    uint32_t size = m_data_64->size;
-    m_keys_ptr = m_data_64->buffer;
-    m_values_ptr = m_data_64->buffer + (m_ptr_size * size);
+    uint32_t size = m_data_64->GetSize();
+    m_keys_ptr = m_data_64->_buffer;
+    m_values_ptr = m_data_64->_buffer + (m_ptr_size * size);
   }
 
   uint32_t num_children = CalculateNumChildren();
@@ -800,22 +915,24 @@ lldb_private::formatters::NSDictionaryMS
 }
 
 
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
-    NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+lldb_private::formatters::Foundation1100::
+  NSDictionaryMSyntheticFrontEnd::
+    NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
     : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
       m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
       m_pair_type() {}
 
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
-    ~NSDictionaryMLegacySyntheticFrontEnd() {
+lldb_private::formatters::Foundation1100::
+  NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd() {
   delete m_data_32;
   m_data_32 = nullptr;
   delete m_data_64;
   m_data_64 = nullptr;
 }
 
-size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
-    GetIndexOfChildWithName(const ConstString &name) {
+size_t
+lldb_private::formatters::Foundation1100::
+  NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName(const ConstString &name) {
   const char *item_name = name.GetCString();
   uint32_t idx = ExtractIndexFromString(item_name);
   if (idx < UINT32_MAX && idx >= CalculateNumChildren())
@@ -823,14 +940,17 @@ size_t lldb_private::formatters::NSDicti
   return idx;
 }
 
-size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
-    CalculateNumChildren() {
+size_t
+lldb_private::formatters::Foundation1100::
+  NSDictionaryMSyntheticFrontEnd::CalculateNumChildren() {
   if (!m_data_32 && !m_data_64)
     return 0;
   return (m_data_32 ? m_data_32->_used : m_data_64->_used);
 }
 
-bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::Update() {
+bool
+lldb_private::formatters::Foundation1100::
+  NSDictionaryMSyntheticFrontEnd::Update() {
   m_children.clear();
   ValueObjectSP valobj_sp = m_backend.GetSP();
   m_ptr_size = 0;
@@ -863,14 +983,15 @@ bool lldb_private::formatters::NSDiction
   return false;
 }
 
-bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
-    MightHaveChildren() {
+bool
+lldb_private::formatters::Foundation1100::
+  NSDictionaryMSyntheticFrontEnd::MightHaveChildren() {
   return true;
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::GetChildAtIndex(
-    size_t idx) {
+lldb_private::formatters::Foundation1100::
+  NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
   lldb::addr_t m_keys_ptr =
       (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
   lldb::addr_t m_values_ptr =

Modified: lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp?rev=310959&r1=310958&r2=310959&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp Tue Aug 15 14:23:14 2017
@@ -135,7 +135,7 @@ namespace Foundation1300 {
       GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
 }
   
-namespace Foundation1400 {
+namespace Foundation1428 {
   struct DataDescriptor_32 {
     uint32_t _used : 26;
     uint32_t _size;
@@ -154,6 +154,64 @@ namespace Foundation1400 {
       GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
 }
   
+namespace Foundation1437 {
+  struct DataDescriptor_32 {
+    uint32_t _cow;
+    // __table storage
+    uint32_t _objs_addr;
+    union {
+      uint32_t _mutations;
+      struct {
+        uint32_t _muts;
+        uint32_t _used : 26;
+        uint32_t _szidx : 6;
+      };
+    };
+  };
+  
+  struct DataDescriptor_64 {
+    uint64_t _cow;
+    // __Table storage
+    uint64_t _objs_addr;
+    union {
+      uint64_t _mutations;
+      struct {
+        uint32_t _muts;
+        uint32_t _used : 26;
+        uint32_t _szidx : 6;
+      };
+    };
+  };
+  
+  using NSSetMSyntheticFrontEnd =
+      GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+  
+  template <typename DD>
+  uint64_t
+  __NSSetMSize_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
+  __NSSetMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
+               Status &error) {
+    if (process.GetAddressByteSize() == 4) {
+      return __NSSetMSize_Impl<DataDescriptor_32>(process, valobj_addr, error);
+    } else {
+      return __NSSetMSize_Impl<DataDescriptor_64>(process, valobj_addr, error);
+    }
+  }
+}
+  
 class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
   NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
@@ -219,12 +277,18 @@ bool lldb_private::formatters::NSSetSumm
       return false;
     value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
   } else if (!strcmp(class_name, "__NSSetM")) {
+    AppleObjCRuntime *apple_runtime =
+        llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
     Status error;
-    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
-                                                      ptr_size, 0, error);
+    if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) {
+      value = Foundation1437::__NSSetMSize(*process_sp, valobj_addr, error);
+    } else {
+      value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                        ptr_size, 0, error);
+      value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+    }
     if (error.Fail())
       return false;
-    value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
   }
   /*else if (!strcmp(class_name,"__NSCFSet"))
    {
@@ -312,10 +376,16 @@ lldb_private::formatters::NSSetSynthetic
   } else if (!strcmp(class_name, "__NSSetM")) {
     AppleObjCRuntime *apple_runtime =
         llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
-    if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1400)
-      return (new Foundation1400::NSSetMSyntheticFrontEnd(valobj_sp));
-    else
+    if (apple_runtime) {
+      if (apple_runtime->GetFoundationVersion() >= 1437)
+        return (new Foundation1437::NSSetMSyntheticFrontEnd(valobj_sp));
+      else if (apple_runtime->GetFoundationVersion() >= 1428)
+        return (new Foundation1428::NSSetMSyntheticFrontEnd(valobj_sp));
+      else
+        return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
+    } else {
       return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
+    }
   } else {
     auto &map(NSSet_Additionals::GetAdditionalSynthetics());
     auto iter = map.find(class_name_cs), end = map.end();




More information about the lldb-commits mailing list