diff --git a/lldb/source/Plugins/Language/ObjC/CF.cpp b/lldb/source/Plugins/Language/ObjC/CF.cpp
index 617bb613..f67db46 100644
--- a/lldb/source/Plugins/Language/ObjC/CF.cpp
+++ b/lldb/source/Plugins/Language/ObjC/CF.cpp
@@ -1,4 +1,5 @@
-//===-- CF.cpp ----------------------------------------------------*- C++ -*-===//
+//===-- CF.cpp ----------------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -26,293 +27,277 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-bool
-lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    time_t epoch = GetOSXEpoch();
-    epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
-    tm *tm_date = localtime(&epoch);
-    if (!tm_date)
-        return false;
-    std::string buffer(1024,0);
-    if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
-        return false;
-    stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
-    return true;
+bool lldb_private::formatters::CFAbsoluteTimeSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  time_t epoch = GetOSXEpoch();
+  epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
+  tm *tm_date = localtime(&epoch);
+  if (!tm_date)
+    return false;
+  std::string buffer(1024, 0);
+  if (strftime(&buffer[0], 1023, "%Z", tm_date) == 0)
+    return false;
+  stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year + 1900,
+                tm_date->tm_mon + 1, tm_date->tm_mday, tm_date->tm_hour,
+                tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+  return true;
 }
 
-bool
-lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    static ConstString g_TypeHint("CFBag");
-    
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint32_t count = 0;
-    
-    bool is_type_ok = false; // check to see if this is a CFBag we know about
-    if (descriptor->IsCFType())
-    {
-        ConstString type_name(valobj.GetTypeName());
-        
-        static ConstString g___CFBag("__CFBag");
-        static ConstString g_conststruct__CFBag("const struct __CFBag");
-        
-        if (type_name == g___CFBag ||
-            type_name == g_conststruct__CFBag)
-        {
-            if (valobj.IsPointerType())
-                is_type_ok = true;
-        }
-    }
-    
-    if (is_type_ok)
-    {
-        lldb::addr_t offset = 2*ptr_size+4 + valobj_addr;
-        Error error;
-        count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
-        if (error.Fail())
-            return false;
-    }
-    else
-        return false;
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(options.GetLanguage()))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s\"%u value%s\"%s",
-                  prefix.c_str(),
-                  count,(count == 1 ? "" : "s"),
-                  suffix.c_str());
-    return true;
-}
+bool lldb_private::formatters::CFBagSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  static ConstString g_TypeHint("CFBag");
 
-bool
-lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint32_t count = 0;
-    
-    bool is_type_ok = false; // check to see if this is a CFBag we know about
-    if (descriptor->IsCFType())
-    {
-        ConstString type_name(valobj.GetTypeName());
-        if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef"))
-        {
-            if (valobj.IsPointerType())
-                is_type_ok = true;
-        }
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  if (!runtime)
+    return false;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(valobj));
+
+  if (!descriptor.get() || !descriptor->IsValid())
+    return false;
+
+  uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+  if (!valobj_addr)
+    return false;
+
+  uint32_t count = 0;
+
+  bool is_type_ok = false; // check to see if this is a CFBag we know about
+  if (descriptor->IsCFType()) {
+    ConstString type_name(valobj.GetTypeName());
+
+    static ConstString g___CFBag("__CFBag");
+    static ConstString g_conststruct__CFBag("const struct __CFBag");
+
+    if (type_name == g___CFBag || type_name == g_conststruct__CFBag) {
+      if (valobj.IsPointerType())
+        is_type_ok = true;
     }
-    
-    if (is_type_ok == false)
-        return false;
-    
+  }
+
+  if (is_type_ok) {
+    lldb::addr_t offset = 2 * ptr_size + 4 + valobj_addr;
     Error error;
-    count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
+    count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
     if (error.Fail())
-        return false;
-    uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
-    addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error);
-    if (error.Fail())
-        return false;
-    // make sure we do not try to read huge amounts of data
-    if (num_bytes > 1024)
-        num_bytes = 1024;
-    DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0));
-    num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
-    if (error.Fail() || num_bytes == 0)
-        return false;
-    uint8_t *bytes = buffer_sp->GetBytes();
-    for (uint64_t byte_idx = 0; byte_idx < num_bytes-1; byte_idx++)
-    {
-        uint8_t byte = bytes[byte_idx];
-        bool bit0 = (byte & 1) == 1;
-        bool bit1 = (byte & 2) == 2;
-        bool bit2 = (byte & 4) == 4;
-        bool bit3 = (byte & 8) == 8;
-        bool bit4 = (byte & 16) == 16;
-        bool bit5 = (byte & 32) == 32;
-        bool bit6 = (byte & 64) == 64;
-        bool bit7 = (byte & 128) == 128;
-        stream.Printf("%c%c%c%c %c%c%c%c ",
-                      (bit7 ? '1' : '0'),
-                      (bit6 ? '1' : '0'),
-                      (bit5 ? '1' : '0'),
-                      (bit4 ? '1' : '0'),
-                      (bit3 ? '1' : '0'),
-                      (bit2 ? '1' : '0'),
-                      (bit1 ? '1' : '0'),
-                      (bit0 ? '1' : '0'));
-        count -= 8;
+      return false;
+  } else
+    return false;
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
     }
-    {
-        // print the last byte ensuring we do not print spurious bits
-        uint8_t byte = bytes[num_bytes-1];
-        bool bit0 = (byte & 1) == 1;
-        bool bit1 = (byte & 2) == 2;
-        bool bit2 = (byte & 4) == 4;
-        bool bit3 = (byte & 8) == 8;
-        bool bit4 = (byte & 16) == 16;
-        bool bit5 = (byte & 32) == 32;
-        bool bit6 = (byte & 64) == 64;
-        bool bit7 = (byte & 128) == 128;
-        if (count)
-        {
-            stream.Printf("%c",bit7 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit6 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit5 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit4 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit3 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit2 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit1 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-            stream.Printf("%c",bit0 ? '1' : '0');
-    }
-    return true;
+  }
+
+  stream.Printf("%s\"%u value%s\"%s", prefix.c_str(), count,
+                (count == 1 ? "" : "s"), suffix.c_str());
+  return true;
 }
 
-bool
-lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    static ConstString g_TypeHint("CFBinaryHeap");
-    
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint32_t count = 0;
-    
-    bool is_type_ok = false; // check to see if this is a CFBinaryHeap we know about
-    if (descriptor->IsCFType())
-    {
-        ConstString type_name(valobj.GetTypeName());
-        
-        static ConstString g___CFBinaryHeap("__CFBinaryHeap");
-        static ConstString g_conststruct__CFBinaryHeap("const struct __CFBinaryHeap");
-        static ConstString g_CFBinaryHeapRef("CFBinaryHeapRef");
+bool lldb_private::formatters::CFBitVectorSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
 
-        if (type_name == g___CFBinaryHeap ||
-            type_name == g_conststruct__CFBinaryHeap ||
-            type_name == g_CFBinaryHeapRef)
-        {
-            if (valobj.IsPointerType())
-                is_type_ok = true;
-        }
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  if (!runtime)
+    return false;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(valobj));
+
+  if (!descriptor.get() || !descriptor->IsValid())
+    return false;
+
+  uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+  if (!valobj_addr)
+    return false;
+
+  uint32_t count = 0;
+
+  bool is_type_ok = false; // check to see if this is a CFBag we know about
+  if (descriptor->IsCFType()) {
+    ConstString type_name(valobj.GetTypeName());
+    if (type_name == ConstString("__CFMutableBitVector") ||
+        type_name == ConstString("__CFBitVector") ||
+        type_name == ConstString("CFMutableBitVectorRef") ||
+        type_name == ConstString("CFBitVectorRef")) {
+      if (valobj.IsPointerType())
+        is_type_ok = true;
     }
-    
-    if (is_type_ok)
-    {
-        lldb::addr_t offset = 2*ptr_size + valobj_addr;
-        Error error;
-        count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
-        if (error.Fail())
-            return false;
+  }
+
+  if (is_type_ok == false)
+    return false;
+
+  Error error;
+  count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size,
+                                                    ptr_size, 0, error);
+  if (error.Fail())
+    return false;
+  uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
+  addr_t data_ptr = process_sp->ReadPointerFromMemory(
+      valobj_addr + 2 * ptr_size + 2 * ptr_size, error);
+  if (error.Fail())
+    return false;
+  // make sure we do not try to read huge amounts of data
+  if (num_bytes > 1024)
+    num_bytes = 1024;
+  DataBufferSP buffer_sp(new DataBufferHeap(num_bytes, 0));
+  num_bytes =
+      process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
+  if (error.Fail() || num_bytes == 0)
+    return false;
+  uint8_t *bytes = buffer_sp->GetBytes();
+  for (uint64_t byte_idx = 0; byte_idx < num_bytes - 1; byte_idx++) {
+    uint8_t byte = bytes[byte_idx];
+    bool bit0 = (byte & 1) == 1;
+    bool bit1 = (byte & 2) == 2;
+    bool bit2 = (byte & 4) == 4;
+    bool bit3 = (byte & 8) == 8;
+    bool bit4 = (byte & 16) == 16;
+    bool bit5 = (byte & 32) == 32;
+    bool bit6 = (byte & 64) == 64;
+    bool bit7 = (byte & 128) == 128;
+    stream.Printf("%c%c%c%c %c%c%c%c ", (bit7 ? '1' : '0'), (bit6 ? '1' : '0'),
+                  (bit5 ? '1' : '0'), (bit4 ? '1' : '0'), (bit3 ? '1' : '0'),
+                  (bit2 ? '1' : '0'), (bit1 ? '1' : '0'), (bit0 ? '1' : '0'));
+    count -= 8;
+  }
+  {
+    // print the last byte ensuring we do not print spurious bits
+    uint8_t byte = bytes[num_bytes - 1];
+    bool bit0 = (byte & 1) == 1;
+    bool bit1 = (byte & 2) == 2;
+    bool bit2 = (byte & 4) == 4;
+    bool bit3 = (byte & 8) == 8;
+    bool bit4 = (byte & 16) == 16;
+    bool bit5 = (byte & 32) == 32;
+    bool bit6 = (byte & 64) == 64;
+    bool bit7 = (byte & 128) == 128;
+    if (count) {
+      stream.Printf("%c", bit7 ? '1' : '0');
+      count -= 1;
     }
-    else
-        return false;
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(options.GetLanguage()))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
+    if (count) {
+      stream.Printf("%c", bit6 ? '1' : '0');
+      count -= 1;
     }
-    
-    stream.Printf("%s\"%u item%s\"%s",
-                  prefix.c_str(),
-                  count,(count == 1 ? "" : "s"),
-                  suffix.c_str());
-    return true;
+    if (count) {
+      stream.Printf("%c", bit5 ? '1' : '0');
+      count -= 1;
+    }
+    if (count) {
+      stream.Printf("%c", bit4 ? '1' : '0');
+      count -= 1;
+    }
+    if (count) {
+      stream.Printf("%c", bit3 ? '1' : '0');
+      count -= 1;
+    }
+    if (count) {
+      stream.Printf("%c", bit2 ? '1' : '0');
+      count -= 1;
+    }
+    if (count) {
+      stream.Printf("%c", bit1 ? '1' : '0');
+      count -= 1;
+    }
+    if (count)
+      stream.Printf("%c", bit0 ? '1' : '0');
+  }
+  return true;
+}
+
+bool lldb_private::formatters::CFBinaryHeapSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  static ConstString g_TypeHint("CFBinaryHeap");
+
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  if (!runtime)
+    return false;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(valobj));
+
+  if (!descriptor.get() || !descriptor->IsValid())
+    return false;
+
+  uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+  if (!valobj_addr)
+    return false;
+
+  uint32_t count = 0;
+
+  bool is_type_ok =
+      false; // check to see if this is a CFBinaryHeap we know about
+  if (descriptor->IsCFType()) {
+    ConstString type_name(valobj.GetTypeName());
+
+    static ConstString g___CFBinaryHeap("__CFBinaryHeap");
+    static ConstString g_conststruct__CFBinaryHeap(
+        "const struct __CFBinaryHeap");
+    static ConstString g_CFBinaryHeapRef("CFBinaryHeapRef");
+
+    if (type_name == g___CFBinaryHeap ||
+        type_name == g_conststruct__CFBinaryHeap ||
+        type_name == g_CFBinaryHeapRef) {
+      if (valobj.IsPointerType())
+        is_type_ok = true;
+    }
+  }
+
+  if (is_type_ok) {
+    lldb::addr_t offset = 2 * ptr_size + valobj_addr;
+    Error error;
+    count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
+    if (error.Fail())
+      return false;
+  } else
+    return false;
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  stream.Printf("%s\"%u item%s\"%s", prefix.c_str(), count,
+                (count == 1 ? "" : "s"), suffix.c_str());
+  return true;
 }
diff --git a/lldb/source/Plugins/Language/ObjC/CF.h b/lldb/source/Plugins/Language/ObjC/CF.h
index 4044f09..ea47267 100644
--- a/lldb/source/Plugins/Language/ObjC/CF.h
+++ b/lldb/source/Plugins/Language/ObjC/CF.h
@@ -15,20 +15,19 @@
 #include "lldb/DataFormatters/TypeSummary.h"
 
 namespace lldb_private {
-    namespace formatters
-    {
-        bool
-        CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-    } // namespace formatters
+namespace formatters {
+bool CFBagSummaryProvider(ValueObject &valobj, Stream &stream,
+                          const TypeSummaryOptions &options);
+
+bool CFBinaryHeapSummaryProvider(ValueObject &valobj, Stream &stream,
+                                 const TypeSummaryOptions &options);
+
+bool CFBitVectorSummaryProvider(ValueObject &valobj, Stream &stream,
+                                const TypeSummaryOptions &options);
+
+bool CFAbsoluteTimeSummaryProvider(ValueObject &valobj, Stream &stream,
+                                   const TypeSummaryOptions &options);
+} // namespace formatters
 } // namespace lldb_private
 
 #endif // liblldb_CF_h_
diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
index e09a700..e23f6a5 100644
--- a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -26,8 +26,8 @@
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Target/Language.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Target/Target.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Utility/ProcessStructReader.h"
 
 #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
@@ -38,964 +38,904 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-bool
-lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"NSBundle"))
-    {
-        uint64_t offset = 5 * ptr_size;
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID), true));
-        
-        StreamString summary_stream;
-        bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
-        if (was_nsstring_ok && summary_stream.GetSize() > 0)
-        {
-            stream.Printf("%s",summary_stream.GetData());
-            return true;
-        }
-    }
-    
+bool lldb_private::formatters::NSBundleSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
     return false;
-}
 
-bool
-lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"__NSTimeZone"))
-    {
-        uint64_t offset = ptr_size;
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType(), true));
-        StreamString summary_stream;
-        bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
-        if (was_nsstring_ok && summary_stream.GetSize() > 0)
-        {
-            stream.Printf("%s",summary_stream.GetData());
-            return true;
-        }
-    }
-    
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  if (!runtime)
     return false;
-}
 
-bool
-lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"NSConcreteNotification"))
-    {
-        uint64_t offset = ptr_size;
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType(), true));
-        StreamString summary_stream;
-        bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options);
-        if (was_nsstring_ok && summary_stream.GetSize() > 0)
-        {
-            stream.Printf("%s",summary_stream.GetData());
-            return true;
-        }
-    }
-    
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(valobj));
+
+  if (!descriptor || !descriptor->IsValid())
     return false;
-}
 
-bool
-lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    uint64_t port_number = 0;
-    
-    if (!strcmp(class_name,"NSMachPort"))
-    {
-        uint64_t offset = (ptr_size == 4 ? 12 : 20);
-        Error error;
-        port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error);
-        if (error.Success())
-        {
-            stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF));
-            return true;
-        }
-    }
-    
+  uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+  if (!valobj_addr)
     return false;
-}
 
-bool
-lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    uint64_t count = 0;
-    
-    do {
-        if (!strcmp(class_name,"NSIndexSet") || !strcmp(class_name,"NSMutableIndexSet"))
-        {
-            Error error;
-            uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 4, 0, error);
-            if (error.Fail())
-                return false;
-            // this means the set is empty - count = 0
-            if ((mode & 1) == 1)
-            {
-                count = 0;
-                break;
-            }
-            if ((mode & 2) == 2)
-                mode = 1; // this means the set only has one range
-            else
-                mode = 2; // this means the set has multiple ranges
-            if (mode == 1)
-            {
-                count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+3*ptr_size, ptr_size, 0, error);
-                if (error.Fail())
-                    return false;
-            }
-            else
-            {
-                // read a pointer to the data at 2*ptr_size
-                count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
-                if (error.Fail())
-                    return false;
-                // read the data at 2*ptr_size from the first location
-                count = process_sp->ReadUnsignedIntegerFromMemory(count+2*ptr_size, ptr_size, 0, error);
-                if (error.Fail())
-                    return false;
-            }
-        }
-        else
-            return false;
-    }  while (false);
-    stream.Printf("%" PRIu64 " index%s",
-                  count,
-                  (count == 1 ? "" : "es"));
-    return true;
-}
+  const char *class_name = descriptor->GetClassName().GetCString();
 
-static void
-NSNumber_FormatChar (ValueObject& valobj,
-                     Stream& stream,
-                     char value,
-                     lldb::LanguageType lang)
-{
-    static ConstString g_TypeHint("NSNumber:char");
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(lang))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%hhd%s",
-                  prefix.c_str(),
-                  value,
-                  suffix.c_str());
-}
-
-static void
-NSNumber_FormatShort (ValueObject& valobj,
-                      Stream& stream,
-                      short value,
-                      lldb::LanguageType lang)
-{
-    static ConstString g_TypeHint("NSNumber:short");
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(lang))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%hd%s",
-                  prefix.c_str(),
-                  value,
-                  suffix.c_str());
-}
-
-static void
-NSNumber_FormatInt (ValueObject& valobj,
-                    Stream& stream,
-                    int value,
-                    lldb::LanguageType lang)
-{
-    static ConstString g_TypeHint("NSNumber:int");
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(lang))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%d%s",
-                  prefix.c_str(),
-                  value,
-                  suffix.c_str());
-}
-
-static void
-NSNumber_FormatLong (ValueObject& valobj,
-                     Stream& stream,
-                     uint64_t value,
-                     lldb::LanguageType lang)
-{
-    static ConstString g_TypeHint("NSNumber:long");
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(lang))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%" PRId64 "%s",
-                  prefix.c_str(),
-                  value,
-                  suffix.c_str());
-}
-
-static void
-NSNumber_FormatFloat (ValueObject& valobj,
-                      Stream& stream,
-                      float value,
-                      lldb::LanguageType lang)
-{
-    static ConstString g_TypeHint("NSNumber:float");
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(lang))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%f%s",
-                  prefix.c_str(),
-                  value,
-                  suffix.c_str());
-}
-
-static void
-NSNumber_FormatDouble (ValueObject& valobj,
-                       Stream& stream,
-                       double value,
-                       lldb::LanguageType lang)
-{
-    static ConstString g_TypeHint("NSNumber:double");
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(lang))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%g%s",
-                  prefix.c_str(),
-                  value,
-                  suffix.c_str());
-}
-
-bool
-lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name, "__NSCFBoolean"))
-        return ObjCBooleanSummaryProvider(valobj, stream, options);
-
-    if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
-    {
-        uint64_t value = 0;
-        uint64_t i_bits = 0;
-        if (descriptor->GetTaggedPointerInfo(&i_bits,&value))
-        {
-            switch (i_bits)
-            {
-                case 0:
-                    NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
-                    break;
-                case 1:
-                case 4:
-                    NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage());
-                    break;
-                case 2:
-                case 8:
-                    NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
-                    break;
-                case 3:
-                case 12:
-                    NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
-                    break;
-                default:
-                    return false;
-            }
-            return true;
-        }
-        else
-        {
-            Error error;
-            uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
-            uint64_t data_location = valobj_addr + 2*ptr_size;
-            uint64_t value = 0;
-            if (error.Fail())
-                return false;
-            switch (data_type)
-            {
-                case 1: // 0B00001
-                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
-                    if (error.Fail())
-                        return false;
-                    NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
-                    break;
-                case 2: // 0B0010
-                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
-                    if (error.Fail())
-                        return false;
-                    NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage());
-                    break;
-                case 3: // 0B0011
-                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
-                    if (error.Fail())
-                        return false;
-                    NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
-                    break;
-                case 17: // 0B10001
-                    data_location += 8;
-                    LLVM_FALLTHROUGH;
-                case 4: // 0B0100
-                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
-                    if (error.Fail())
-                        return false;
-                    NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
-                    break;
-                case 5: // 0B0101
-                {
-                    uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
-                    if (error.Fail())
-                        return false;
-                    float flt_value = 0.0f;
-                    memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
-                    NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
-                    break;
-                }
-                case 6: // 0B0110
-                {
-                    uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
-                    if (error.Fail())
-                        return false;
-                    double dbl_value = 0.0;
-                    memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
-                    NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
-                    break;
-                }
-                default:
-                    return false;
-            }
-            return true;
-        }
-    }
-
+  if (!class_name || !*class_name)
     return false;
+
+  if (!strcmp(class_name, "NSBundle")) {
+    uint64_t offset = 5 * ptr_size;
+    ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
+        offset,
+        valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID),
+        true));
+
+    StreamString summary_stream;
+    bool was_nsstring_ok =
+        NSStringSummaryProvider(*text, summary_stream, options);
+    if (was_nsstring_ok && summary_stream.GetSize() > 0) {
+      stream.Printf("%s", summary_stream.GetData());
+      return true;
+    }
+  }
+
+  return false;
 }
 
-bool
-lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (strcmp(class_name, "NSURL") == 0)
-    {
-        uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
-        uint64_t offset_base = offset_text + ptr_size;
-        CompilerType type(valobj.GetCompilerType());
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
-        ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
-        if (!text)
-            return false;
-        if (text->GetValueAsUnsigned(0) == 0)
-            return false;
-        StreamString summary;
-        if (!NSStringSummaryProvider(*text, summary, options))
-            return false;
-        if (base && base->GetValueAsUnsigned(0))
-        {
-            if (summary.GetSize() > 0)
-                summary.GetString().resize(summary.GetSize()-1);
-            summary.Printf(" -- ");
-            StreamString base_summary;
-            if (NSURLSummaryProvider(*base, base_summary, options) && base_summary.GetSize() > 0)
-                summary.Printf("%s",base_summary.GetSize() > 2 ? base_summary.GetData() + 2 : base_summary.GetData());
-        }
-        if (summary.GetSize())
-        {
-            stream.Printf("%s",summary.GetData());
-            return true;
-        }
-    }
-
+bool lldb_private::formatters::NSTimeZoneSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
     return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  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;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  if (!strcmp(class_name, "__NSTimeZone")) {
+    uint64_t offset = ptr_size;
+    ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
+        offset, valobj.GetCompilerType(), true));
+    StreamString summary_stream;
+    bool was_nsstring_ok =
+        NSStringSummaryProvider(*text, summary_stream, options);
+    if (was_nsstring_ok && summary_stream.GetSize() > 0) {
+      stream.Printf("%s", summary_stream.GetData());
+      return true;
+    }
+  }
+
+  return false;
 }
 
-bool
-lldb_private::formatters::NSDateSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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 date_value_bits = 0;
-    double date_value = 0.0;
-    
-    ConstString class_name = descriptor->GetClassName();
-    
-    static const ConstString g_NSDate("NSDate");
-    static const ConstString g___NSDate("__NSDate");
-    static const ConstString g___NSTaggedDate("__NSTaggedDate");
-    static const ConstString g_NSCalendarDate("NSCalendarDate");
+bool lldb_private::formatters::NSNotificationSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
 
-    if (class_name.IsEmpty())
-        return false;
-    
-    if ((class_name == g_NSDate) ||
-        (class_name == g___NSDate) ||
-        (class_name == g___NSTaggedDate))
-    {
-        uint64_t info_bits=0,value_bits = 0;
-        if (descriptor->GetTaggedPointerInfo(&info_bits,&value_bits))
-        {
-            date_value_bits = ((value_bits << 8) | (info_bits << 4));
-            memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
-        }
-        else
-        {
-            llvm::Triple triple(process_sp->GetTarget().GetArchitecture().GetTriple());
-            uint32_t delta = (triple.isWatchOS() && triple.isWatchABI()) ? 8 : ptr_size;
-            Error error;
-            date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+delta, 8, 0, error);
-            memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
-            if (error.Fail())
-                return false;
-        }
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  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;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  if (!strcmp(class_name, "NSConcreteNotification")) {
+    uint64_t offset = ptr_size;
+    ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
+        offset, valobj.GetCompilerType(), true));
+    StreamString summary_stream;
+    bool was_nsstring_ok =
+        NSStringSummaryProvider(*text, summary_stream, options);
+    if (was_nsstring_ok && summary_stream.GetSize() > 0) {
+      stream.Printf("%s", summary_stream.GetData());
+      return true;
     }
-    else if (class_name == g_NSCalendarDate)
-    {
-        Error error;
-        date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, 8, 0, error);
-        memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
+  }
+
+  return false;
+}
+
+bool lldb_private::formatters::NSMachPortSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  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;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  uint64_t port_number = 0;
+
+  if (!strcmp(class_name, "NSMachPort")) {
+    uint64_t offset = (ptr_size == 4 ? 12 : 20);
+    Error error;
+    port_number = process_sp->ReadUnsignedIntegerFromMemory(
+        offset + valobj_addr, 4, 0, error);
+    if (error.Success()) {
+      stream.Printf("mach port: %u",
+                    (uint32_t)(port_number & 0x00000000FFFFFFFF));
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool lldb_private::formatters::NSIndexSetSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  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;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  uint64_t count = 0;
+
+  do {
+    if (!strcmp(class_name, "NSIndexSet") ||
+        !strcmp(class_name, "NSMutableIndexSet")) {
+      Error error;
+      uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(
+          valobj_addr + ptr_size, 4, 0, error);
+      if (error.Fail())
+        return false;
+      // this means the set is empty - count = 0
+      if ((mode & 1) == 1) {
+        count = 0;
+        break;
+      }
+      if ((mode & 2) == 2)
+        mode = 1; // this means the set only has one range
+      else
+        mode = 2; // this means the set has multiple ranges
+      if (mode == 1) {
+        count = process_sp->ReadUnsignedIntegerFromMemory(
+            valobj_addr + 3 * ptr_size, ptr_size, 0, error);
         if (error.Fail())
-            return false;
-    }
-    else
-        return false;
-
-    if (date_value == -63114076800)
-    {
-        stream.Printf("0001-12-30 00:00:00 +0000");
-        return true;
-    }
-    // this snippet of code assumes that time_t == seconds since Jan-1-1970
-    // this is generally true and POSIXly happy, but might break if a library
-    // vendor decides to get creative
-    time_t epoch = GetOSXEpoch();
-    epoch = epoch + (time_t)date_value;
-    tm *tm_date = gmtime(&epoch);
-    if (!tm_date)
-        return false;
-    std::string buffer(1024,0);
-    if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
-        return false;
-    stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
-    return true;
+          return false;
+      } else {
+        // read a pointer to the data at 2*ptr_size
+        count = process_sp->ReadUnsignedIntegerFromMemory(
+            valobj_addr + 2 * ptr_size, ptr_size, 0, error);
+        if (error.Fail())
+          return false;
+        // read the data at 2*ptr_size from the first location
+        count = process_sp->ReadUnsignedIntegerFromMemory(count + 2 * ptr_size,
+                                                          ptr_size, 0, error);
+        if (error.Fail())
+          return false;
+      }
+    } else
+      return false;
+  } while (false);
+  stream.Printf("%" PRIu64 " index%s", count, (count == 1 ? "" : "es"));
+  return true;
 }
 
-bool
-lldb_private::formatters::ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0)));
-    
-    if (!descriptor || !descriptor->IsValid())
-        return false;
-    
-    ConstString class_name = descriptor->GetClassName();
-    
-    if (class_name.IsEmpty())
-        return false;
-    
-    if (ConstString cs = Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown))
-        class_name = cs;
-    
-    stream.Printf("%s",class_name.AsCString("<unknown class>"));
-    return true;
+static void NSNumber_FormatChar(ValueObject &valobj, Stream &stream, char value,
+                                lldb::LanguageType lang) {
+  static ConstString g_TypeHint("NSNumber:char");
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(lang)) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  stream.Printf("%s%hhd%s", prefix.c_str(), value, suffix.c_str());
 }
 
-class ObjCClassSyntheticChildrenFrontEnd : public SyntheticChildrenFrontEnd
-{
+static void NSNumber_FormatShort(ValueObject &valobj, Stream &stream,
+                                 short value, lldb::LanguageType lang) {
+  static ConstString g_TypeHint("NSNumber:short");
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(lang)) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  stream.Printf("%s%hd%s", prefix.c_str(), value, suffix.c_str());
+}
+
+static void NSNumber_FormatInt(ValueObject &valobj, Stream &stream, int value,
+                               lldb::LanguageType lang) {
+  static ConstString g_TypeHint("NSNumber:int");
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(lang)) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  stream.Printf("%s%d%s", prefix.c_str(), value, suffix.c_str());
+}
+
+static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream,
+                                uint64_t value, lldb::LanguageType lang) {
+  static ConstString g_TypeHint("NSNumber:long");
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(lang)) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  stream.Printf("%s%" PRId64 "%s", prefix.c_str(), value, suffix.c_str());
+}
+
+static void NSNumber_FormatFloat(ValueObject &valobj, Stream &stream,
+                                 float value, lldb::LanguageType lang) {
+  static ConstString g_TypeHint("NSNumber:float");
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(lang)) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  stream.Printf("%s%f%s", prefix.c_str(), value, suffix.c_str());
+}
+
+static void NSNumber_FormatDouble(ValueObject &valobj, Stream &stream,
+                                  double value, lldb::LanguageType lang) {
+  static ConstString g_TypeHint("NSNumber:double");
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(lang)) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  stream.Printf("%s%g%s", prefix.c_str(), value, suffix.c_str());
+}
+
+bool lldb_private::formatters::NSNumberSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  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;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  if (!strcmp(class_name, "__NSCFBoolean"))
+    return ObjCBooleanSummaryProvider(valobj, stream, options);
+
+  if (!strcmp(class_name, "NSNumber") || !strcmp(class_name, "__NSCFNumber")) {
+    uint64_t value = 0;
+    uint64_t i_bits = 0;
+    if (descriptor->GetTaggedPointerInfo(&i_bits, &value)) {
+      switch (i_bits) {
+      case 0:
+        NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
+        break;
+      case 1:
+      case 4:
+        NSNumber_FormatShort(valobj, stream, (short)value,
+                             options.GetLanguage());
+        break;
+      case 2:
+      case 8:
+        NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
+        break;
+      case 3:
+      case 12:
+        NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
+        break;
+      default:
+        return false;
+      }
+      return true;
+    } else {
+      Error error;
+      uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(
+                               valobj_addr + ptr_size, 1, 0, error) &
+                           0x1F);
+      uint64_t data_location = valobj_addr + 2 * ptr_size;
+      uint64_t value = 0;
+      if (error.Fail())
+        return false;
+      switch (data_type) {
+      case 1: // 0B00001
+        value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0,
+                                                          error);
+        if (error.Fail())
+          return false;
+        NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
+        break;
+      case 2: // 0B0010
+        value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0,
+                                                          error);
+        if (error.Fail())
+          return false;
+        NSNumber_FormatShort(valobj, stream, (short)value,
+                             options.GetLanguage());
+        break;
+      case 3: // 0B0011
+        value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0,
+                                                          error);
+        if (error.Fail())
+          return false;
+        NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
+        break;
+      case 17: // 0B10001
+        data_location += 8;
+        LLVM_FALLTHROUGH;
+      case 4: // 0B0100
+        value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0,
+                                                          error);
+        if (error.Fail())
+          return false;
+        NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
+        break;
+      case 5: // 0B0101
+      {
+        uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(
+            data_location, 4, 0, error);
+        if (error.Fail())
+          return false;
+        float flt_value = 0.0f;
+        memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
+        NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
+        break;
+      }
+      case 6: // 0B0110
+      {
+        uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(
+            data_location, 8, 0, error);
+        if (error.Fail())
+          return false;
+        double dbl_value = 0.0;
+        memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
+        NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
+        break;
+      }
+      default:
+        return false;
+      }
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool lldb_private::formatters::NSURLSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  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;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  if (strcmp(class_name, "NSURL") == 0) {
+    uint64_t offset_text = ptr_size + ptr_size +
+                           8; // ISA + pointer + 8 bytes of data (even on 32bit)
+    uint64_t offset_base = offset_text + ptr_size;
+    CompilerType type(valobj.GetCompilerType());
+    ValueObjectSP text(
+        valobj.GetSyntheticChildAtOffset(offset_text, type, true));
+    ValueObjectSP base(
+        valobj.GetSyntheticChildAtOffset(offset_base, type, true));
+    if (!text)
+      return false;
+    if (text->GetValueAsUnsigned(0) == 0)
+      return false;
+    StreamString summary;
+    if (!NSStringSummaryProvider(*text, summary, options))
+      return false;
+    if (base && base->GetValueAsUnsigned(0)) {
+      if (summary.GetSize() > 0)
+        summary.GetString().resize(summary.GetSize() - 1);
+      summary.Printf(" -- ");
+      StreamString base_summary;
+      if (NSURLSummaryProvider(*base, base_summary, options) &&
+          base_summary.GetSize() > 0)
+        summary.Printf("%s", base_summary.GetSize() > 2
+                                 ? base_summary.GetData() + 2
+                                 : base_summary.GetData());
+    }
+    if (summary.GetSize()) {
+      stream.Printf("%s", summary.GetData());
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool lldb_private::formatters::NSDateSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  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 date_value_bits = 0;
+  double date_value = 0.0;
+
+  ConstString class_name = descriptor->GetClassName();
+
+  static const ConstString g_NSDate("NSDate");
+  static const ConstString g___NSDate("__NSDate");
+  static const ConstString g___NSTaggedDate("__NSTaggedDate");
+  static const ConstString g_NSCalendarDate("NSCalendarDate");
+
+  if (class_name.IsEmpty())
+    return false;
+
+  if ((class_name == g_NSDate) || (class_name == g___NSDate) ||
+      (class_name == g___NSTaggedDate)) {
+    uint64_t info_bits = 0, value_bits = 0;
+    if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits)) {
+      date_value_bits = ((value_bits << 8) | (info_bits << 4));
+      memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
+    } else {
+      llvm::Triple triple(
+          process_sp->GetTarget().GetArchitecture().GetTriple());
+      uint32_t delta =
+          (triple.isWatchOS() && triple.isWatchABI()) ? 8 : ptr_size;
+      Error error;
+      date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(
+          valobj_addr + delta, 8, 0, error);
+      memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
+      if (error.Fail())
+        return false;
+    }
+  } else if (class_name == g_NSCalendarDate) {
+    Error error;
+    date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(
+        valobj_addr + 2 * ptr_size, 8, 0, error);
+    memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
+    if (error.Fail())
+      return false;
+  } else
+    return false;
+
+  if (date_value == -63114076800) {
+    stream.Printf("0001-12-30 00:00:00 +0000");
+    return true;
+  }
+  // this snippet of code assumes that time_t == seconds since Jan-1-1970
+  // this is generally true and POSIXly happy, but might break if a library
+  // vendor decides to get creative
+  time_t epoch = GetOSXEpoch();
+  epoch = epoch + (time_t)date_value;
+  tm *tm_date = gmtime(&epoch);
+  if (!tm_date)
+    return false;
+  std::string buffer(1024, 0);
+  if (strftime(&buffer[0], 1023, "%Z", tm_date) == 0)
+    return false;
+  stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year + 1900,
+                tm_date->tm_mon + 1, tm_date->tm_mday, tm_date->tm_hour,
+                tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+  return true;
+}
+
+bool lldb_private::formatters::ObjCClassSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  if (!runtime)
+    return false;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0)));
+
+  if (!descriptor || !descriptor->IsValid())
+    return false;
+
+  ConstString class_name = descriptor->GetClassName();
+
+  if (class_name.IsEmpty())
+    return false;
+
+  if (ConstString cs =
+          Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown))
+    class_name = cs;
+
+  stream.Printf("%s", class_name.AsCString("<unknown class>"));
+  return true;
+}
+
+class ObjCClassSyntheticChildrenFrontEnd : public SyntheticChildrenFrontEnd {
 public:
-    ObjCClassSyntheticChildrenFrontEnd (lldb::ValueObjectSP valobj_sp) :
-        SyntheticChildrenFrontEnd(*valobj_sp)
-    {
-    }
-    
-    ~ObjCClassSyntheticChildrenFrontEnd() override = default;
+  ObjCClassSyntheticChildrenFrontEnd(lldb::ValueObjectSP valobj_sp)
+      : SyntheticChildrenFrontEnd(*valobj_sp) {}
 
-    size_t
-    CalculateNumChildren() override
-    {
-        return 0;
-    }
-    
-    lldb::ValueObjectSP
-    GetChildAtIndex(size_t idx) override
-    {
-        return lldb::ValueObjectSP();
-    }
-    
-    bool
-    Update() override
-    {
-        return false;
-    }
-    
-    bool
-    MightHaveChildren() override
-    {
-        return false;
-    }
-    
-    size_t
-    GetIndexOfChildWithName(const ConstString &name) override
-    {
-        return UINT32_MAX;
-    }
+  ~ObjCClassSyntheticChildrenFrontEnd() override = default;
+
+  size_t CalculateNumChildren() override { return 0; }
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
+    return lldb::ValueObjectSP();
+  }
+
+  bool Update() override { return false; }
+
+  bool MightHaveChildren() override { return false; }
+
+  size_t GetIndexOfChildWithName(const ConstString &name) override {
+    return UINT32_MAX;
+  }
 };
 
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::ObjCClassSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
-    return new ObjCClassSyntheticChildrenFrontEnd(valobj_sp);
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::ObjCClassSyntheticFrontEndCreator(
+    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+  return new ObjCClassSyntheticChildrenFrontEnd(valobj_sp);
 }
 
-template<bool needs_at>
-bool
-lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor || !descriptor->IsValid())
-        return false;
-    
-    bool is_64bit = (process_sp->GetAddressByteSize() == 8);
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint64_t value = 0;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"NSConcreteData") ||
-        !strcmp(class_name,"NSConcreteMutableData") ||
-        !strcmp(class_name,"__NSCFData"))
-    {
-        uint32_t offset = (is_64bit ? 16 : 8);
-        Error error;
-        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
-        if (error.Fail())
-            return false;
-    }
-    else if (!strcmp(class_name, "_NSInlineData"))
-    {
-        uint32_t offset = (is_64bit ? 8 : 4);
-        Error error;
-        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, 2, 0, error);
-        if (error.Fail())
-            return false;
-    }
-    else if (!strcmp(class_name, "_NSZeroData"))
-    {
-        value = 0;
-    }
-    else
-        return false;
-    
-    stream.Printf("%s%" PRIu64 " byte%s%s",
-                  (needs_at ? "@\"" : ""),
-                  value,
-                  (value != 1 ? "s" : ""),
-                  (needs_at ? "\"" : ""));
-    
-    return true;
-}
-
-bool
-lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
-    
-    ValueObjectSP real_guy_sp = valobj.GetSP();
-    
-    if (type_info & eTypeIsPointer)
-    {
-        Error err;
-        real_guy_sp = valobj.Dereference(err);
-        if (err.Fail() || !real_guy_sp)
-            return false;
-    }
-    else if (type_info & eTypeIsReference)
-    {
-        real_guy_sp =  valobj.GetChildAtIndex(0, true);
-        if (!real_guy_sp)
-            return false;
-    }
-    uint8_t value = (real_guy_sp->GetValueAsUnsigned(0) & 0xFF);
-    switch (value)
-    {
-        case 0:
-            stream.Printf("NO");
-            break;
-        case 1:
-            stream.Printf("YES");
-            break;
-        default:
-            stream.Printf("%u",value);
-            break;
-    }
-    return true;
-}
-
-bool
-lldb_private::formatters::ObjCBooleanSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    lldb::addr_t valobj_ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-    if (valobj_ptr_value == LLDB_INVALID_ADDRESS)
-        return false;
-
-    ProcessSP process_sp(valobj.GetProcessSP());
-    if (!process_sp)
-        return false;
-
-    if (AppleObjCRuntime *objc_runtime = (AppleObjCRuntime*)process_sp->GetObjCLanguageRuntime())
-    {
-        lldb::addr_t cf_true = LLDB_INVALID_ADDRESS,
-                     cf_false = LLDB_INVALID_ADDRESS;
-        objc_runtime->GetValuesForGlobalCFBooleans(cf_true, cf_false);
-        if (valobj_ptr_value == cf_true)
-        {
-            stream.PutCString("YES");
-            return true;
-        }
-        if (valobj_ptr_value == cf_false)
-        {
-            stream.PutCString("NO");
-            return true;
-        }
-    }
-
+template <bool needs_at>
+bool lldb_private::formatters::NSDataSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
     return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  if (!runtime)
+    return false;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(valobj));
+
+  if (!descriptor || !descriptor->IsValid())
+    return false;
+
+  bool is_64bit = (process_sp->GetAddressByteSize() == 8);
+  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+  if (!valobj_addr)
+    return false;
+
+  uint64_t value = 0;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  if (!strcmp(class_name, "NSConcreteData") ||
+      !strcmp(class_name, "NSConcreteMutableData") ||
+      !strcmp(class_name, "__NSCFData")) {
+    uint32_t offset = (is_64bit ? 16 : 8);
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(
+        valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
+    if (error.Fail())
+      return false;
+  } else if (!strcmp(class_name, "_NSInlineData")) {
+    uint32_t offset = (is_64bit ? 8 : 4);
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, 2,
+                                                      0, error);
+    if (error.Fail())
+      return false;
+  } else if (!strcmp(class_name, "_NSZeroData")) {
+    value = 0;
+  } else
+    return false;
+
+  stream.Printf("%s%" PRIu64 " byte%s%s", (needs_at ? "@\"" : ""), value,
+                (value != 1 ? "s" : ""), (needs_at ? "\"" : ""));
+
+  return true;
+}
+
+bool lldb_private::formatters::ObjCBOOLSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
+
+  ValueObjectSP real_guy_sp = valobj.GetSP();
+
+  if (type_info & eTypeIsPointer) {
+    Error err;
+    real_guy_sp = valobj.Dereference(err);
+    if (err.Fail() || !real_guy_sp)
+      return false;
+  } else if (type_info & eTypeIsReference) {
+    real_guy_sp = valobj.GetChildAtIndex(0, true);
+    if (!real_guy_sp)
+      return false;
+  }
+  uint8_t value = (real_guy_sp->GetValueAsUnsigned(0) & 0xFF);
+  switch (value) {
+  case 0:
+    stream.Printf("NO");
+    break;
+  case 1:
+    stream.Printf("YES");
+    break;
+  default:
+    stream.Printf("%u", value);
+    break;
+  }
+  return true;
+}
+
+bool lldb_private::formatters::ObjCBooleanSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  lldb::addr_t valobj_ptr_value =
+      valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+  if (valobj_ptr_value == LLDB_INVALID_ADDRESS)
+    return false;
+
+  ProcessSP process_sp(valobj.GetProcessSP());
+  if (!process_sp)
+    return false;
+
+  if (AppleObjCRuntime *objc_runtime =
+          (AppleObjCRuntime *)process_sp->GetObjCLanguageRuntime()) {
+    lldb::addr_t cf_true = LLDB_INVALID_ADDRESS,
+                 cf_false = LLDB_INVALID_ADDRESS;
+    objc_runtime->GetValuesForGlobalCFBooleans(cf_true, cf_false);
+    if (valobj_ptr_value == cf_true) {
+      stream.PutCString("YES");
+      return true;
+    }
+    if (valobj_ptr_value == cf_false) {
+      stream.PutCString("NO");
+      return true;
+    }
+  }
+
+  return false;
 }
 
 template <bool is_sel_ptr>
-bool
-lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    lldb::ValueObjectSP valobj_sp;
-    
-    CompilerType charstar (valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeChar).GetPointerType());
-    
-    if (!charstar)
-        return false;
-    
-    ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
-    
-    if (is_sel_ptr)
-    {
-        lldb::addr_t data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-        if (data_address == LLDB_INVALID_ADDRESS)
-            return false;
-        valobj_sp = ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar);
-    }
-    else
-    {
-        DataExtractor data;
-        Error error;
-        valobj.GetData(data, error);
-        if (error.Fail())
-            return false;
-        valobj_sp = ValueObject::CreateValueObjectFromData("text", data, exe_ctx, charstar);
-    }
-    
-    if (!valobj_sp)
-        return false;
-    
-    stream.Printf("%s",valobj_sp->GetSummaryAsCString());
-    return true;
+bool lldb_private::formatters::ObjCSELSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  lldb::ValueObjectSP valobj_sp;
+
+  CompilerType charstar(valobj.GetCompilerType()
+                            .GetBasicTypeFromAST(eBasicTypeChar)
+                            .GetPointerType());
+
+  if (!charstar)
+    return false;
+
+  ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
+
+  if (is_sel_ptr) {
+    lldb::addr_t data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+    if (data_address == LLDB_INVALID_ADDRESS)
+      return false;
+    valobj_sp = ValueObject::CreateValueObjectFromAddress("text", data_address,
+                                                          exe_ctx, charstar);
+  } else {
+    DataExtractor data;
+    Error error;
+    valobj.GetData(data, error);
+    if (error.Fail())
+      return false;
+    valobj_sp =
+        ValueObject::CreateValueObjectFromData("text", data, exe_ctx, charstar);
+  }
+
+  if (!valobj_sp)
+    return false;
+
+  stream.Printf("%s", valobj_sp->GetSummaryAsCString());
+  return true;
 }
 
 // POSIX has an epoch on Jan-1-1970, but Cocoa prefers Jan-1-2001
 // this call gives the POSIX equivalent of the Cocoa epoch
-time_t
-lldb_private::formatters::GetOSXEpoch ()
-{
-    static time_t epoch = 0;
-    if (!epoch)
-    {
+time_t lldb_private::formatters::GetOSXEpoch() {
+  static time_t epoch = 0;
+  if (!epoch) {
 #ifndef _WIN32
-        tzset();
-        tm tm_epoch;
-        tm_epoch.tm_sec = 0;
-        tm_epoch.tm_hour = 0;
-        tm_epoch.tm_min = 0;
-        tm_epoch.tm_mon = 0;
-        tm_epoch.tm_mday = 1;
-        tm_epoch.tm_year = 2001-1900;
-        tm_epoch.tm_isdst = -1;
-        tm_epoch.tm_gmtoff = 0;
-        tm_epoch.tm_zone = nullptr;
-        epoch = timegm(&tm_epoch);
+    tzset();
+    tm tm_epoch;
+    tm_epoch.tm_sec = 0;
+    tm_epoch.tm_hour = 0;
+    tm_epoch.tm_min = 0;
+    tm_epoch.tm_mon = 0;
+    tm_epoch.tm_mday = 1;
+    tm_epoch.tm_year = 2001 - 1900;
+    tm_epoch.tm_isdst = -1;
+    tm_epoch.tm_gmtoff = 0;
+    tm_epoch.tm_zone = nullptr;
+    epoch = timegm(&tm_epoch);
 #endif
-    }
-    return epoch;
+  }
+  return epoch;
 }
 
-template bool
-lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::NSDataSummaryProvider<true>(
+    ValueObject &, Stream &, const TypeSummaryOptions &);
 
-template bool
-lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::NSDataSummaryProvider<false>(
+    ValueObject &, Stream &, const TypeSummaryOptions &);
 
-template bool
-lldb_private::formatters::ObjCSELSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::ObjCSELSummaryProvider<true>(
+    ValueObject &, Stream &, const TypeSummaryOptions &);
 
-template bool
-lldb_private::formatters::ObjCSELSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::ObjCSELSummaryProvider<false>(
+    ValueObject &, Stream &, const TypeSummaryOptions &);
diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.h b/lldb/source/Plugins/Language/ObjC/Cocoa.h
index 5ab3544..491a119 100644
--- a/lldb/source/Plugins/Language/ObjC/Cocoa.h
+++ b/lldb/source/Plugins/Language/ObjC/Cocoa.h
@@ -1,4 +1,5 @@
-//===-- Cocoa.h ---------------------------------------------------*- C++ -*-===//
+//===-- Cocoa.h ---------------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -17,92 +18,96 @@
 #include "lldb/Target/ObjCLanguageRuntime.h"
 
 namespace lldb_private {
-    namespace formatters
-    {
-        bool
-        NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        template<bool needs_at>
-        bool
-        NSDataSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSNumberSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSDateSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSBundleSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSURLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        extern template bool
-        NSDataSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-        
-        extern template bool
-        NSDataSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-        
-        SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-        
-        SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-        
-        bool
-        ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        SyntheticChildrenFrontEnd* ObjCClassSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-        
-        bool
-        ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+namespace formatters {
+bool NSIndexSetSummaryProvider(ValueObject &valobj, Stream &stream,
+                               const TypeSummaryOptions &options);
 
-        bool
-        ObjCBooleanSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        template <bool is_sel_ptr>
-        bool
-        ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        extern template bool
-        ObjCSELSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
-        
-        extern template bool
-        ObjCSELSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
-        
-        bool
-        NSError_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSException_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        SyntheticChildrenFrontEnd*
-        NSErrorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp);
-        
-        SyntheticChildrenFrontEnd*
-        NSExceptionSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp);
-        
-        class NSArray_Additionals
-        {
-        public:
-            static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-            GetAdditionalSummaries ();
-            
-            static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
-            GetAdditionalSynthetics ();
-        };
-    } // namespace formatters
+bool NSArraySummaryProvider(ValueObject &valobj, Stream &stream,
+                            const TypeSummaryOptions &options);
+
+template <bool needs_at>
+bool NSDataSummaryProvider(ValueObject &valobj, Stream &stream,
+                           const TypeSummaryOptions &options);
+
+bool NSNumberSummaryProvider(ValueObject &valobj, Stream &stream,
+                             const TypeSummaryOptions &options);
+
+bool NSNotificationSummaryProvider(ValueObject &valobj, Stream &stream,
+                                   const TypeSummaryOptions &options);
+
+bool NSTimeZoneSummaryProvider(ValueObject &valobj, Stream &stream,
+                               const TypeSummaryOptions &options);
+
+bool NSMachPortSummaryProvider(ValueObject &valobj, Stream &stream,
+                               const TypeSummaryOptions &options);
+
+bool NSDateSummaryProvider(ValueObject &valobj, Stream &stream,
+                           const TypeSummaryOptions &options);
+
+bool NSBundleSummaryProvider(ValueObject &valobj, Stream &stream,
+                             const TypeSummaryOptions &options);
+
+bool NSURLSummaryProvider(ValueObject &valobj, Stream &stream,
+                          const TypeSummaryOptions &options);
+
+extern template bool NSDataSummaryProvider<true>(ValueObject &, Stream &,
+                                                 const TypeSummaryOptions &);
+
+extern template bool NSDataSummaryProvider<false>(ValueObject &, Stream &,
+                                                  const TypeSummaryOptions &);
+
+SyntheticChildrenFrontEnd *
+NSArraySyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
+NSIndexPathSyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                    lldb::ValueObjectSP);
+
+bool ObjCClassSummaryProvider(ValueObject &valobj, Stream &stream,
+                              const TypeSummaryOptions &options);
+
+SyntheticChildrenFrontEnd *
+ObjCClassSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
+
+bool ObjCBOOLSummaryProvider(ValueObject &valobj, Stream &stream,
+                             const TypeSummaryOptions &options);
+
+bool ObjCBooleanSummaryProvider(ValueObject &valobj, Stream &stream,
+                                const TypeSummaryOptions &options);
+
+template <bool is_sel_ptr>
+bool ObjCSELSummaryProvider(ValueObject &valobj, Stream &stream,
+                            const TypeSummaryOptions &options);
+
+extern template bool ObjCSELSummaryProvider<true>(ValueObject &, Stream &,
+                                                  const TypeSummaryOptions &);
+
+extern template bool ObjCSELSummaryProvider<false>(ValueObject &, Stream &,
+                                                   const TypeSummaryOptions &);
+
+bool NSError_SummaryProvider(ValueObject &valobj, Stream &stream,
+                             const TypeSummaryOptions &options);
+
+bool NSException_SummaryProvider(ValueObject &valobj, Stream &stream,
+                                 const TypeSummaryOptions &options);
+
+SyntheticChildrenFrontEnd *
+NSErrorSyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                lldb::ValueObjectSP valobj_sp);
+
+SyntheticChildrenFrontEnd *
+NSExceptionSyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                    lldb::ValueObjectSP valobj_sp);
+
+class NSArray_Additionals {
+public:
+  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+  GetAdditionalSummaries();
+
+  static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+  GetAdditionalSynthetics();
+};
+} // namespace formatters
 } // namespace lldb_private
 
 #endif // liblldb_Cocoa_h_
diff --git a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
index 4103067..dacbf78 100644
--- a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -1,4 +1,5 @@
-//===-- CoreMedia.cpp --------------------------------------------*- C++ -*-===//
+//===-- CoreMedia.cpp --------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -18,72 +19,77 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-bool
-lldb_private::formatters::CMTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    CompilerType type = valobj.GetCompilerType();
-    if (!type.IsValid())
-        return false;
+bool lldb_private::formatters::CMTimeSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  CompilerType type = valobj.GetCompilerType();
+  if (!type.IsValid())
+    return false;
 
-    TypeSystem *type_system = valobj.GetExecutionContextRef().GetTargetSP()->GetScratchTypeSystemForLanguage(nullptr, lldb::eLanguageTypeC);
-    if (!type_system)
-        return false;
-    
-    // fetch children by offset to compensate for potential lack of debug info
-    auto int64_ty = type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
-    auto int32_ty = type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
-    
-    auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true));
-    auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true));
-    auto flags_sp(valobj.GetSyntheticChildAtOffset(12, int32_ty, true));
-    
-    if (!value_sp || !timescale_sp || !flags_sp)
-        return false;
-    
-    auto value = value_sp->GetValueAsUnsigned(0);
-    auto timescale = (int32_t)timescale_sp->GetValueAsUnsigned(0); // the timescale specifies the fraction of a second each unit in the numerator occupies
-    auto flags = Flags(flags_sp->GetValueAsUnsigned(0) & 0x00000000000000FF); // the flags I need sit in the LSB
-    
-    const unsigned int FlagPositiveInf = 4;
-    const unsigned int FlagNegativeInf = 8;
-    const unsigned int FlagIndefinite = 16;
-    
-    if (flags.AnySet(FlagIndefinite))
-    {
-        stream.Printf("indefinite");
-        return true;
-    }
-    
-    if (flags.AnySet(FlagPositiveInf))
-    {
-        stream.Printf("+oo");
-        return true;
-    }
-    
-    if (flags.AnySet(FlagNegativeInf))
-    {
-        stream.Printf("-oo");
-        return true;
-    }
-    
-    if (timescale == 0)
-        return false;
-    
-    switch (timescale)
-    {
-        case 0:
-            return false;
-        case 1:
-            stream.Printf("%" PRId64 " seconds", value);
-            return true;
-        case 2:
-            stream.Printf("%" PRId64 " half seconds", value);
-            return true;
-        case 3:
-            stream.Printf("%" PRId64 " third%sof a second", value, value == 1 ? " " : "s ");
-            return true;
-        default:
-            stream.Printf("%" PRId64 " %" PRId32 "th%sof a second", value, timescale, value == 1 ? " " : "s ");
-            return true;
-    }
+  TypeSystem *type_system =
+      valobj.GetExecutionContextRef()
+          .GetTargetSP()
+          ->GetScratchTypeSystemForLanguage(nullptr, lldb::eLanguageTypeC);
+  if (!type_system)
+    return false;
+
+  // fetch children by offset to compensate for potential lack of debug info
+  auto int64_ty =
+      type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
+  auto int32_ty =
+      type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
+
+  auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true));
+  auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true));
+  auto flags_sp(valobj.GetSyntheticChildAtOffset(12, int32_ty, true));
+
+  if (!value_sp || !timescale_sp || !flags_sp)
+    return false;
+
+  auto value = value_sp->GetValueAsUnsigned(0);
+  auto timescale = (int32_t)timescale_sp->GetValueAsUnsigned(
+      0); // the timescale specifies the fraction of a second each unit in the
+          // numerator occupies
+  auto flags = Flags(flags_sp->GetValueAsUnsigned(0) &
+                     0x00000000000000FF); // the flags I need sit in the LSB
+
+  const unsigned int FlagPositiveInf = 4;
+  const unsigned int FlagNegativeInf = 8;
+  const unsigned int FlagIndefinite = 16;
+
+  if (flags.AnySet(FlagIndefinite)) {
+    stream.Printf("indefinite");
+    return true;
+  }
+
+  if (flags.AnySet(FlagPositiveInf)) {
+    stream.Printf("+oo");
+    return true;
+  }
+
+  if (flags.AnySet(FlagNegativeInf)) {
+    stream.Printf("-oo");
+    return true;
+  }
+
+  if (timescale == 0)
+    return false;
+
+  switch (timescale) {
+  case 0:
+    return false;
+  case 1:
+    stream.Printf("%" PRId64 " seconds", value);
+    return true;
+  case 2:
+    stream.Printf("%" PRId64 " half seconds", value);
+    return true;
+  case 3:
+    stream.Printf("%" PRId64 " third%sof a second", value,
+                  value == 1 ? " " : "s ");
+    return true;
+  default:
+    stream.Printf("%" PRId64 " %" PRId32 "th%sof a second", value, timescale,
+                  value == 1 ? " " : "s ");
+    return true;
+  }
 }
diff --git a/lldb/source/Plugins/Language/ObjC/CoreMedia.h b/lldb/source/Plugins/Language/ObjC/CoreMedia.h
index 2ffabaa..20de792 100644
--- a/lldb/source/Plugins/Language/ObjC/CoreMedia.h
+++ b/lldb/source/Plugins/Language/ObjC/CoreMedia.h
@@ -1,4 +1,5 @@
-//===-- CoreMedia.h -----------------------------------------------*- C++ -*-===//
+//===-- CoreMedia.h -----------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -15,12 +16,11 @@
 #include "lldb/DataFormatters/TypeSummary.h"
 
 namespace lldb_private {
-    namespace formatters
-    {
-        
-        bool
-        CMTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-    } // namespace formatters
+namespace formatters {
+
+bool CMTimeSummaryProvider(ValueObject &valobj, Stream &stream,
+                           const TypeSummaryOptions &options);
+} // namespace formatters
 } // namespace lldb_private
 
 #endif // liblldb_CF_h_
diff --git a/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
index 5de97b6..034687b 100644
--- a/lldb/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
@@ -15,6 +15,7 @@
 // Project includes
 #include "Cocoa.h"
 
+#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Stream.h"
@@ -26,801 +27,683 @@
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Target/Language.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
-#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
 #include "lldb/Target/Target.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 NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+namespace lldb_private {
+namespace formatters {
+std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+NSArray_Additionals::GetAdditionalSummaries() {
+  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+  return g_map;
+}
 
-            ~NSArrayMSyntheticFrontEnd() override = default;
+std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+NSArray_Additionals::GetAdditionalSynthetics() {
+  static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
+      g_map;
+  return g_map;
+}
 
-            size_t
-            CalculateNumChildren() override;
-            
-            lldb::ValueObjectSP
-            GetChildAtIndex(size_t idx) override;
-            
-            bool
-            Update() override = 0;
-            
-            bool
-            MightHaveChildren() override;
-            
-            size_t
-            GetIndexOfChildWithName(const 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;
-            CompilerType m_id_type;
-        };
-        
-        class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd
-        {
-        public:
-            NSArrayMSyntheticFrontEnd_109 (lldb::ValueObjectSP valobj_sp);
+class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSArrayMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-            ~NSArrayMSyntheticFrontEnd_109() override;
+  ~NSArrayMSyntheticFrontEnd() override = default;
 
-            bool
-            Update() override;
-            
-        protected:
-            lldb::addr_t
-            GetDataAddress() override;
-            
-            uint64_t
-            GetUsedCount() override;
-            
-            uint64_t
-            GetOffset() override;
-            
-            uint64_t
-            GetSize() override;
-            
-        private:
-            struct DataDescriptor_32
-            {
-                uint32_t _used;
-                uint32_t _priv1 : 2;
-                uint32_t _size : 30;
-                uint32_t _priv2 : 2;
-                uint32_t _offset : 30;
-                uint32_t _priv3;
-                uint32_t _data;
-            };
+  size_t CalculateNumChildren() override;
 
-            struct DataDescriptor_64
-            {
-                uint64_t _used;
-                uint64_t _priv1 : 2;
-                uint64_t _size : 62;
-                uint64_t _priv2 : 2;
-                uint64_t _offset : 62;
-                uint32_t _priv3;
-                uint64_t _data;
-            };
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
 
-            DataDescriptor_32 *m_data_32;
-            DataDescriptor_64 *m_data_64;
-        };
-        
-        class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd
-        {
-        public:
-            NSArrayMSyntheticFrontEnd_1010 (lldb::ValueObjectSP valobj_sp);
+  bool Update() override = 0;
 
-            ~NSArrayMSyntheticFrontEnd_1010() override;
+  bool MightHaveChildren() override;
 
-            bool
-            Update() override;
-            
-        protected:
-            lldb::addr_t
-            GetDataAddress() override;
-            
-            uint64_t
-            GetUsedCount() override;
-            
-            uint64_t
-            GetOffset() override;
-            
-            uint64_t
-            GetSize() override;
-            
-        private:
-            struct DataDescriptor_32
-            {
-                uint32_t _used;
-                uint32_t _offset;
-                uint32_t _size : 28;
-                uint64_t _priv1 : 4;
-                uint32_t _priv2;
-                uint32_t _data;
-            };
+  size_t GetIndexOfChildWithName(const ConstString &name) override;
 
-            struct DataDescriptor_64
-            {
-                uint64_t _used;
-                uint64_t _offset;
-                uint64_t _size : 60;
-                uint64_t _priv1 : 4;
-                uint32_t _priv2;
-                uint64_t _data;
-            };
+protected:
+  virtual lldb::addr_t GetDataAddress() = 0;
 
-            DataDescriptor_32 *m_data_32;
-            DataDescriptor_64 *m_data_64;
-        };
-        
-        class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+  virtual uint64_t GetUsedCount() = 0;
 
-            ~NSArrayISyntheticFrontEnd() override = default;
+  virtual uint64_t GetOffset() = 0;
 
-            size_t
-            CalculateNumChildren() override;
-            
-            lldb::ValueObjectSP
-            GetChildAtIndex(size_t idx) override;
-            
-            bool
-            Update() override;
-            
-            bool
-            MightHaveChildren() override;
-            
-            size_t
-            GetIndexOfChildWithName(const ConstString &name) override;
+  virtual uint64_t GetSize() = 0;
 
-        private:
-            ExecutionContextRef m_exe_ctx_ref;
-            uint8_t m_ptr_size;
-            uint64_t m_items;
-            lldb::addr_t m_data_ptr;
-            CompilerType m_id_type;
-        };
-        
-        class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSArray0SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+  ExecutionContextRef m_exe_ctx_ref;
+  uint8_t m_ptr_size;
+  CompilerType m_id_type;
+};
 
-            ~NSArray0SyntheticFrontEnd() override = default;
+class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd {
+public:
+  NSArrayMSyntheticFrontEnd_109(lldb::ValueObjectSP valobj_sp);
 
-            size_t
-            CalculateNumChildren() override;
-            
-            lldb::ValueObjectSP
-            GetChildAtIndex(size_t idx) override;
-            
-            bool
-            Update() override;
-            
-            bool
-            MightHaveChildren() override;
-            
-            size_t
-            GetIndexOfChildWithName(const ConstString &name) override;
-        };
+  ~NSArrayMSyntheticFrontEnd_109() override;
 
-        class NSArray1SyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSArray1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-            
-            ~NSArray1SyntheticFrontEnd() override = default;
-            
-            size_t
-            CalculateNumChildren() override;
-            
-            lldb::ValueObjectSP
-            GetChildAtIndex(size_t idx) override;
-            
-            bool
-            Update() override;
-            
-            bool
-            MightHaveChildren() override;
-            
-            size_t
-            GetIndexOfChildWithName(const ConstString &name) override;
-        };
-    } // namespace formatters
+  bool Update() override;
+
+protected:
+  lldb::addr_t GetDataAddress() override;
+
+  uint64_t GetUsedCount() override;
+
+  uint64_t GetOffset() override;
+
+  uint64_t GetSize() override;
+
+private:
+  struct DataDescriptor_32 {
+    uint32_t _used;
+    uint32_t _priv1 : 2;
+    uint32_t _size : 30;
+    uint32_t _priv2 : 2;
+    uint32_t _offset : 30;
+    uint32_t _priv3;
+    uint32_t _data;
+  };
+
+  struct DataDescriptor_64 {
+    uint64_t _used;
+    uint64_t _priv1 : 2;
+    uint64_t _size : 62;
+    uint64_t _priv2 : 2;
+    uint64_t _offset : 62;
+    uint32_t _priv3;
+    uint64_t _data;
+  };
+
+  DataDescriptor_32 *m_data_32;
+  DataDescriptor_64 *m_data_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:
+  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;
+  };
+
+  DataDescriptor_32 *m_data_32;
+  DataDescriptor_64 *m_data_64;
+};
+
+class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  ~NSArrayISyntheticFrontEnd() override = default;
+
+  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;
+  uint64_t m_items;
+  lldb::addr_t m_data_ptr;
+  CompilerType m_id_type;
+};
+
+class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  ~NSArray0SyntheticFrontEnd() override = default;
+
+  size_t CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+  bool Update() override;
+
+  bool MightHaveChildren() override;
+
+  size_t GetIndexOfChildWithName(const ConstString &name) override;
+};
+
+class NSArray1SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSArray1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  ~NSArray1SyntheticFrontEnd() override = default;
+
+  size_t CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+  bool Update() override;
+
+  bool MightHaveChildren() override;
+
+  size_t GetIndexOfChildWithName(const ConstString &name) override;
+};
+} // namespace formatters
 } // namespace lldb_private
 
-bool
-lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    static ConstString g_TypeHint("NSArray");
-    
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    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_NSArray0("__NSArray0");
-    static const ConstString g_NSArray1("__NSSingleObjectArrayI");
-    static const ConstString g_NSArrayCF("__NSCFArray");
-    
-    if (class_name.IsEmpty())
-        return false;
-    
-    if (class_name == g_NSArrayI)
-    {
-        Error error;
-        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
-        if (error.Fail())
-            return false;
-    }
-    else if (class_name == g_NSArrayM)
-    {
-        Error 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)
-    {
-        Error error;
-        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
-        if (error.Fail())
-            return false;
-    }
+bool lldb_private::formatters::NSArraySummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  static ConstString g_TypeHint("NSArray");
+
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  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_NSArray0("__NSArray0");
+  static const ConstString g_NSArray1("__NSSingleObjectArrayI");
+  static const ConstString g_NSArrayCF("__NSCFArray");
+
+  if (class_name.IsEmpty())
+    return false;
+
+  if (class_name == g_NSArrayI) {
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                      ptr_size, 0, error);
+    if (error.Fail())
+      return false;
+  } else if (class_name == g_NSArrayM) {
+    Error 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) {
+    Error 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
-    {
-        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;
+      return false;
+  }
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
     }
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(options.GetLanguage()))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%" PRIu64 " %s%s%s",
-                  prefix.c_str(),
-                  value,
-                  "element",
-                  value == 1 ? "" : "s",
-                  suffix.c_str());
-    return true;
+  }
+
+  stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element",
+                value == 1 ? "" : "s", suffix.c_str());
+  return true;
 }
 
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_id_type()
-{
-    if (valobj_sp)
-    {
-        clang::ASTContext *ast = valobj_sp->GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext()->getASTContext();
-        if (ast)
-            m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy);
-        if (valobj_sp->GetProcessSP())
-            m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
-    }
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd(
+    lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+      m_id_type() {
+  if (valobj_sp) {
+    clang::ASTContext *ast = valobj_sp->GetExecutionContextRef()
+                                 .GetTargetSP()
+                                 ->GetScratchClangASTContext()
+                                 ->getASTContext();
+    if (ast)
+      m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy);
+    if (valobj_sp->GetProcessSP())
+      m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
+  }
 }
 
-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_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_1010::
+    NSArrayMSyntheticFrontEnd_1010(lldb::ValueObjectSP valobj_sp)
+    : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
+      m_data_64(nullptr) {}
 
 size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
-{
-    return GetUsedCount();
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren() {
+  return GetUsedCount();
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
-    if (idx >= CalculateNumChildren())
-        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.GetData(),
-                                        object_at_idx,
-                                        m_exe_ctx_ref,
-                                        m_id_type);
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex(
+    size_t idx) {
+  if (idx >= CalculateNumChildren())
+    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.GetData(), object_at_idx,
+                                      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();
-    Error 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;
+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;
-}
-
-bool
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::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();
-    Error 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;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  Error error;
+  error.Clear();
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
     return false;
-}
-
-bool
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
-{
-    return true;
-}
-
-size_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::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;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::~NSArrayMSyntheticFrontEnd_109()
-{
-    delete m_data_32;
-    m_data_32 = nullptr;
-    delete m_data_64;
-    m_data_64 = nullptr;
-}
-
-lldb::addr_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress ()
-{
-    if (!m_data_32 && !m_data_64)
-        return LLDB_INVALID_ADDRESS;
-    return m_data_32 ? m_data_32->_data :
-    m_data_64->_data;
-}
-
-uint64_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::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;
-}
-
-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 ()
-{
-    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::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (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::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::CalculateNumChildren ()
-{
-    return m_items;
-}
-
-bool
-lldb_private::formatters::NSArrayISyntheticFrontEnd::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();
-    Error 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;
+  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::NSArrayISyntheticFrontEnd::MightHaveChildren ()
-{
-    return true;
+bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::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();
+  Error 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;
 }
 
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd::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();
-    Error error;
-    if (error.Fail())
-        return lldb::ValueObjectSP();
-    StreamString idx_name;
-    idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-    return CreateValueObjectFromAddress(idx_name.GetData(),
-                                        object_at_idx,
-                                        m_exe_ctx_ref,
-                                        m_id_type);
-}
-
-lldb_private::formatters::NSArray0SyntheticFrontEnd::NSArray0SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-    SyntheticChildrenFrontEnd(*valobj_sp)
-{
+bool lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren() {
+  return true;
 }
 
 size_t
-lldb_private::formatters::NSArray0SyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::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::NSArray0SyntheticFrontEnd::CalculateNumChildren ()
-{
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::
+    ~NSArrayMSyntheticFrontEnd_109() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+}
+
+lldb::addr_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress() {
+  if (!m_data_32 && !m_data_64)
+    return LLDB_INVALID_ADDRESS;
+  return m_data_32 ? m_data_32->_data : m_data_64->_data;
+}
+
+uint64_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetUsedCount() {
+  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::NSArray0SyntheticFrontEnd::Update()
-{
-    return false;
+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;
 }
 
-bool
-lldb_private::formatters::NSArray0SyntheticFrontEnd::MightHaveChildren ()
-{
-    return false;
+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::ValueObjectSP
-lldb_private::formatters::NSArray0SyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
-    return lldb::ValueObjectSP();
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::
+    ~NSArrayMSyntheticFrontEnd_1010() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
 }
 
-lldb_private::formatters::NSArray1SyntheticFrontEnd::NSArray1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd (*valobj_sp.get())
-{
+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;
+}
+
+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() {
+  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::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd(
+    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::NSArray1SyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
-    static const ConstString g_zero("[0]");
-    
-    if (name == g_zero)
-        return 0;
-    
+lldb_private::formatters::NSArrayISyntheticFrontEnd::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::NSArray1SyntheticFrontEnd::CalculateNumChildren ()
-{
-    return 1;
+lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren() {
+  return m_items;
 }
 
-bool
-lldb_private::formatters::NSArray1SyntheticFrontEnd::Update()
-{
+bool lldb_private::formatters::NSArrayISyntheticFrontEnd::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();
+  Error 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::NSArray1SyntheticFrontEnd::MightHaveChildren ()
-{
-    return true;
+bool lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren() {
+  return true;
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
-    static const ConstString g_zero("[0]");
-    
-    if (idx == 0)
-    {
-        CompilerType id_type(m_backend.GetTargetSP()->GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
-        return m_backend.GetSyntheticChildAtOffset(m_backend.GetProcessSP()->GetAddressByteSize(), id_type, true, g_zero);
-    }
+lldb_private::formatters::NSArrayISyntheticFrontEnd::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();
+  Error error;
+  if (error.Fail())
+    return lldb::ValueObjectSP();
+  StreamString idx_name;
+  idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+  return CreateValueObjectFromAddress(idx_name.GetData(), object_at_idx,
+                                      m_exe_ctx_ref, m_id_type);
 }
 
-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>(process_sp->GetObjCLanguageRuntime());
-    if (!runtime)
-        return nullptr;
-    
-    CompilerType valobj_type(valobj_sp->GetCompilerType());
-    Flags flags(valobj_type.GetTypeInfo());
-    
-    if (flags.IsClear(eTypeIsPointer))
-    {
-        Error 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_NSArrayM("__NSArrayM");
-    static const ConstString g_NSArray0("__NSArray0");
-    static const ConstString g_NSArray1("__NSSingleObjectArrayI");
-    
-    if (class_name.IsEmpty())
-        return nullptr;
-    
-    if (class_name == g_NSArrayI)
-    {
-        return (new NSArrayISyntheticFrontEnd(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() >= 1100)
-            return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
-        else
-            return (new NSArrayMSyntheticFrontEnd_109(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);
-    }
-    
+lldb_private::formatters::NSArray0SyntheticFrontEnd::NSArray0SyntheticFrontEnd(
+    lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp) {}
+
+size_t
+lldb_private::formatters::NSArray0SyntheticFrontEnd::GetIndexOfChildWithName(
+    const ConstString &name) {
+  return UINT32_MAX;
+}
+
+size_t
+lldb_private::formatters::NSArray0SyntheticFrontEnd::CalculateNumChildren() {
+  return 0;
+}
+
+bool lldb_private::formatters::NSArray0SyntheticFrontEnd::Update() {
+  return false;
+}
+
+bool lldb_private::formatters::NSArray0SyntheticFrontEnd::MightHaveChildren() {
+  return false;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArray0SyntheticFrontEnd::GetChildAtIndex(
+    size_t idx) {
+  return lldb::ValueObjectSP();
+}
+
+lldb_private::formatters::NSArray1SyntheticFrontEnd::NSArray1SyntheticFrontEnd(
+    lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp.get()) {}
+
+size_t
+lldb_private::formatters::NSArray1SyntheticFrontEnd::GetIndexOfChildWithName(
+    const ConstString &name) {
+  static const ConstString g_zero("[0]");
+
+  if (name == g_zero)
+    return 0;
+
+  return UINT32_MAX;
+}
+
+size_t
+lldb_private::formatters::NSArray1SyntheticFrontEnd::CalculateNumChildren() {
+  return 1;
+}
+
+bool lldb_private::formatters::NSArray1SyntheticFrontEnd::Update() {
+  return false;
+}
+
+bool lldb_private::formatters::NSArray1SyntheticFrontEnd::MightHaveChildren() {
+  return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex(
+    size_t idx) {
+  static const ConstString g_zero("[0]");
+
+  if (idx == 0) {
+    CompilerType id_type(
+        m_backend.GetTargetSP()->GetScratchClangASTContext()->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>(
+      process_sp->GetObjCLanguageRuntime());
+  if (!runtime)
+    return nullptr;
+
+  CompilerType valobj_type(valobj_sp->GetCompilerType());
+  Flags flags(valobj_type.GetTypeInfo());
+
+  if (flags.IsClear(eTypeIsPointer)) {
+    Error 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_NSArrayM("__NSArrayM");
+  static const ConstString g_NSArray0("__NSArray0");
+  static const ConstString g_NSArray1("__NSSingleObjectArrayI");
+
+  if (class_name.IsEmpty())
+    return nullptr;
+
+  if (class_name == g_NSArrayI) {
+    return (new NSArrayISyntheticFrontEnd(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() >= 1100)
+      return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
+    else
+      return (new NSArrayMSyntheticFrontEnd_109(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;
 }
diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
index cdebd6b..e1fa673 100644
--- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -34,768 +34,689 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-NSDictionary_Additionals::GetAdditionalSummaries ()
-{
-    static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
-    return g_map;
+std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+NSDictionary_Additionals::GetAdditionalSummaries() {
+  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+  return g_map;
 }
 
-std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
-NSDictionary_Additionals::GetAdditionalSynthetics ()
-{
-    static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
-    return g_map;
+std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+NSDictionary_Additionals::GetAdditionalSynthetics() {
+  static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
+      g_map;
+  return g_map;
 }
 
-static CompilerType
-GetLLDBNSPairType (TargetSP target_sp)
-{
-    CompilerType compiler_type;
-    
-    ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext();
-    
-    if (target_ast_context)
-    {
-        ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair");
-        
-        compiler_type = target_ast_context->GetTypeForIdentifier<clang::CXXRecordDecl>(g___lldb_autogen_nspair);
-        
-        if (!compiler_type)
-        {
-            compiler_type = target_ast_context->CreateRecordType(nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
-            
-            if (compiler_type)
-            {
-                ClangASTContext::StartTagDeclarationDefinition(compiler_type);
-                CompilerType id_compiler_type = target_ast_context->GetBasicType (eBasicTypeObjCID);
-                ClangASTContext::AddFieldToRecordType(compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0);
-                ClangASTContext::AddFieldToRecordType(compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0);
-                ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
-            }
-        }
+static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
+  CompilerType compiler_type;
+
+  ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext();
+
+  if (target_ast_context) {
+    ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair");
+
+    compiler_type =
+        target_ast_context->GetTypeForIdentifier<clang::CXXRecordDecl>(
+            g___lldb_autogen_nspair);
+
+    if (!compiler_type) {
+      compiler_type = target_ast_context->CreateRecordType(
+          nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(),
+          clang::TTK_Struct, lldb::eLanguageTypeC);
+
+      if (compiler_type) {
+        ClangASTContext::StartTagDeclarationDefinition(compiler_type);
+        CompilerType id_compiler_type =
+            target_ast_context->GetBasicType(eBasicTypeObjCID);
+        ClangASTContext::AddFieldToRecordType(
+            compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0);
+        ClangASTContext::AddFieldToRecordType(
+            compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0);
+        ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+      }
     }
-    return compiler_type;
+  }
+  return compiler_type;
 }
 
 namespace lldb_private {
-    namespace  formatters {
-        class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+namespace formatters {
+class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSDictionaryISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-            ~NSDictionaryISyntheticFrontEnd() override;
+  ~NSDictionaryISyntheticFrontEnd() 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;
+  size_t CalculateNumChildren() override;
 
-        private:
-            struct DataDescriptor_32
-            {
-                uint32_t _used : 26;
-                uint32_t _szidx : 6;
-            };
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
 
-            struct DataDescriptor_64
-            {
-                uint64_t _used : 58;
-                uint32_t _szidx : 6;
-            };
+  bool Update() override;
 
-            struct DictionaryItemDescriptor
-            {
-                lldb::addr_t key_ptr;
-                lldb::addr_t val_ptr;
-                lldb::ValueObjectSP valobj_sp;
-            };
+  bool MightHaveChildren() override;
 
-            ExecutionContextRef m_exe_ctx_ref;
-            uint8_t m_ptr_size;
-            lldb::ByteOrder m_order;
-            DataDescriptor_32 *m_data_32;
-            DataDescriptor_64 *m_data_64;
-            lldb::addr_t m_data_ptr;
-            CompilerType m_pair_type;
-            std::vector<DictionaryItemDescriptor> m_children;
-        };
+  size_t GetIndexOfChildWithName(const ConstString &name) override;
 
-        class NSDictionary1SyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSDictionary1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-            
-            ~NSDictionary1SyntheticFrontEnd() override = default;
-            
-            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:
-            ValueObjectSP m_pair;
-        };
-        
-        class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+private:
+  struct DataDescriptor_32 {
+    uint32_t _used : 26;
+    uint32_t _szidx : 6;
+  };
 
-            ~NSDictionaryMSyntheticFrontEnd() override;
+  struct DataDescriptor_64 {
+    uint64_t _used : 58;
+    uint32_t _szidx : 6;
+  };
 
-            size_t
-            CalculateNumChildren() override;
-            
-            lldb::ValueObjectSP
-            GetChildAtIndex(size_t idx) override;
-            
-            bool
-            Update() override;
-            
-            bool
-            MightHaveChildren() override;
-            
-            size_t
-            GetIndexOfChildWithName(const ConstString &name) override;
+  struct DictionaryItemDescriptor {
+    lldb::addr_t key_ptr;
+    lldb::addr_t val_ptr;
+    lldb::ValueObjectSP valobj_sp;
+  };
 
-        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;
-            };
+  ExecutionContextRef m_exe_ctx_ref;
+  uint8_t m_ptr_size;
+  lldb::ByteOrder m_order;
+  DataDescriptor_32 *m_data_32;
+  DataDescriptor_64 *m_data_64;
+  lldb::addr_t m_data_ptr;
+  CompilerType m_pair_type;
+  std::vector<DictionaryItemDescriptor> m_children;
+};
 
-            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;
-            };
+class NSDictionary1SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-            struct DictionaryItemDescriptor
-            {
-                lldb::addr_t key_ptr;
-                lldb::addr_t val_ptr;
-                lldb::ValueObjectSP valobj_sp;
-            };
+  ~NSDictionary1SyntheticFrontEnd() override = default;
 
-            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
+  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:
+  ValueObjectSP m_pair;
+};
+
+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 formatters
 } // namespace lldb_private
 
-template<bool name_entries>
-bool
-lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    static ConstString g_TypeHint("NSDictionary");
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    bool is_64bit = (ptr_size == 8);
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint64_t value = 0;
-    
-    ConstString class_name(descriptor->GetClassName());
+template <bool name_entries>
+bool lldb_private::formatters::NSDictionarySummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  static ConstString g_TypeHint("NSDictionary");
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
+    return false;
 
-    static const ConstString g_DictionaryI("__NSDictionaryI");
-    static const ConstString g_DictionaryM("__NSDictionaryM");
-    static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
-    
-    if (class_name.IsEmpty())
-        return false;
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
 
-    if (class_name == g_DictionaryI)
-    {
-        Error error;
-        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
-        if (error.Fail())
-            return false;
-        value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
-    }
-    else if (class_name == g_DictionaryM)
-    {
-        Error error;
-        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
-        if (error.Fail())
-            return false;
-        value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
-    }
-    else if (class_name == g_Dictionary1)
-    {
-        value = 1;
-    }
-    /*else if (!strcmp(class_name,"__NSCFDictionary"))
-     {
-     Error error;
-     value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
-     if (error.Fail())
-     return false;
-     if (is_64bit)
-     value &= ~0x0f1f000000000000UL;
-     }*/
+  if (!runtime)
+    return false;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(valobj));
+
+  if (!descriptor || !descriptor->IsValid())
+    return false;
+
+  uint32_t ptr_size = process_sp->GetAddressByteSize();
+  bool is_64bit = (ptr_size == 8);
+
+  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_DictionaryI("__NSDictionaryI");
+  static const ConstString g_DictionaryM("__NSDictionaryM");
+  static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
+
+  if (class_name.IsEmpty())
+    return false;
+
+  if (class_name == g_DictionaryI) {
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                      ptr_size, 0, error);
+    if (error.Fail())
+      return false;
+    value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+  } else if (class_name == g_DictionaryM) {
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                      ptr_size, 0, error);
+    if (error.Fail())
+      return false;
+    value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+  } else if (class_name == g_Dictionary1) {
+    value = 1;
+  }
+  /*else if (!strcmp(class_name,"__NSCFDictionary"))
+   {
+   Error error;
+   value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ?
+   20 : 12), 4, 0, error);
+   if (error.Fail())
+   return false;
+   if (is_64bit)
+   value &= ~0x0f1f000000000000UL;
+   }*/
+  else {
+    auto &map(NSDictionary_Additionals::GetAdditionalSummaries());
+    auto iter = map.find(class_name), end = map.end();
+    if (iter != end)
+      return iter->second(valobj, stream, options);
     else
-    {
-        auto& map(NSDictionary_Additionals::GetAdditionalSummaries());
-        auto iter = map.find(class_name), end = map.end();
-        if (iter != end)
-            return iter->second(valobj, stream, options);
-        else
-            return false;
+      return false;
+  }
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
     }
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(options.GetLanguage()))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%" PRIu64 " %s%s%s",
-                  prefix.c_str(),
-                  value,
-                  "key/value pair",
-                  value == 1 ? "" : "s",
-                  suffix.c_str());
-    return true;
+  }
+
+  stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "key/value pair",
+                value == 1 ? "" : "s", suffix.c_str());
+  return true;
 }
 
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
-{
-    lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
-    if (!process_sp)
-        return nullptr;
-    ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    if (!runtime)
-        return nullptr;
-    
-    CompilerType valobj_type(valobj_sp->GetCompilerType());
-    Flags flags(valobj_type.GetTypeInfo());
-    
-    if (flags.IsClear(eTypeIsPointer))
-    {
-        Error 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_DictionaryI("__NSDictionaryI");
-    static const ConstString g_DictionaryM("__NSDictionaryM");
-    static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
-    
-    if (class_name.IsEmpty())
-        return nullptr;
-    
-    if (class_name == g_DictionaryI)
-    {
-        return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
-    }
-    else if (class_name == g_DictionaryM)
-    {
-        return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
-    }
-    else if (class_name == g_Dictionary1)
-    {
-        return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
-    }
-    else
-    {
-        auto& map(NSDictionary_Additionals::GetAdditionalSynthetics());
-        auto iter = map.find(class_name), end = map.end();
-        if (iter != end)
-            return iter->second(synth, valobj_sp);
-    }
-    
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
+    CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) {
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
     return nullptr;
-}
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+  if (!runtime)
+    return nullptr;
 
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (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()
-{
-}
+  CompilerType valobj_type(valobj_sp->GetCompilerType());
+  Flags flags(valobj_type.GetTypeInfo());
 
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
-{
-    delete m_data_32;
-    m_data_32 = nullptr;
-    delete m_data_64;
-    m_data_64 = nullptr;
-}
-
-size_t
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::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::NSDictionaryISyntheticFrontEnd::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::NSDictionaryISyntheticFrontEnd::Update()
-{
-    m_children.clear();
-    delete m_data_32;
-    m_data_32 = nullptr;
-    delete m_data_64;
-    m_data_64 = nullptr;
-    m_ptr_size = 0;
-    ValueObjectSP valobj_sp = m_backend.GetSP();
-    if (!valobj_sp)
-        return false;
-    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  if (flags.IsClear(eTypeIsPointer)) {
     Error error;
-    error.Clear();
-    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
-    if (!process_sp)
-        return false;
-    m_ptr_size = process_sp->GetAddressByteSize();
-    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), 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;
-    m_data_ptr = data_location + m_ptr_size;
-    return false;
+    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_DictionaryI("__NSDictionaryI");
+  static const ConstString g_DictionaryM("__NSDictionaryM");
+  static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
+
+  if (class_name.IsEmpty())
+    return nullptr;
+
+  if (class_name == g_DictionaryI) {
+    return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
+  } else if (class_name == g_DictionaryM) {
+    return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+  } else if (class_name == g_Dictionary1) {
+    return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
+  } else {
+    auto &map(NSDictionary_Additionals::GetAdditionalSynthetics());
+    auto iter = map.find(class_name), end = map.end();
+    if (iter != end)
+      return iter->second(synth, valobj_sp);
+  }
+
+  return nullptr;
 }
 
-bool
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
-{
-    return true;
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+    NSDictionaryISyntheticFrontEnd(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::NSDictionaryISyntheticFrontEnd::
+    ~NSDictionaryISyntheticFrontEnd() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
 }
 
-lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
-    uint32_t num_children = CalculateNumChildren();
-    
-    if (idx >= num_children)
-        return lldb::ValueObjectSP();
-    
-    if (m_children.empty())
-    {
-        // do the scan phase
-        lldb::addr_t key_at_idx = 0, val_at_idx = 0;
-        
-        uint32_t tries = 0;
-        uint32_t test_idx = 0;
-        
-        while(tries < num_children)
-        {
-            key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
-            val_at_idx = key_at_idx + m_ptr_size;
-            ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
-            if (!process_sp)
-                return lldb::ValueObjectSP();
-            Error error;
-            key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
-            if (error.Fail())
-                return lldb::ValueObjectSP();
-            val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
-            if (error.Fail())
-                return lldb::ValueObjectSP();
-            
-            test_idx++;
-            
-            if (!key_at_idx || !val_at_idx)
-                continue;
-            tries++;
-            
-            DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
-            
-            m_children.push_back(descriptor);
-        }
-    }
-    
-    if (idx >= m_children.size()) // should never happen
-        return lldb::ValueObjectSP();
-    
-    DictionaryItemDescriptor &dict_item = m_children[idx];
-    if (!dict_item.valobj_sp)
-    {
-        if (!m_pair_type.IsValid())
-        {
-            TargetSP target_sp(m_backend.GetTargetSP());
-            if (!target_sp)
-                return ValueObjectSP();
-            m_pair_type = GetLLDBNSPairType(target_sp);
-        }
-        if (!m_pair_type.IsValid())
-            return ValueObjectSP();
-        
-        DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
-        
-        if (m_ptr_size == 8)
-        {
-            uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
-            *data_ptr = dict_item.key_ptr;
-            *(data_ptr+1) = dict_item.val_ptr;
-        }
-        else
-        {
-            uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
-            *data_ptr = dict_item.key_ptr;
-            *(data_ptr+1) = dict_item.val_ptr;
-        }
-        
-        StreamString idx_name;
-        idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-        DataExtractor data(buffer_sp, m_order, m_ptr_size);
-        dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetData(),
-                                                        data,
-                                                        m_exe_ctx_ref,
-                                                        m_pair_type);
-    }
-    return dict_item.valobj_sp;
-}
-
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::NSDictionary1SyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_pair(nullptr)
-{
-}
-
-size_t
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
-    static const ConstString g_zero("[0]");
-    
-    if (name == g_zero)
-        return 0;
-    
+size_t lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+    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::NSDictionary1SyntheticFrontEnd::CalculateNumChildren ()
-{
-    return 1;
+size_t lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+    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::NSDictionary1SyntheticFrontEnd::Update()
-{
-    m_pair.reset();
+bool lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update() {
+  m_children.clear();
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+  m_ptr_size = 0;
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  if (!valobj_sp)
     return false;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  Error error;
+  error.Clear();
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
+    return false;
+  m_ptr_size = process_sp->GetAddressByteSize();
+  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),
+                           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;
+  m_data_ptr = data_location + m_ptr_size;
+  return false;
 }
 
-bool
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::MightHaveChildren ()
-{
-    return true;
+bool lldb_private::formatters::NSDictionaryISyntheticFrontEnd::
+    MightHaveChildren() {
+  return true;
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
-    if (idx != 0)
-        return lldb::ValueObjectSP();
-    
-    if (m_pair.get())
-        return m_pair;
-    
-    auto process_sp(m_backend.GetProcessSP());
-    if (!process_sp)
-        return nullptr;
-    
-    auto ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t key_ptr = m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS) + ptr_size;
-    lldb::addr_t value_ptr = key_ptr + ptr_size;
-    
-    Error error;
-    
-    lldb::addr_t value_at_idx = process_sp->ReadPointerFromMemory(key_ptr, error);
-    if (error.Fail())
-        return nullptr;
-    lldb::addr_t key_at_idx = process_sp->ReadPointerFromMemory(value_ptr, error);
-    if (error.Fail())
-        return nullptr;
-    
-    auto pair_type = GetLLDBNSPairType(process_sp->GetTarget().shared_from_this());
-    
-    DataBufferSP buffer_sp(new DataBufferHeap(2*ptr_size,0));
-    
-    if (ptr_size == 8)
-    {
-        uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
-        *data_ptr = key_at_idx;
-        *(data_ptr+1) = value_at_idx;
-    }
-    else
-    {
-        uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
-        *data_ptr = key_ptr;
-        *(data_ptr+1) = value_ptr;
-    }
-    
-    DataExtractor data(buffer_sp, process_sp->GetByteOrder(), ptr_size);
-    m_pair = CreateValueObjectFromData("[0]",
-                                       data,
-                                       m_backend.GetExecutionContextRef(),
-                                       pair_type);
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex(
+    size_t idx) {
+  uint32_t num_children = CalculateNumChildren();
 
-    
+  if (idx >= num_children)
+    return lldb::ValueObjectSP();
+
+  if (m_children.empty()) {
+    // do the scan phase
+    lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+
+    uint32_t tries = 0;
+    uint32_t test_idx = 0;
+
+    while (tries < num_children) {
+      key_at_idx = m_data_ptr + (2 * test_idx * m_ptr_size);
+      val_at_idx = key_at_idx + m_ptr_size;
+      ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+      if (!process_sp)
+        return lldb::ValueObjectSP();
+      Error error;
+      key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+      if (error.Fail())
+        return lldb::ValueObjectSP();
+      val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+      if (error.Fail())
+        return lldb::ValueObjectSP();
+
+      test_idx++;
+
+      if (!key_at_idx || !val_at_idx)
+        continue;
+      tries++;
+
+      DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx,
+                                             lldb::ValueObjectSP()};
+
+      m_children.push_back(descriptor);
+    }
+  }
+
+  if (idx >= m_children.size()) // should never happen
+    return lldb::ValueObjectSP();
+
+  DictionaryItemDescriptor &dict_item = m_children[idx];
+  if (!dict_item.valobj_sp) {
+    if (!m_pair_type.IsValid()) {
+      TargetSP target_sp(m_backend.GetTargetSP());
+      if (!target_sp)
+        return ValueObjectSP();
+      m_pair_type = GetLLDBNSPairType(target_sp);
+    }
+    if (!m_pair_type.IsValid())
+      return ValueObjectSP();
+
+    DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0));
+
+    if (m_ptr_size == 8) {
+      uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
+      *data_ptr = dict_item.key_ptr;
+      *(data_ptr + 1) = dict_item.val_ptr;
+    } else {
+      uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
+      *data_ptr = dict_item.key_ptr;
+      *(data_ptr + 1) = dict_item.val_ptr;
+    }
+
+    StreamString idx_name;
+    idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+    DataExtractor data(buffer_sp, m_order, m_ptr_size);
+    dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetData(), data,
+                                                    m_exe_ctx_ref, m_pair_type);
+  }
+  return dict_item.valobj_sp;
+}
+
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
+    NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_pair(nullptr) {}
+
+size_t lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
+    GetIndexOfChildWithName(const ConstString &name) {
+  static const ConstString g_zero("[0]");
+
+  if (name == g_zero)
+    return 0;
+
+  return UINT32_MAX;
+}
+
+size_t lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
+    CalculateNumChildren() {
+  return 1;
+}
+
+bool lldb_private::formatters::NSDictionary1SyntheticFrontEnd::Update() {
+  m_pair.reset();
+  return false;
+}
+
+bool lldb_private::formatters::NSDictionary1SyntheticFrontEnd::
+    MightHaveChildren() {
+  return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionary1SyntheticFrontEnd::GetChildAtIndex(
+    size_t idx) {
+  if (idx != 0)
+    return lldb::ValueObjectSP();
+
+  if (m_pair.get())
     return m_pair;
+
+  auto process_sp(m_backend.GetProcessSP());
+  if (!process_sp)
+    return nullptr;
+
+  auto ptr_size = process_sp->GetAddressByteSize();
+
+  lldb::addr_t key_ptr =
+      m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS) + ptr_size;
+  lldb::addr_t value_ptr = key_ptr + ptr_size;
+
+  Error error;
+
+  lldb::addr_t value_at_idx = process_sp->ReadPointerFromMemory(key_ptr, error);
+  if (error.Fail())
+    return nullptr;
+  lldb::addr_t key_at_idx = process_sp->ReadPointerFromMemory(value_ptr, error);
+  if (error.Fail())
+    return nullptr;
+
+  auto pair_type =
+      GetLLDBNSPairType(process_sp->GetTarget().shared_from_this());
+
+  DataBufferSP buffer_sp(new DataBufferHeap(2 * ptr_size, 0));
+
+  if (ptr_size == 8) {
+    uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
+    *data_ptr = key_at_idx;
+    *(data_ptr + 1) = value_at_idx;
+  } else {
+    uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
+    *data_ptr = key_ptr;
+    *(data_ptr + 1) = value_ptr;
+  }
+
+  DataExtractor data(buffer_sp, process_sp->GetByteOrder(), ptr_size);
+  m_pair = CreateValueObjectFromData(
+      "[0]", data, m_backend.GetExecutionContextRef(), pair_type);
+
+  return m_pair;
 }
 
-lldb_private::formatters::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::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::NSDictionaryMSyntheticFrontEnd::
+    ~NSDictionaryMSyntheticFrontEnd() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
 }
 
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
-{
-    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) {
+  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::NSDictionaryMSyntheticFrontEnd::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::NSDictionaryMSyntheticFrontEnd::
+    CalculateNumChildren() {
+  if (!m_data_32 && !m_data_64)
+    return 0;
+  return (m_data_32 ? m_data_32->_used : m_data_64->_used);
 }
 
-size_t
-lldb_private::formatters::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::NSDictionaryMSyntheticFrontEnd::Update()
-{
-    m_children.clear();
-    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();
-    Error error;
-    error.Clear();
-    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
-    if (!process_sp)
-        return false;
-    m_ptr_size = process_sp->GetAddressByteSize();
-    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), 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;
+bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
+  m_children.clear();
+  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();
+  Error error;
+  error.Clear();
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
+    return false;
+  m_ptr_size = process_sp->GetAddressByteSize();
+  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),
+                           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::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
-{
-    return true;
+bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::
+    MightHaveChildren() {
+  return true;
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::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 = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
-    
-    uint32_t num_children = CalculateNumChildren();
-    
-    if (idx >= num_children)
+lldb_private::formatters::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 =
+      (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
+
+  uint32_t num_children = CalculateNumChildren();
+
+  if (idx >= num_children)
+    return lldb::ValueObjectSP();
+
+  if (m_children.empty()) {
+    // do the scan phase
+    lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+
+    uint32_t tries = 0;
+    uint32_t test_idx = 0;
+
+    while (tries < num_children) {
+      key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
+      val_at_idx = m_values_ptr + (test_idx * m_ptr_size);
+      ;
+      ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+      if (!process_sp)
         return lldb::ValueObjectSP();
-    
-    if (m_children.empty())
-    {
-        // do the scan phase
-        lldb::addr_t key_at_idx = 0, val_at_idx = 0;
-        
-        uint32_t tries = 0;
-        uint32_t test_idx = 0;
-        
-        while(tries < num_children)
-        {
-            key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
-            val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
-            ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
-            if (!process_sp)
-                return lldb::ValueObjectSP();
-            Error error;
-            key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
-            if (error.Fail())
-                return lldb::ValueObjectSP();
-            val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
-            if (error.Fail())
-                return lldb::ValueObjectSP();
-            
-            test_idx++;
-            
-            if (!key_at_idx || !val_at_idx)
-                continue;
-            tries++;
-            
-            DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
-            
-            m_children.push_back(descriptor);
-        }
-    }
-    
-    if (idx >= m_children.size()) // should never happen
+      Error error;
+      key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+      if (error.Fail())
         return lldb::ValueObjectSP();
-    
-    DictionaryItemDescriptor &dict_item = m_children[idx];
-    if (!dict_item.valobj_sp)
-    {
-        if (!m_pair_type.IsValid())
-        {
-            TargetSP target_sp(m_backend.GetTargetSP());
-            if (!target_sp)
-                return ValueObjectSP();
-            m_pair_type = GetLLDBNSPairType(target_sp);
-        }
-        if (!m_pair_type.IsValid())
-            return ValueObjectSP();
-        
-        DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
-        
-        if (m_ptr_size == 8)
-        {
-            uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
-            *data_ptr = dict_item.key_ptr;
-            *(data_ptr+1) = dict_item.val_ptr;
-        }
-        else
-        {
-            uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
-            *data_ptr = dict_item.key_ptr;
-            *(data_ptr+1) = dict_item.val_ptr;
-        }
-        
-        StreamString idx_name;
-        idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-        DataExtractor data(buffer_sp, m_order, m_ptr_size);
-        dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetData(),
-                                                        data,
-                                                        m_exe_ctx_ref,
-                                                        m_pair_type);
+      val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+      if (error.Fail())
+        return lldb::ValueObjectSP();
+
+      test_idx++;
+
+      if (!key_at_idx || !val_at_idx)
+        continue;
+      tries++;
+
+      DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx,
+                                             lldb::ValueObjectSP()};
+
+      m_children.push_back(descriptor);
     }
-    return dict_item.valobj_sp;
+  }
+
+  if (idx >= m_children.size()) // should never happen
+    return lldb::ValueObjectSP();
+
+  DictionaryItemDescriptor &dict_item = m_children[idx];
+  if (!dict_item.valobj_sp) {
+    if (!m_pair_type.IsValid()) {
+      TargetSP target_sp(m_backend.GetTargetSP());
+      if (!target_sp)
+        return ValueObjectSP();
+      m_pair_type = GetLLDBNSPairType(target_sp);
+    }
+    if (!m_pair_type.IsValid())
+      return ValueObjectSP();
+
+    DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0));
+
+    if (m_ptr_size == 8) {
+      uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
+      *data_ptr = dict_item.key_ptr;
+      *(data_ptr + 1) = dict_item.val_ptr;
+    } else {
+      uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
+      *data_ptr = dict_item.key_ptr;
+      *(data_ptr + 1) = dict_item.val_ptr;
+    }
+
+    StreamString idx_name;
+    idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+    DataExtractor data(buffer_sp, m_order, m_ptr_size);
+    dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetData(), data,
+                                                    m_exe_ctx_ref, m_pair_type);
+  }
+  return dict_item.valobj_sp;
 }
 
-template bool
-lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::NSDictionarySummaryProvider<true>(
+    ValueObject &, Stream &, const TypeSummaryOptions &);
 
-template bool
-lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&);
+template bool lldb_private::formatters::NSDictionarySummaryProvider<false>(
+    ValueObject &, Stream &, const TypeSummaryOptions &);
diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.h b/lldb/source/Plugins/Language/ObjC/NSDictionary.h
index e96c25a..cbb484a 100644
--- a/lldb/source/Plugins/Language/ObjC/NSDictionary.h
+++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.h
@@ -1,4 +1,5 @@
-//===-- NSDictionary.h ---------------------------------------------------*- C++ -*-===//
+//===-- NSDictionary.h ---------------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -19,30 +20,32 @@
 #include <map>
 
 namespace lldb_private {
-    namespace formatters
-    {
-        template<bool name_entries>
-        bool
-        NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+namespace formatters {
+template <bool name_entries>
+bool NSDictionarySummaryProvider(ValueObject &valobj, Stream &stream,
+                                 const TypeSummaryOptions &options);
 
-        extern template bool
-        NSDictionarySummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-        
-        extern template bool
-        NSDictionarySummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-        
-        SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-        
-        class NSDictionary_Additionals
-        {
-        public:
-            static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-            GetAdditionalSummaries ();
-            
-            static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
-            GetAdditionalSynthetics ();
-        };
-    } // namespace formatters
+extern template bool
+NSDictionarySummaryProvider<true>(ValueObject &, Stream &,
+                                  const TypeSummaryOptions &);
+
+extern template bool
+NSDictionarySummaryProvider<false>(ValueObject &, Stream &,
+                                   const TypeSummaryOptions &);
+
+SyntheticChildrenFrontEnd *
+NSDictionarySyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                     lldb::ValueObjectSP);
+
+class NSDictionary_Additionals {
+public:
+  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+  GetAdditionalSummaries();
+
+  static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+  GetAdditionalSynthetics();
+};
+} // namespace formatters
 } // namespace lldb_private
 
 #endif // liblldb_NSDictionary_h_
diff --git a/lldb/source/Plugins/Language/ObjC/NSError.cpp b/lldb/source/Plugins/Language/ObjC/NSError.cpp
index 4bfb024..bad22b1 100644
--- a/lldb/source/Plugins/Language/ObjC/NSError.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSError.cpp
@@ -34,196 +34,187 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-static lldb::addr_t
-DerefToNSErrorPointer (ValueObject& valobj)
-{
-    CompilerType valobj_type(valobj.GetCompilerType());
-    Flags type_flags(valobj_type.GetTypeInfo());
-    if (type_flags.AllClear(eTypeHasValue))
-    {
-        if (valobj.IsBaseClass() && valobj.GetParent())
-            return valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-    }
-    else
-    {
-        lldb::addr_t ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-        if (type_flags.AllSet(eTypeIsPointer))
-        {
-            CompilerType pointee_type(valobj_type.GetPointeeType());
-            Flags pointee_flags(pointee_type.GetTypeInfo());
-            if (pointee_flags.AllSet(eTypeIsPointer))
-            {
-                if (ProcessSP process_sp = valobj.GetProcessSP())
-                {
-                    Error error;
-                    ptr_value = process_sp->ReadPointerFromMemory(ptr_value, error);
-                }
-            }
+static lldb::addr_t DerefToNSErrorPointer(ValueObject &valobj) {
+  CompilerType valobj_type(valobj.GetCompilerType());
+  Flags type_flags(valobj_type.GetTypeInfo());
+  if (type_flags.AllClear(eTypeHasValue)) {
+    if (valobj.IsBaseClass() && valobj.GetParent())
+      return valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+  } else {
+    lldb::addr_t ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+    if (type_flags.AllSet(eTypeIsPointer)) {
+      CompilerType pointee_type(valobj_type.GetPointeeType());
+      Flags pointee_flags(pointee_type.GetTypeInfo());
+      if (pointee_flags.AllSet(eTypeIsPointer)) {
+        if (ProcessSP process_sp = valobj.GetProcessSP()) {
+          Error error;
+          ptr_value = process_sp->ReadPointerFromMemory(ptr_value, error);
         }
-        return ptr_value;
+      }
     }
-    
-    return LLDB_INVALID_ADDRESS;
+    return ptr_value;
+  }
+
+  return LLDB_INVALID_ADDRESS;
 }
 
-bool
-lldb_private::formatters::NSError_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp(valobj.GetProcessSP());
+bool lldb_private::formatters::NSError_SummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp(valobj.GetProcessSP());
+  if (!process_sp)
+    return false;
+
+  lldb::addr_t ptr_value = DerefToNSErrorPointer(valobj);
+  if (ptr_value == LLDB_INVALID_ADDRESS)
+    return false;
+
+  size_t ptr_size = process_sp->GetAddressByteSize();
+  lldb::addr_t code_location = ptr_value + 2 * ptr_size;
+  lldb::addr_t domain_location = ptr_value + 3 * ptr_size;
+
+  Error error;
+  uint64_t code = process_sp->ReadUnsignedIntegerFromMemory(code_location,
+                                                            ptr_size, 0, error);
+  if (error.Fail())
+    return false;
+
+  lldb::addr_t domain_str_value =
+      process_sp->ReadPointerFromMemory(domain_location, error);
+  if (error.Fail() || domain_str_value == LLDB_INVALID_ADDRESS)
+    return false;
+
+  if (!domain_str_value) {
+    stream.Printf("domain: nil - code: %" PRIu64, code);
+    return true;
+  }
+
+  InferiorSizedWord isw(domain_str_value, *process_sp);
+
+  ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData(
+      "domain_str", isw.GetAsData(process_sp->GetByteOrder()),
+      valobj.GetExecutionContextRef(), process_sp->GetTarget()
+                                           .GetScratchClangASTContext()
+                                           ->GetBasicType(lldb::eBasicTypeVoid)
+                                           .GetPointerType());
+
+  if (!domain_str_sp)
+    return false;
+
+  StreamString domain_str_summary;
+  if (NSStringSummaryProvider(*domain_str_sp, domain_str_summary, options) &&
+      !domain_str_summary.Empty()) {
+    stream.Printf("domain: %s - code: %" PRIu64, domain_str_summary.GetData(),
+                  code);
+    return true;
+  } else {
+    stream.Printf("domain: nil - code: %" PRIu64, code);
+    return true;
+  }
+}
+
+class NSErrorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSErrorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+      : SyntheticChildrenFrontEnd(*valobj_sp) {}
+
+  ~NSErrorSyntheticFrontEnd() override = default;
+  // no need to delete m_child_ptr - it's kept alive by the cluster manager on
+  // our behalf
+
+  size_t CalculateNumChildren() override {
+    if (m_child_ptr)
+      return 1;
+    if (m_child_sp)
+      return 1;
+    return 0;
+  }
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
+    if (idx != 0)
+      return lldb::ValueObjectSP();
+
+    if (m_child_ptr)
+      return m_child_ptr->GetSP();
+    return m_child_sp;
+  }
+
+  bool Update() override {
+    m_child_ptr = nullptr;
+    m_child_sp.reset();
+
+    ProcessSP process_sp(m_backend.GetProcessSP());
     if (!process_sp)
-        return false;
-    
-    lldb::addr_t ptr_value = DerefToNSErrorPointer(valobj);
-    if (ptr_value == LLDB_INVALID_ADDRESS)
-        return false;
+      return false;
+
+    lldb::addr_t userinfo_location = DerefToNSErrorPointer(m_backend);
+    if (userinfo_location == LLDB_INVALID_ADDRESS)
+      return false;
 
     size_t ptr_size = process_sp->GetAddressByteSize();
-    lldb::addr_t code_location = ptr_value + 2 * ptr_size;
-    lldb::addr_t domain_location = ptr_value + 3 * ptr_size;
-    
+
+    userinfo_location += 4 * ptr_size;
     Error error;
-    uint64_t code = process_sp->ReadUnsignedIntegerFromMemory(code_location, ptr_size, 0, error);
-    if (error.Fail())
-        return false;
-    
-    lldb::addr_t domain_str_value = process_sp->ReadPointerFromMemory(domain_location, error);
-    if (error.Fail() || domain_str_value == LLDB_INVALID_ADDRESS)
-        return false;
-    
-    if (!domain_str_value)
-    {
-        stream.Printf("domain: nil - code: %" PRIu64, code);
-        return true;
-    }
-    
-    InferiorSizedWord isw(domain_str_value, *process_sp);
-    
-    ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData("domain_str", isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeVoid).GetPointerType());
-    
-    if (!domain_str_sp)
-        return false;
-    
-    StreamString domain_str_summary;
-    if (NSStringSummaryProvider(*domain_str_sp, domain_str_summary, options) && !domain_str_summary.Empty())
-    {
-        stream.Printf("domain: %s - code: %" PRIu64, domain_str_summary.GetData(), code);
-        return true;
-    }
-    else
-    {
-        stream.Printf("domain: nil - code: %" PRIu64, code);
-        return true;
-    }
-}
+    lldb::addr_t userinfo =
+        process_sp->ReadPointerFromMemory(userinfo_location, error);
+    if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
+      return false;
+    InferiorSizedWord isw(userinfo, *process_sp);
+    m_child_sp = CreateValueObjectFromData(
+        "_userInfo", isw.GetAsData(process_sp->GetByteOrder()),
+        m_backend.GetExecutionContextRef(),
+        process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(
+            lldb::eBasicTypeObjCID));
+    return false;
+  }
 
-class NSErrorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
-public:
-    NSErrorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-    SyntheticChildrenFrontEnd(*valobj_sp)
-    {}
+  bool MightHaveChildren() override { return true; }
 
-    ~NSErrorSyntheticFrontEnd() override = default;
-    // no need to delete m_child_ptr - it's kept alive by the cluster manager on our behalf
-
-    size_t
-    CalculateNumChildren() override
-    {
-        if (m_child_ptr)
-            return 1;
-        if (m_child_sp)
-            return 1;
-        return 0;
-    }
-    
-    lldb::ValueObjectSP
-    GetChildAtIndex(size_t idx) override
-    {
-        if (idx != 0)
-            return lldb::ValueObjectSP();
-        
-        if (m_child_ptr)
-            return m_child_ptr->GetSP();
-        return m_child_sp;
-    }
-    
-    bool
-    Update() override
-    {
-        m_child_ptr = nullptr;
-        m_child_sp.reset();
-        
-        ProcessSP process_sp(m_backend.GetProcessSP());
-        if (!process_sp)
-            return false;
-        
-        lldb::addr_t userinfo_location = DerefToNSErrorPointer(m_backend);
-        if (userinfo_location == LLDB_INVALID_ADDRESS)
-            return false;
-        
-        size_t ptr_size = process_sp->GetAddressByteSize();
-
-        userinfo_location += 4 * ptr_size;
-        Error error;
-        lldb::addr_t userinfo = process_sp->ReadPointerFromMemory(userinfo_location, error);
-        if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
-            return false;
-        InferiorSizedWord isw(userinfo,*process_sp);
-        m_child_sp = CreateValueObjectFromData("_userInfo",
-                                               isw.GetAsData(process_sp->GetByteOrder()),
-                                               m_backend.GetExecutionContextRef(),
-                                               process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
-        return false;
-    }
-    
-    bool
-    MightHaveChildren() override
-    {
-        return true;
-    }
-    
-    size_t
-    GetIndexOfChildWithName(const ConstString &name) override
-    {
-        static ConstString g___userInfo("_userInfo");
-        if (name == g___userInfo)
-            return 0;
-        return UINT32_MAX;
-    }
+  size_t GetIndexOfChildWithName(const ConstString &name) override {
+    static ConstString g___userInfo("_userInfo");
+    if (name == g___userInfo)
+      return 0;
+    return UINT32_MAX;
+  }
 
 private:
-    // the child here can be "real" (i.e. an actual child of the root) or synthetized from raw memory
-    // if the former, I need to store a plain pointer to it - or else a loop of references will cause this entire hierarchy of values to leak
-    // if the latter, then I need to store a SharedPointer to it - so that it only goes away when everyone else in the cluster goes away
-    // oh joy!
-    ValueObject* m_child_ptr;
-    ValueObjectSP m_child_sp;
+  // the child here can be "real" (i.e. an actual child of the root) or
+  // synthetized from raw memory
+  // if the former, I need to store a plain pointer to it - or else a loop of
+  // references will cause this entire hierarchy of values to leak
+  // if the latter, then I need to store a SharedPointer to it - so that it only
+  // goes away when everyone else in the cluster goes away
+  // oh joy!
+  ValueObject *m_child_ptr;
+  ValueObjectSP m_child_sp;
 };
 
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::NSErrorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
-    lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
-    if (!process_sp)
-        return nullptr;
-    ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    if (!runtime)
-        return nullptr;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return nullptr;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return nullptr;
-    
-    if (!strcmp(class_name,"NSError"))
-        return (new NSErrorSyntheticFrontEnd(valobj_sp));
-    else if (!strcmp(class_name,"__NSCFError"))
-        return (new NSErrorSyntheticFrontEnd(valobj_sp));
-    
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSErrorSyntheticFrontEndCreator(
+    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
     return nullptr;
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+  if (!runtime)
+    return nullptr;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(*valobj_sp.get()));
+
+  if (!descriptor.get() || !descriptor->IsValid())
+    return nullptr;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return nullptr;
+
+  if (!strcmp(class_name, "NSError"))
+    return (new NSErrorSyntheticFrontEnd(valobj_sp));
+  else if (!strcmp(class_name, "__NSCFError"))
+    return (new NSErrorSyntheticFrontEnd(valobj_sp));
+
+  return nullptr;
 }
diff --git a/lldb/source/Plugins/Language/ObjC/NSException.cpp b/lldb/source/Plugins/Language/ObjC/NSException.cpp
index f70e7c7..1609048 100644
--- a/lldb/source/Plugins/Language/ObjC/NSException.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSException.cpp
@@ -34,186 +34,183 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-bool
-lldb_private::formatters::NSException_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    ProcessSP process_sp(valobj.GetProcessSP());
-    if (!process_sp)
-        return false;
-    
-    lldb::addr_t ptr_value = LLDB_INVALID_ADDRESS;
-    
-    CompilerType valobj_type(valobj.GetCompilerType());
-    Flags type_flags(valobj_type.GetTypeInfo());
-    if (type_flags.AllClear(eTypeHasValue))
-    {
-        if (valobj.IsBaseClass() && valobj.GetParent())
-            ptr_value = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-    }
-    else
-        ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-    
-    if (ptr_value == LLDB_INVALID_ADDRESS)
-        return false;
-    size_t ptr_size = process_sp->GetAddressByteSize();
-    lldb::addr_t name_location = ptr_value + 1 * ptr_size;
-    lldb::addr_t reason_location = ptr_value + 2 * ptr_size;
-    
-    Error error;
-    lldb::addr_t name = process_sp->ReadPointerFromMemory(name_location, error);
-    if (error.Fail() || name == LLDB_INVALID_ADDRESS)
-        return false;
-    
-    lldb::addr_t reason = process_sp->ReadPointerFromMemory(reason_location, error);
-    if (error.Fail() || reason == LLDB_INVALID_ADDRESS)
-        return false;
-    
-    InferiorSizedWord name_isw(name, *process_sp);
-    InferiorSizedWord reason_isw(reason, *process_sp);
-    
-    CompilerType voidstar = process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
-    
-    ValueObjectSP name_sp = ValueObject::CreateValueObjectFromData("name_str", name_isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), voidstar);
-    ValueObjectSP reason_sp = ValueObject::CreateValueObjectFromData("reason_str", reason_isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), voidstar);
-    
-    if (!name_sp || !reason_sp)
-        return false;
-    
-    StreamString name_str_summary;
-    StreamString reason_str_summary;
-    if (NSStringSummaryProvider(*name_sp, name_str_summary, options) &&
-        NSStringSummaryProvider(*reason_sp, reason_str_summary, options) &&
-        !name_str_summary.Empty() &&
-        !reason_str_summary.Empty())
-    {
-        stream.Printf("name: %s - reason: %s", name_str_summary.GetData(), reason_str_summary.GetData());
-        return true;
-    }
-    else
-        return false;
+bool lldb_private::formatters::NSException_SummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  ProcessSP process_sp(valobj.GetProcessSP());
+  if (!process_sp)
+    return false;
+
+  lldb::addr_t ptr_value = LLDB_INVALID_ADDRESS;
+
+  CompilerType valobj_type(valobj.GetCompilerType());
+  Flags type_flags(valobj_type.GetTypeInfo());
+  if (type_flags.AllClear(eTypeHasValue)) {
+    if (valobj.IsBaseClass() && valobj.GetParent())
+      ptr_value = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+  } else
+    ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+
+  if (ptr_value == LLDB_INVALID_ADDRESS)
+    return false;
+  size_t ptr_size = process_sp->GetAddressByteSize();
+  lldb::addr_t name_location = ptr_value + 1 * ptr_size;
+  lldb::addr_t reason_location = ptr_value + 2 * ptr_size;
+
+  Error error;
+  lldb::addr_t name = process_sp->ReadPointerFromMemory(name_location, error);
+  if (error.Fail() || name == LLDB_INVALID_ADDRESS)
+    return false;
+
+  lldb::addr_t reason =
+      process_sp->ReadPointerFromMemory(reason_location, error);
+  if (error.Fail() || reason == LLDB_INVALID_ADDRESS)
+    return false;
+
+  InferiorSizedWord name_isw(name, *process_sp);
+  InferiorSizedWord reason_isw(reason, *process_sp);
+
+  CompilerType voidstar = process_sp->GetTarget()
+                              .GetScratchClangASTContext()
+                              ->GetBasicType(lldb::eBasicTypeVoid)
+                              .GetPointerType();
+
+  ValueObjectSP name_sp = ValueObject::CreateValueObjectFromData(
+      "name_str", name_isw.GetAsData(process_sp->GetByteOrder()),
+      valobj.GetExecutionContextRef(), voidstar);
+  ValueObjectSP reason_sp = ValueObject::CreateValueObjectFromData(
+      "reason_str", reason_isw.GetAsData(process_sp->GetByteOrder()),
+      valobj.GetExecutionContextRef(), voidstar);
+
+  if (!name_sp || !reason_sp)
+    return false;
+
+  StreamString name_str_summary;
+  StreamString reason_str_summary;
+  if (NSStringSummaryProvider(*name_sp, name_str_summary, options) &&
+      NSStringSummaryProvider(*reason_sp, reason_str_summary, options) &&
+      !name_str_summary.Empty() && !reason_str_summary.Empty()) {
+    stream.Printf("name: %s - reason: %s", name_str_summary.GetData(),
+                  reason_str_summary.GetData());
+    return true;
+  } else
+    return false;
 }
 
-class NSExceptionSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
+class NSExceptionSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
-    NSExceptionSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-    SyntheticChildrenFrontEnd(*valobj_sp)
-    {}
+  NSExceptionSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+      : SyntheticChildrenFrontEnd(*valobj_sp) {}
 
-    ~NSExceptionSyntheticFrontEnd() override = default;
-    // no need to delete m_child_ptr - it's kept alive by the cluster manager on our behalf
+  ~NSExceptionSyntheticFrontEnd() override = default;
+  // no need to delete m_child_ptr - it's kept alive by the cluster manager on
+  // our behalf
 
-    size_t
-    CalculateNumChildren() override
-    {
-        if (m_child_ptr)
-            return 1;
-        if (m_child_sp)
-            return 1;
-        return 0;
-    }
-    
-    lldb::ValueObjectSP
-    GetChildAtIndex(size_t idx) override
-    {
-        if (idx != 0)
-            return lldb::ValueObjectSP();
-        
-        if (m_child_ptr)
-            return m_child_ptr->GetSP();
-        return m_child_sp;
-    }
-    
-    bool
-    Update() override
-    {
-        m_child_ptr = nullptr;
-        m_child_sp.reset();
-        
-        ProcessSP process_sp(m_backend.GetProcessSP());
-        if (!process_sp)
-            return false;
-        
-        lldb::addr_t userinfo_location = LLDB_INVALID_ADDRESS;
-        
-        CompilerType valobj_type(m_backend.GetCompilerType());
-        Flags type_flags(valobj_type.GetTypeInfo());
-        if (type_flags.AllClear(eTypeHasValue))
-        {
-            if (m_backend.IsBaseClass() && m_backend.GetParent())
-                userinfo_location = m_backend.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-        }
-        else
-            userinfo_location = m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-        
-        if (userinfo_location == LLDB_INVALID_ADDRESS)
-            return false;
-        
-        size_t ptr_size = process_sp->GetAddressByteSize();
-        
-        userinfo_location += 3 * ptr_size;
-        Error error;
-        lldb::addr_t userinfo = process_sp->ReadPointerFromMemory(userinfo_location, error);
-        if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
-            return false;
-        InferiorSizedWord isw(userinfo,*process_sp);
-        m_child_sp = CreateValueObjectFromData("userInfo",
-                                               isw.GetAsData(process_sp->GetByteOrder()),
-                                               m_backend.GetExecutionContextRef(),
-                                               process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeObjCID));
-        return false;
-    }
-    
-    bool
-    MightHaveChildren() override
-    {
-        return true;
-    }
-    
-    size_t
-    GetIndexOfChildWithName(const ConstString &name) override
-    {
-        static ConstString g___userInfo("userInfo");
-        if (name == g___userInfo)
-            return 0;
-        return UINT32_MAX;
-    }
+  size_t CalculateNumChildren() override {
+    if (m_child_ptr)
+      return 1;
+    if (m_child_sp)
+      return 1;
+    return 0;
+  }
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
+    if (idx != 0)
+      return lldb::ValueObjectSP();
+
+    if (m_child_ptr)
+      return m_child_ptr->GetSP();
+    return m_child_sp;
+  }
+
+  bool Update() override {
+    m_child_ptr = nullptr;
+    m_child_sp.reset();
+
+    ProcessSP process_sp(m_backend.GetProcessSP());
+    if (!process_sp)
+      return false;
+
+    lldb::addr_t userinfo_location = LLDB_INVALID_ADDRESS;
+
+    CompilerType valobj_type(m_backend.GetCompilerType());
+    Flags type_flags(valobj_type.GetTypeInfo());
+    if (type_flags.AllClear(eTypeHasValue)) {
+      if (m_backend.IsBaseClass() && m_backend.GetParent())
+        userinfo_location =
+            m_backend.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+    } else
+      userinfo_location = m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+
+    if (userinfo_location == LLDB_INVALID_ADDRESS)
+      return false;
+
+    size_t ptr_size = process_sp->GetAddressByteSize();
+
+    userinfo_location += 3 * ptr_size;
+    Error error;
+    lldb::addr_t userinfo =
+        process_sp->ReadPointerFromMemory(userinfo_location, error);
+    if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
+      return false;
+    InferiorSizedWord isw(userinfo, *process_sp);
+    m_child_sp = CreateValueObjectFromData(
+        "userInfo", isw.GetAsData(process_sp->GetByteOrder()),
+        m_backend.GetExecutionContextRef(),
+        process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(
+            lldb::eBasicTypeObjCID));
+    return false;
+  }
+
+  bool MightHaveChildren() override { return true; }
+
+  size_t GetIndexOfChildWithName(const ConstString &name) override {
+    static ConstString g___userInfo("userInfo");
+    if (name == g___userInfo)
+      return 0;
+    return UINT32_MAX;
+  }
 
 private:
-    // the child here can be "real" (i.e. an actual child of the root) or synthetized from raw memory
-    // if the former, I need to store a plain pointer to it - or else a loop of references will cause this entire hierarchy of values to leak
-    // if the latter, then I need to store a SharedPointer to it - so that it only goes away when everyone else in the cluster goes away
-    // oh joy!
-    ValueObject* m_child_ptr;
-    ValueObjectSP m_child_sp;
+  // the child here can be "real" (i.e. an actual child of the root) or
+  // synthetized from raw memory
+  // if the former, I need to store a plain pointer to it - or else a loop of
+  // references will cause this entire hierarchy of values to leak
+  // if the latter, then I need to store a SharedPointer to it - so that it only
+  // goes away when everyone else in the cluster goes away
+  // oh joy!
+  ValueObject *m_child_ptr;
+  ValueObjectSP m_child_sp;
 };
 
-SyntheticChildrenFrontEnd*
-lldb_private::formatters::NSExceptionSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
-    lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
-    if (!process_sp)
-        return nullptr;
-    ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    if (!runtime)
-        return nullptr;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return nullptr;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return nullptr;
-    
-    if (!strcmp(class_name,"NSException"))
-        return (new NSExceptionSyntheticFrontEnd(valobj_sp));
-    else if (!strcmp(class_name,"NSCFException"))
-        return (new NSExceptionSyntheticFrontEnd(valobj_sp));
-    else if (!strcmp(class_name,"__NSCFException"))
-        return (new NSExceptionSyntheticFrontEnd(valobj_sp));
-    
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSExceptionSyntheticFrontEndCreator(
+    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
     return nullptr;
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+  if (!runtime)
+    return nullptr;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(*valobj_sp.get()));
+
+  if (!descriptor.get() || !descriptor->IsValid())
+    return nullptr;
+
+  const char *class_name = descriptor->GetClassName().GetCString();
+
+  if (!class_name || !*class_name)
+    return nullptr;
+
+  if (!strcmp(class_name, "NSException"))
+    return (new NSExceptionSyntheticFrontEnd(valobj_sp));
+  else if (!strcmp(class_name, "NSCFException"))
+    return (new NSExceptionSyntheticFrontEnd(valobj_sp));
+  else if (!strcmp(class_name, "__NSCFException"))
+    return (new NSExceptionSyntheticFrontEnd(valobj_sp));
+
+  return nullptr;
 }
diff --git a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
index 0bebaca..d169334 100644
--- a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -26,371 +26,299 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-static constexpr size_t
-PACKED_INDEX_SHIFT_64(size_t i)
-{
-    return (60 - (13 * (4-i)));
+static constexpr size_t PACKED_INDEX_SHIFT_64(size_t i) {
+  return (60 - (13 * (4 - i)));
 }
 
-static constexpr size_t
-PACKED_INDEX_SHIFT_32(size_t i)
-{
-    return (32 - (13 * (2-i)));
+static constexpr size_t PACKED_INDEX_SHIFT_32(size_t i) {
+  return (32 - (13 * (2 - i)));
 }
 
-class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
+class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
-    NSIndexPathSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-    SyntheticChildrenFrontEnd (*valobj_sp.get()),
-    m_descriptor_sp(nullptr),
-    m_impl(),
-    m_ptr_size(0),
-    m_uint_star_type()
-    {
-        m_ptr_size = m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize();
-    }
+  NSIndexPathSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+      : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_descriptor_sp(nullptr),
+        m_impl(), m_ptr_size(0), m_uint_star_type() {
+    m_ptr_size =
+        m_backend.GetTargetSP()->GetArchitecture().GetAddressByteSize();
+  }
 
-    ~NSIndexPathSyntheticFrontEnd() override = default;
+  ~NSIndexPathSyntheticFrontEnd() override = default;
 
-    size_t
-    CalculateNumChildren() override
-    {
-        return m_impl.GetNumIndexes();
-    }
-    
-    lldb::ValueObjectSP
-    GetChildAtIndex(size_t idx) override
-    {
-        return m_impl.GetIndexAtIndex(idx, m_uint_star_type);
-    }
-    
-    bool
-    Update() override
-    {
-        m_impl.Clear();
-        
-        TypeSystem* type_system = m_backend.GetCompilerType().GetTypeSystem();
-        if (!type_system)
-            return false;
+  size_t CalculateNumChildren() override { return m_impl.GetNumIndexes(); }
 
-        ClangASTContext *ast = m_backend.GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext();
-        if (!ast)
-            return false;
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
+    return m_impl.GetIndexAtIndex(idx, m_uint_star_type);
+  }
 
-        m_uint_star_type = ast->GetPointerSizedIntType(false);
-        
-        static ConstString g__indexes("_indexes");
-        static ConstString g__length("_length");
+  bool Update() override {
+    m_impl.Clear();
 
-        ProcessSP process_sp = m_backend.GetProcessSP();
-        if (!process_sp)
-            return false;
-        
-        ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-        
-        if (!runtime)
-            return false;
-        
-        ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(m_backend));
-        
-        if (!descriptor.get() || !descriptor->IsValid())
-            return false;
-        
-        uint64_t info_bits(0),value_bits(0),payload(0);
-        
-        if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits, &payload))
-        {
-            m_impl.m_inlined.SetIndexes(payload, *process_sp);
-            m_impl.m_mode = Mode::Inlined;
+    TypeSystem *type_system = m_backend.GetCompilerType().GetTypeSystem();
+    if (!type_system)
+      return false;
+
+    ClangASTContext *ast = m_backend.GetExecutionContextRef()
+                               .GetTargetSP()
+                               ->GetScratchClangASTContext();
+    if (!ast)
+      return false;
+
+    m_uint_star_type = ast->GetPointerSizedIntType(false);
+
+    static ConstString g__indexes("_indexes");
+    static ConstString g__length("_length");
+
+    ProcessSP process_sp = m_backend.GetProcessSP();
+    if (!process_sp)
+      return false;
+
+    ObjCLanguageRuntime *runtime =
+        (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+            lldb::eLanguageTypeObjC);
+
+    if (!runtime)
+      return false;
+
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+        runtime->GetClassDescriptor(m_backend));
+
+    if (!descriptor.get() || !descriptor->IsValid())
+      return false;
+
+    uint64_t info_bits(0), value_bits(0), payload(0);
+
+    if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits, &payload)) {
+      m_impl.m_inlined.SetIndexes(payload, *process_sp);
+      m_impl.m_mode = Mode::Inlined;
+    } else {
+      ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _indexes_id;
+      ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _length_id;
+
+      bool has_indexes(false), has_length(false);
+
+      for (size_t x = 0; x < descriptor->GetNumIVars(); x++) {
+        const auto &ivar = descriptor->GetIVarAtIndex(x);
+        if (ivar.m_name == g__indexes) {
+          _indexes_id = ivar;
+          has_indexes = true;
+        } else if (ivar.m_name == g__length) {
+          _length_id = ivar;
+          has_length = true;
         }
-        else
-        {
-            ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _indexes_id;
-            ObjCLanguageRuntime::ClassDescriptor::iVarDescriptor _length_id;
-            
-            bool has_indexes(false),has_length(false);
-            
-            for (size_t x = 0;
-                 x < descriptor->GetNumIVars();
-                 x++)
-            {
-                const auto& ivar = descriptor->GetIVarAtIndex(x);
-                if (ivar.m_name == g__indexes)
-                {
-                    _indexes_id = ivar;
-                    has_indexes = true;
-                }
-                else if (ivar.m_name == g__length)
-                {
-                    _length_id = ivar;
-                    has_length = true;
-                }
-                
-                if (has_length && has_indexes)
-                    break;
-            }
-            
-            if (has_length && has_indexes)
-            {
-                m_impl.m_outsourced.m_indexes = m_backend.GetSyntheticChildAtOffset(_indexes_id.m_offset,
-                                                                                    m_uint_star_type.GetPointerType(),
-                                                                                    true).get();
-                ValueObjectSP length_sp(m_backend.GetSyntheticChildAtOffset(_length_id.m_offset,
-                                                                            m_uint_star_type,
-                                                                            true));
-                if (length_sp)
-                {
-                    m_impl.m_outsourced.m_count = length_sp->GetValueAsUnsigned(0);
-                    if (m_impl.m_outsourced.m_indexes)
-                        m_impl.m_mode = Mode::Outsourced;
-                }
-            }
+
+        if (has_length && has_indexes)
+          break;
+      }
+
+      if (has_length && has_indexes) {
+        m_impl.m_outsourced.m_indexes =
+            m_backend
+                .GetSyntheticChildAtOffset(_indexes_id.m_offset,
+                                           m_uint_star_type.GetPointerType(),
+                                           true)
+                .get();
+        ValueObjectSP length_sp(m_backend.GetSyntheticChildAtOffset(
+            _length_id.m_offset, m_uint_star_type, true));
+        if (length_sp) {
+          m_impl.m_outsourced.m_count = length_sp->GetValueAsUnsigned(0);
+          if (m_impl.m_outsourced.m_indexes)
+            m_impl.m_mode = Mode::Outsourced;
         }
-        return false;
+      }
     }
-    
-    bool
-    MightHaveChildren() override
-    {
-        if (m_impl.m_mode == Mode::Invalid)
-            return false;
-        return true;
-    }
-    
-    size_t
-    GetIndexOfChildWithName(const ConstString &name) override
-    {
-        const char* item_name = name.GetCString();
-        uint32_t idx = ExtractIndexFromString(item_name);
-        if (idx < UINT32_MAX && idx >= CalculateNumChildren())
-            return UINT32_MAX;
-        return idx;
-    }
-    
-    lldb::ValueObjectSP
-    GetSyntheticValue() override
-    {
-        return nullptr;
-    }
+    return false;
+  }
+
+  bool MightHaveChildren() override {
+    if (m_impl.m_mode == Mode::Invalid)
+      return false;
+    return true;
+  }
+
+  size_t GetIndexOfChildWithName(const ConstString &name) override {
+    const char *item_name = name.GetCString();
+    uint32_t idx = ExtractIndexFromString(item_name);
+    if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+      return UINT32_MAX;
+    return idx;
+  }
+
+  lldb::ValueObjectSP GetSyntheticValue() override { return nullptr; }
 
 protected:
-    ObjCLanguageRuntime::ClassDescriptorSP m_descriptor_sp;
-    
-    enum class Mode {
-        Inlined,
-        Outsourced,
-        Invalid
+  ObjCLanguageRuntime::ClassDescriptorSP m_descriptor_sp;
+
+  enum class Mode { Inlined, Outsourced, Invalid };
+
+  struct Impl {
+    size_t GetNumIndexes() {
+      switch (m_mode) {
+      case Mode::Inlined:
+        return m_inlined.GetNumIndexes();
+      case Mode::Outsourced:
+        return m_outsourced.m_count;
+      default:
+        return 0;
+      }
+    }
+
+    lldb::ValueObjectSP GetIndexAtIndex(size_t idx,
+                                        const CompilerType &desired_type) {
+      if (idx >= GetNumIndexes())
+        return nullptr;
+      switch (m_mode) {
+      default:
+        return nullptr;
+      case Mode::Inlined:
+        return m_inlined.GetIndexAtIndex(idx, desired_type);
+      case Mode::Outsourced:
+        return m_outsourced.GetIndexAtIndex(idx);
+      }
+    }
+
+    struct InlinedIndexes {
+    public:
+      void SetIndexes(uint64_t value, Process &p) {
+        m_indexes = value;
+        _lengthForInlinePayload(p.GetAddressByteSize());
+        m_process = &p;
+      }
+
+      size_t GetNumIndexes() { return m_count; }
+
+      lldb::ValueObjectSP GetIndexAtIndex(size_t idx,
+                                          const CompilerType &desired_type) {
+        if (!m_process)
+          return nullptr;
+
+        std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx));
+        if (!value.second)
+          return nullptr;
+
+        Value v;
+        if (m_ptr_size == 8) {
+          Scalar scalar((unsigned long long)value.first);
+          v = Value(scalar);
+        } else {
+          Scalar scalar((unsigned int)value.first);
+          v = Value(scalar);
+        }
+
+        v.SetCompilerType(desired_type);
+
+        StreamString idx_name;
+        idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+
+        return ValueObjectConstResult::Create(m_process, v,
+                                              ConstString(idx_name.GetData()));
+      }
+
+      void Clear() {
+        m_indexes = 0;
+        m_count = 0;
+        m_ptr_size = 0;
+        m_process = nullptr;
+      }
+
+      InlinedIndexes()
+          : m_indexes(0), m_count(0), m_ptr_size(0), m_process(nullptr) {}
+
+    private:
+      uint64_t m_indexes;
+      size_t m_count;
+      uint32_t m_ptr_size;
+      Process *m_process;
+
+      // cfr. Foundation for the details of this code
+      size_t _lengthForInlinePayload(uint32_t ptr_size) {
+        m_ptr_size = ptr_size;
+        if (m_ptr_size == 8)
+          m_count = ((m_indexes >> 3) & 0x7);
+        else
+          m_count = ((m_indexes >> 3) & 0x3);
+        return m_count;
+      }
+
+      std::pair<uint64_t, bool> _indexAtPositionForInlinePayload(size_t pos) {
+        static const uint64_t PACKED_INDEX_MASK = ((1 << 13) - 1);
+        if (m_ptr_size == 8) {
+          switch (pos) {
+          case 3:
+          case 2:
+          case 1:
+          case 0:
+            return {(m_indexes >> PACKED_INDEX_SHIFT_64(pos)) &
+                        PACKED_INDEX_MASK,
+                    true};
+          default:
+            return {0, false};
+          }
+        } else {
+          switch (pos) {
+          case 0:
+          case 1:
+            return {(m_indexes >> PACKED_INDEX_SHIFT_32(pos)) &
+                        PACKED_INDEX_MASK,
+                    true};
+          default:
+            return {0, false};
+          }
+        }
+        return {0, false};
+      }
     };
-    
-    struct Impl
-    {
-        size_t
-        GetNumIndexes ()
-        {
-            switch (m_mode)
-            {
-                case Mode::Inlined:
-                    return m_inlined.GetNumIndexes();
-                case Mode::Outsourced:
-                    return m_outsourced.m_count;
-                default:
-                    return 0;
-            }
-        }
-        
-        lldb::ValueObjectSP
-        GetIndexAtIndex (size_t idx, const CompilerType& desired_type)
-        {
-            if (idx >= GetNumIndexes())
-                return nullptr;
-            switch (m_mode)
-            {
-                default: return nullptr;
-                case Mode::Inlined:
-                    return m_inlined.GetIndexAtIndex (idx, desired_type);
-                case Mode::Outsourced:
-                    return m_outsourced.GetIndexAtIndex (idx);
-            }
-        }
-        
-        struct InlinedIndexes
-        {
-        public:
-            void SetIndexes(uint64_t value, Process& p)
-            {
-                m_indexes = value;
-                _lengthForInlinePayload(p.GetAddressByteSize());
-                m_process = &p;
-            }
-            
-            size_t
-            GetNumIndexes ()
-            {
-                return m_count;
-            }
-            
-            lldb::ValueObjectSP
-            GetIndexAtIndex (size_t idx, const CompilerType& desired_type)
-            {
-                if (!m_process)
-                    return nullptr;
 
-                std::pair<uint64_t, bool> value(_indexAtPositionForInlinePayload(idx));
-                if (!value.second)
-                    return nullptr;
-                
-                Value v;
-                if (m_ptr_size == 8)
-                {
-                    Scalar scalar( (unsigned long long)value.first );
-                    v = Value(scalar);
-                }
-                else
-                {
-                    Scalar scalar( (unsigned int)value.first );
-                    v = Value(scalar);
-                }
-                
-                v.SetCompilerType(desired_type);
-                
-                StreamString idx_name;
-                idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-                
-                return ValueObjectConstResult::Create(m_process, v, ConstString(idx_name.GetData()));
-            }
-            
-            void
-            Clear ()
-            {
-                m_indexes = 0;
-                m_count = 0;
-                m_ptr_size = 0;
-                m_process = nullptr;
-            }
-            
-            InlinedIndexes () :
-            m_indexes(0),
-            m_count(0),
-            m_ptr_size(0),
-            m_process(nullptr)
-            {
-            }
-            
-        private:
-            uint64_t m_indexes;
-            size_t m_count;
-            uint32_t m_ptr_size;
-            Process *m_process;
-            
-            // cfr. Foundation for the details of this code
-            size_t _lengthForInlinePayload(uint32_t ptr_size) {
-                m_ptr_size = ptr_size;
-                if (m_ptr_size == 8)
-                    m_count = ((m_indexes >> 3) & 0x7);
-                else
-                    m_count = ((m_indexes >> 3) & 0x3);
-                return m_count;
-            }
-            
-            std::pair<uint64_t, bool>
-            _indexAtPositionForInlinePayload(size_t pos)
-            {
-                static const uint64_t PACKED_INDEX_MASK = ((1 << 13) - 1);
-                if (m_ptr_size == 8)
-                {
-                    switch (pos)
-                    {
-                        case 3:
-                        case 2:
-                        case 1:
-                        case 0:
-                            return {(m_indexes >> PACKED_INDEX_SHIFT_64(pos)) & PACKED_INDEX_MASK,true};
-                        default:
-                            return {0,false};
-                    }
-                }
-                else
-                {
-                    switch (pos)
-                    {
-                        case 0:
-                        case 1:
-                            return {(m_indexes >> PACKED_INDEX_SHIFT_32(pos)) & PACKED_INDEX_MASK,true};
-                        default:
-                            return {0,false};
-                    }
-                }
-                return {0,false};
-            }
-            
-        };
+    struct OutsourcedIndexes {
+      lldb::ValueObjectSP GetIndexAtIndex(size_t idx) {
+        if (m_indexes) {
+          ValueObjectSP index_sp(m_indexes->GetSyntheticArrayMember(idx, true));
+          return index_sp;
+        }
+        return nullptr;
+      }
 
-        struct OutsourcedIndexes
-        {
-            lldb::ValueObjectSP
-            GetIndexAtIndex (size_t idx)
-            {
-                if (m_indexes)
-                {
-                    ValueObjectSP index_sp(m_indexes->GetSyntheticArrayMember(idx, true));
-                    return index_sp;
-                }
-                return nullptr;
-            }
-            
-            void
-            Clear ()
-            {
-                m_indexes = nullptr;
-                m_count = 0;
-            }
-            
-            OutsourcedIndexes () :
-            m_indexes(nullptr),
-            m_count(0)
-            {
-            }
-            
-            ValueObject *m_indexes;
-            size_t m_count;
-        };
-        
-        union
-        {
-            struct InlinedIndexes m_inlined;
-            struct OutsourcedIndexes m_outsourced;
-        };
-        
-        void
-        Clear ()
-        {
-            m_mode = Mode::Invalid;
-            m_inlined.Clear();
-            m_outsourced.Clear();
-        }
-        
-        Impl() :
-        m_mode(Mode::Invalid)
-        {
-        }
-        
-        Mode m_mode;
-    } m_impl;
-    
-    uint32_t m_ptr_size;
-    CompilerType m_uint_star_type;
+      void Clear() {
+        m_indexes = nullptr;
+        m_count = 0;
+      }
+
+      OutsourcedIndexes() : m_indexes(nullptr), m_count(0) {}
+
+      ValueObject *m_indexes;
+      size_t m_count;
+    };
+
+    union {
+      struct InlinedIndexes m_inlined;
+      struct OutsourcedIndexes m_outsourced;
+    };
+
+    void Clear() {
+      m_mode = Mode::Invalid;
+      m_inlined.Clear();
+      m_outsourced.Clear();
+    }
+
+    Impl() : m_mode(Mode::Invalid) {}
+
+    Mode m_mode;
+  } m_impl;
+
+  uint32_t m_ptr_size;
+  CompilerType m_uint_star_type;
 };
 
 namespace lldb_private {
-    namespace formatters {
-        
-        SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-        {
-            if (valobj_sp)
-                return new NSIndexPathSyntheticFrontEnd(valobj_sp);
-            return nullptr;
-        }
+namespace formatters {
 
-    } // namespace formatters
+SyntheticChildrenFrontEnd *
+NSIndexPathSyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                    lldb::ValueObjectSP valobj_sp) {
+  if (valobj_sp)
+    return new NSIndexPathSyntheticFrontEnd(valobj_sp);
+  return nullptr;
+}
+
+} // namespace formatters
 } // namespace lldb_private
diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/lldb/source/Plugins/Language/ObjC/NSSet.cpp
index 3157710..a9ca98c 100644
--- a/lldb/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSSet.cpp
@@ -29,636 +29,572 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-NSSet_Additionals::GetAdditionalSummaries ()
-{
-    static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
-    return g_map;
+std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+NSSet_Additionals::GetAdditionalSummaries() {
+  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+  return g_map;
 }
 
-std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
-NSSet_Additionals::GetAdditionalSynthetics ()
-{
-    static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
-    return g_map;
+std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+NSSet_Additionals::GetAdditionalSynthetics() {
+  static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>
+      g_map;
+  return g_map;
 }
 
 namespace lldb_private {
-    namespace formatters {
-        class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+namespace formatters {
+class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSSetISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-            ~NSSetISyntheticFrontEnd() override;
+  ~NSSetISyntheticFrontEnd() 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;
+  size_t CalculateNumChildren() override;
 
-        private:
-            struct DataDescriptor_32
-            {
-                uint32_t _used : 26;
-                uint32_t _szidx : 6;
-            };
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
 
-            struct DataDescriptor_64
-            {
-                uint64_t _used : 58;
-                uint32_t _szidx : 6;
-            };
+  bool Update() override;
 
-            struct SetItemDescriptor
-            {
-                lldb::addr_t item_ptr;
-                lldb::ValueObjectSP valobj_sp;
-            };
+  bool MightHaveChildren() override;
 
-            ExecutionContextRef m_exe_ctx_ref;
-            uint8_t m_ptr_size;
-            DataDescriptor_32 *m_data_32;
-            DataDescriptor_64 *m_data_64;
-            lldb::addr_t m_data_ptr;
-            std::vector<SetItemDescriptor> m_children;
-        };
-        
-        class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+  size_t GetIndexOfChildWithName(const ConstString &name) override;
 
-            ~NSSetMSyntheticFrontEnd() override;
+private:
+  struct DataDescriptor_32 {
+    uint32_t _used : 26;
+    uint32_t _szidx : 6;
+  };
 
-            size_t
-            CalculateNumChildren() override;
-            
-            lldb::ValueObjectSP
-            GetChildAtIndex(size_t idx) override;
-            
-            bool
-            Update() override;
-            
-            bool
-            MightHaveChildren() override;
-            
-            size_t
-            GetIndexOfChildWithName(const ConstString &name) override;
+  struct DataDescriptor_64 {
+    uint64_t _used : 58;
+    uint32_t _szidx : 6;
+  };
 
-        private:
-            struct DataDescriptor_32
-            {
-                uint32_t _used : 26;
-                uint32_t _size;
-                uint32_t _mutations;
-                uint32_t _objs_addr;
-            };
+  struct SetItemDescriptor {
+    lldb::addr_t item_ptr;
+    lldb::ValueObjectSP valobj_sp;
+  };
 
-            struct DataDescriptor_64
-            {
-                uint64_t _used : 58;
-                uint64_t _size;
-                uint64_t _mutations;
-                uint64_t _objs_addr;
-            };
+  ExecutionContextRef m_exe_ctx_ref;
+  uint8_t m_ptr_size;
+  DataDescriptor_32 *m_data_32;
+  DataDescriptor_64 *m_data_64;
+  lldb::addr_t m_data_ptr;
+  std::vector<SetItemDescriptor> m_children;
+};
 
-            struct SetItemDescriptor
-            {
-                lldb::addr_t item_ptr;
-                lldb::ValueObjectSP valobj_sp;
-            };
+class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSSetMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-            ExecutionContextRef m_exe_ctx_ref;
-            uint8_t m_ptr_size;
-            DataDescriptor_32 *m_data_32;
-            DataDescriptor_64 *m_data_64;
-            std::vector<SetItemDescriptor> m_children;
-        };
-        
-        class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
-        {
-        public:
-            NSSetCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+  ~NSSetMSyntheticFrontEnd() override;
 
-            ~NSSetCodeRunningSyntheticFrontEnd() override;
+  size_t CalculateNumChildren() 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;
-        };
-    } // namespace formatters
+  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 _size;
+    uint32_t _mutations;
+    uint32_t _objs_addr;
+  };
+
+  struct DataDescriptor_64 {
+    uint64_t _used : 58;
+    uint64_t _size;
+    uint64_t _mutations;
+    uint64_t _objs_addr;
+  };
+
+  struct SetItemDescriptor {
+    lldb::addr_t item_ptr;
+    lldb::ValueObjectSP valobj_sp;
+  };
+
+  ExecutionContextRef m_exe_ctx_ref;
+  uint8_t m_ptr_size;
+  DataDescriptor_32 *m_data_32;
+  DataDescriptor_64 *m_data_64;
+  std::vector<SetItemDescriptor> m_children;
+};
+
+class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  ~NSSetCodeRunningSyntheticFrontEnd() 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;
+};
+} // namespace formatters
 } // namespace lldb_private
 
-template<bool cf_style>
-bool
-lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    static ConstString g_TypeHint("NSSet");
-    
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    bool is_64bit = (ptr_size == 8);
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint64_t value = 0;
-    
-    ConstString class_name_cs = descriptor->GetClassName();
-    const char* class_name = class_name_cs.GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"__NSSetI"))
-    {
-        Error error;
-        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
-        if (error.Fail())
-            return false;
-        value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
-    }
-    else if (!strcmp(class_name,"__NSSetM"))
-    {
-        Error error;
-        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
-        if (error.Fail())
-            return false;
-        value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
-    }
-    /*else if (!strcmp(class_name,"__NSCFSet"))
-     {
-     Error error;
-     value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
-     if (error.Fail())
-     return false;
-     if (is_64bit)
-     value &= ~0x1fff000000000000UL;
-     }
-     else if (!strcmp(class_name,"NSCountedSet"))
-     {
-     Error error;
-     value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
-     if (error.Fail())
-     return false;
-     value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), 4, 0, error);
-     if (error.Fail())
-     return false;
-     if (is_64bit)
-     value &= ~0x1fff000000000000UL;
-     }*/
-    else
-    {
-        auto& map(NSSet_Additionals::GetAdditionalSummaries());
-        auto iter = map.find(class_name_cs), end = map.end();
-        if (iter != end)
-            return iter->second(valobj, stream, options);
-        else
-            return false;
-    }
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(options.GetLanguage()))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    stream.Printf("%s%" PRIu64 " %s%s%s",
-                  prefix.c_str(),
-                  value,
-                  "element",
-                  value == 1 ? "" : "s",
-                  suffix.c_str());
-    return true;
-}
+template <bool cf_style>
+bool lldb_private::formatters::NSSetSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  static ConstString g_TypeHint("NSSet");
 
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
-{
-    lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
-    if (!process_sp)
-        return nullptr;
-    ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    if (!runtime)
-        return nullptr;
-    
-    CompilerType valobj_type(valobj_sp->GetCompilerType());
-    Flags flags(valobj_type.GetTypeInfo());
-    
-    if (flags.IsClear(eTypeIsPointer))
-    {
-        Error 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_cs = descriptor->GetClassName();
-    const char* class_name = class_name_cs.GetCString();
-    
-    if (!class_name || !*class_name)
-        return nullptr;
-    
-    if (!strcmp(class_name,"__NSSetI"))
-    {
-        return (new NSSetISyntheticFrontEnd(valobj_sp));
-    }
-    else if (!strcmp(class_name,"__NSSetM"))
-    {
-        return (new NSSetMSyntheticFrontEnd(valobj_sp));
-    }
-    else
-    {
-        auto& map(NSSet_Additionals::GetAdditionalSynthetics());
-        auto iter = map.find(class_name_cs), end = map.end();
-        if (iter != end)
-            return iter->second(synth, valobj_sp);
-        return nullptr;
-    }
-}
-
-lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-    SyntheticChildrenFrontEnd(*valobj_sp),
-    m_exe_ctx_ref(),
-    m_ptr_size(8),
-    m_data_32(nullptr),
-    m_data_64(nullptr)
-{
-    if (valobj_sp)
-        Update();
-}
-
-lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd ()
-{
-    delete m_data_32;
-    m_data_32 = nullptr;
-    delete m_data_64;
-    m_data_64 = nullptr;
-}
-
-size_t
-lldb_private::formatters::NSSetISyntheticFrontEnd::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::NSSetISyntheticFrontEnd::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::NSSetISyntheticFrontEnd::Update()
-{
-    m_children.clear();
-    delete m_data_32;
-    m_data_32 = nullptr;
-    delete m_data_64;
-    m_data_64 = nullptr;
-    m_ptr_size = 0;
-    ValueObjectSP valobj_sp = m_backend.GetSP();
-    if (!valobj_sp)
-        return false;
-    if (!valobj_sp)
-        return false;
-    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-    Error error;
-    if (valobj_sp->IsPointerType())
-    {
-        valobj_sp = valobj_sp->Dereference(error);
-        if (error.Fail() || !valobj_sp)
-            return false;
-    }
-    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->GetAddressOf() + 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;
-    m_data_ptr = data_location + m_ptr_size;
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
     return false;
+
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+
+  if (!runtime)
+    return false;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(valobj));
+
+  if (!descriptor || !descriptor->IsValid())
+    return false;
+
+  uint32_t ptr_size = process_sp->GetAddressByteSize();
+  bool is_64bit = (ptr_size == 8);
+
+  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+  if (!valobj_addr)
+    return false;
+
+  uint64_t value = 0;
+
+  ConstString class_name_cs = descriptor->GetClassName();
+  const char *class_name = class_name_cs.GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  if (!strcmp(class_name, "__NSSetI")) {
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                      ptr_size, 0, error);
+    if (error.Fail())
+      return false;
+    value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+  } else if (!strcmp(class_name, "__NSSetM")) {
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                      ptr_size, 0, error);
+    if (error.Fail())
+      return false;
+    value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+  }
+  /*else if (!strcmp(class_name,"__NSCFSet"))
+   {
+   Error error;
+   value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ?
+   20 : 12), 4, 0, error);
+   if (error.Fail())
+   return false;
+   if (is_64bit)
+   value &= ~0x1fff000000000000UL;
+   }
+   else if (!strcmp(class_name,"NSCountedSet"))
+   {
+   Error error;
+   value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+   ptr_size, 0, error);
+   if (error.Fail())
+   return false;
+   value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 :
+   12), 4, 0, error);
+   if (error.Fail())
+   return false;
+   if (is_64bit)
+   value &= ~0x1fff000000000000UL;
+   }*/
+  else {
+    auto &map(NSSet_Additionals::GetAdditionalSummaries());
+    auto iter = map.find(class_name_cs), end = map.end();
+    if (iter != end)
+      return iter->second(valobj, stream, options);
+    else
+      return false;
+  }
+
+  std::string prefix, suffix;
+  if (Language *language = Language::FindPlugin(options.GetLanguage())) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element",
+                value == 1 ? "" : "s", suffix.c_str());
+  return true;
 }
 
-bool
-lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren ()
-{
-    return true;
+SyntheticChildrenFrontEnd *
+lldb_private::formatters::NSSetSyntheticFrontEndCreator(
+    CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) {
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
+    return nullptr;
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
+  if (!runtime)
+    return nullptr;
+
+  CompilerType valobj_type(valobj_sp->GetCompilerType());
+  Flags flags(valobj_type.GetTypeInfo());
+
+  if (flags.IsClear(eTypeIsPointer)) {
+    Error 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_cs = descriptor->GetClassName();
+  const char *class_name = class_name_cs.GetCString();
+
+  if (!class_name || !*class_name)
+    return nullptr;
+
+  if (!strcmp(class_name, "__NSSetI")) {
+    return (new NSSetISyntheticFrontEnd(valobj_sp));
+  } else if (!strcmp(class_name, "__NSSetM")) {
+    return (new NSSetMSyntheticFrontEnd(valobj_sp));
+  } else {
+    auto &map(NSSet_Additionals::GetAdditionalSynthetics());
+    auto iter = map.find(class_name_cs), end = map.end();
+    if (iter != end)
+      return iter->second(synth, valobj_sp);
+    return nullptr;
+  }
+}
+
+lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd(
+    lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+      m_data_32(nullptr), m_data_64(nullptr) {
+  if (valobj_sp)
+    Update();
+}
+
+lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+}
+
+size_t
+lldb_private::formatters::NSSetISyntheticFrontEnd::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::NSSetISyntheticFrontEnd::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::NSSetISyntheticFrontEnd::Update() {
+  m_children.clear();
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+  m_ptr_size = 0;
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  if (!valobj_sp)
+    return false;
+  if (!valobj_sp)
+    return false;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  Error error;
+  if (valobj_sp->IsPointerType()) {
+    valobj_sp = valobj_sp->Dereference(error);
+    if (error.Fail() || !valobj_sp)
+      return false;
+  }
+  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->GetAddressOf() + 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;
+  m_data_ptr = data_location + m_ptr_size;
+  return false;
+}
+
+bool lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren() {
+  return true;
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
-    uint32_t num_children = CalculateNumChildren();
-    
-    if (idx >= num_children)
+lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+  uint32_t num_children = CalculateNumChildren();
+
+  if (idx >= num_children)
+    return lldb::ValueObjectSP();
+
+  ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+  if (!process_sp)
+    return lldb::ValueObjectSP();
+
+  if (m_children.empty()) {
+    // do the scan phase
+    lldb::addr_t obj_at_idx = 0;
+
+    uint32_t tries = 0;
+    uint32_t test_idx = 0;
+
+    while (tries < num_children) {
+      obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
+      if (!process_sp)
         return lldb::ValueObjectSP();
-    
-    ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
-    if (!process_sp)
+      Error error;
+      obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
+      if (error.Fail())
         return lldb::ValueObjectSP();
-    
-    if (m_children.empty())
-    {
-        // do the scan phase
-        lldb::addr_t obj_at_idx = 0;
-        
-        uint32_t tries = 0;
-        uint32_t test_idx = 0;
-        
-        while(tries < num_children)
-        {
-            obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
-            if (!process_sp)
-                return lldb::ValueObjectSP();
-            Error error;
-            obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
-            if (error.Fail())
-                return lldb::ValueObjectSP();
-            
-            test_idx++;
-            
-            if (!obj_at_idx)
-                continue;
-            tries++;
-            
-            SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
-            
-            m_children.push_back(descriptor);
-        }
+
+      test_idx++;
+
+      if (!obj_at_idx)
+        continue;
+      tries++;
+
+      SetItemDescriptor descriptor = {obj_at_idx, lldb::ValueObjectSP()};
+
+      m_children.push_back(descriptor);
     }
-    
-    if (idx >= m_children.size()) // should never happen
-        return lldb::ValueObjectSP();
-    
-    SetItemDescriptor &set_item = m_children[idx];
-    if (!set_item.valobj_sp)
-    {
-        auto ptr_size = process_sp->GetAddressByteSize();
-        DataBufferHeap buffer(ptr_size,0);
-        switch (ptr_size)
-        {
-            case 0: // architecture has no clue?? - fail
-                return lldb::ValueObjectSP();
-            case 4:
-                *((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
-                break;
-            case 8:
-                *((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
-                break;
-            default:
-                assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
-        }
-        StreamString idx_name;
-        idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-        
-        DataExtractor data(buffer.GetBytes(),
-                           buffer.GetByteSize(),
-                           process_sp->GetByteOrder(),
-                           process_sp->GetAddressByteSize());
-        
-        set_item.valobj_sp =
-        CreateValueObjectFromData(idx_name.GetData(),
-                                  data,
-                                  m_exe_ctx_ref,
-                                  m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
+  }
+
+  if (idx >= m_children.size()) // should never happen
+    return lldb::ValueObjectSP();
+
+  SetItemDescriptor &set_item = m_children[idx];
+  if (!set_item.valobj_sp) {
+    auto ptr_size = process_sp->GetAddressByteSize();
+    DataBufferHeap buffer(ptr_size, 0);
+    switch (ptr_size) {
+    case 0: // architecture has no clue?? - fail
+      return lldb::ValueObjectSP();
+    case 4:
+      *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
+      break;
+    case 8:
+      *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
+      break;
+    default:
+      assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
     }
-    return set_item.valobj_sp;
+    StreamString idx_name;
+    idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+
+    DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
+                       process_sp->GetByteOrder(),
+                       process_sp->GetAddressByteSize());
+
+    set_item.valobj_sp = CreateValueObjectFromData(
+        idx_name.GetData(), data, m_exe_ctx_ref,
+        m_backend.GetCompilerType().GetBasicTypeFromAST(
+            lldb::eBasicTypeObjCID));
+  }
+  return set_item.valobj_sp;
 }
 
-lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-    SyntheticChildrenFrontEnd(*valobj_sp),
-    m_exe_ctx_ref(),
-    m_ptr_size(8),
-    m_data_32(nullptr),
-    m_data_64(nullptr)
-{
-    if (valobj_sp)
-        Update ();
+lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd(
+    lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+      m_data_32(nullptr), m_data_64(nullptr) {
+  if (valobj_sp)
+    Update();
 }
 
-lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd ()
-{
-    delete m_data_32;
-    m_data_32 = nullptr;
-    delete m_data_64;
-    m_data_64 = nullptr;
+lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
 }
 
 size_t
-lldb_private::formatters::NSSetMSyntheticFrontEnd::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;
+lldb_private::formatters::NSSetMSyntheticFrontEnd::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::NSSetMSyntheticFrontEnd::CalculateNumChildren ()
-{
-    if (!m_data_32 && !m_data_64)
-        return 0;
-    return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+lldb_private::formatters::NSSetMSyntheticFrontEnd::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::NSSetMSyntheticFrontEnd::Update()
-{
-    m_children.clear();
-    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;
-    if (!valobj_sp)
-        return false;
-    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-    Error error;
-    if (valobj_sp->IsPointerType())
-    {
-        valobj_sp = valobj_sp->Dereference(error);
-        if (error.Fail() || !valobj_sp)
-            return false;
-    }
-    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->GetAddressOf() + 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;
+bool lldb_private::formatters::NSSetMSyntheticFrontEnd::Update() {
+  m_children.clear();
+  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;
+  if (!valobj_sp)
+    return false;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  Error error;
+  if (valobj_sp->IsPointerType()) {
+    valobj_sp = valobj_sp->Dereference(error);
+    if (error.Fail() || !valobj_sp)
+      return false;
+  }
+  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->GetAddressOf() + 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::NSSetMSyntheticFrontEnd::MightHaveChildren ()
-{
-    return true;
+bool lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren() {
+  return true;
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
-{
-    lldb::addr_t m_objs_addr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
-    
-    uint32_t num_children = CalculateNumChildren();
-    
-    if (idx >= num_children)
+lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+  lldb::addr_t m_objs_addr =
+      (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
+
+  uint32_t num_children = CalculateNumChildren();
+
+  if (idx >= num_children)
+    return lldb::ValueObjectSP();
+
+  ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+  if (!process_sp)
+    return lldb::ValueObjectSP();
+
+  if (m_children.empty()) {
+    // do the scan phase
+    lldb::addr_t obj_at_idx = 0;
+
+    uint32_t tries = 0;
+    uint32_t test_idx = 0;
+
+    while (tries < num_children) {
+      obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
+      if (!process_sp)
         return lldb::ValueObjectSP();
-    
-    ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
-    if (!process_sp)
+      Error error;
+      obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
+      if (error.Fail())
         return lldb::ValueObjectSP();
-    
-    if (m_children.empty())
-    {
-        // do the scan phase
-        lldb::addr_t obj_at_idx = 0;
-        
-        uint32_t tries = 0;
-        uint32_t test_idx = 0;
-        
-        while(tries < num_children)
-        {
-            obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
-            if (!process_sp)
-                return lldb::ValueObjectSP();
-            Error error;
-            obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
-            if (error.Fail())
-                return lldb::ValueObjectSP();
-            
-            test_idx++;
-            
-            if (!obj_at_idx)
-                continue;
-            tries++;
-            
-            SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
-            
-            m_children.push_back(descriptor);
-        }
+
+      test_idx++;
+
+      if (!obj_at_idx)
+        continue;
+      tries++;
+
+      SetItemDescriptor descriptor = {obj_at_idx, lldb::ValueObjectSP()};
+
+      m_children.push_back(descriptor);
     }
-    
-    if (idx >= m_children.size()) // should never happen
-        return lldb::ValueObjectSP();
-    
-    SetItemDescriptor &set_item = m_children[idx];
-    if (!set_item.valobj_sp)
-    {
-        auto ptr_size = process_sp->GetAddressByteSize();
-        DataBufferHeap buffer(ptr_size,0);
-        switch (ptr_size)
-        {
-            case 0: // architecture has no clue?? - fail
-                return lldb::ValueObjectSP();
-            case 4:
-                *((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
-                break;
-            case 8:
-                *((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
-                break;
-            default:
-                assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
-        }
-        StreamString idx_name;
-        idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
-        
-        DataExtractor data(buffer.GetBytes(),
-                           buffer.GetByteSize(),
-                           process_sp->GetByteOrder(),
-                           process_sp->GetAddressByteSize());
-        
-        set_item.valobj_sp =
-        CreateValueObjectFromData(idx_name.GetData(),
-                                  data,
-                                  m_exe_ctx_ref,
-                                  m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
+  }
+
+  if (idx >= m_children.size()) // should never happen
+    return lldb::ValueObjectSP();
+
+  SetItemDescriptor &set_item = m_children[idx];
+  if (!set_item.valobj_sp) {
+    auto ptr_size = process_sp->GetAddressByteSize();
+    DataBufferHeap buffer(ptr_size, 0);
+    switch (ptr_size) {
+    case 0: // architecture has no clue?? - fail
+      return lldb::ValueObjectSP();
+    case 4:
+      *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
+      break;
+    case 8:
+      *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
+      break;
+    default:
+      assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
     }
-    return set_item.valobj_sp;
+    StreamString idx_name;
+    idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+
+    DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
+                       process_sp->GetByteOrder(),
+                       process_sp->GetAddressByteSize());
+
+    set_item.valobj_sp = CreateValueObjectFromData(
+        idx_name.GetData(), data, m_exe_ctx_ref,
+        m_backend.GetCompilerType().GetBasicTypeFromAST(
+            lldb::eBasicTypeObjCID));
+  }
+  return set_item.valobj_sp;
 }
 
-template bool
-lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+template bool lldb_private::formatters::NSSetSummaryProvider<true>(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
 
-template bool
-lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+template bool lldb_private::formatters::NSSetSummaryProvider<false>(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.h b/lldb/source/Plugins/Language/ObjC/NSSet.h
index c862270..dbc5dfa 100644
--- a/lldb/source/Plugins/Language/ObjC/NSSet.h
+++ b/lldb/source/Plugins/Language/ObjC/NSSet.h
@@ -1,4 +1,5 @@
-//===-- NSSet.h ---------------------------------------------------*- C++ -*-===//
+//===-- NSSet.h ---------------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -17,24 +18,23 @@
 #include "lldb/DataFormatters/TypeSynthetic.h"
 
 namespace lldb_private {
-    namespace formatters
-    {
-        template<bool cf_style>
-        bool
-        NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-        
-        class NSSet_Additionals
-        {
-        public:
-            static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-            GetAdditionalSummaries ();
-            
-            static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
-            GetAdditionalSynthetics ();
-        };
-    } // namespace formatters
+namespace formatters {
+template <bool cf_style>
+bool NSSetSummaryProvider(ValueObject &valobj, Stream &stream,
+                          const TypeSummaryOptions &options);
+
+SyntheticChildrenFrontEnd *NSSetSyntheticFrontEndCreator(CXXSyntheticChildren *,
+                                                         lldb::ValueObjectSP);
+
+class NSSet_Additionals {
+public:
+  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+  GetAdditionalSummaries();
+
+  static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> &
+  GetAdditionalSynthetics();
+};
+} // namespace formatters
 } // namespace lldb_private
 
 #endif // liblldb_NSSet_h_
diff --git a/lldb/source/Plugins/Language/ObjC/NSString.cpp b/lldb/source/Plugins/Language/ObjC/NSString.cpp
index 8089663..0f2a059 100644
--- a/lldb/source/Plugins/Language/ObjC/NSString.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSString.cpp
@@ -1,4 +1,5 @@
-//===-- NSString.cpp ----------------------------------------------*- C++ -*-===//
+//===-- NSString.cpp ----------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -26,380 +27,380 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-NSString_Additionals::GetAdditionalSummaries ()
-{
-    static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
-    return g_map;
+std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+NSString_Additionals::GetAdditionalSummaries() {
+  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+  return g_map;
 }
 
-static CompilerType
-GetNSPathStore2Type (Target &target)
-{
-    static ConstString g_type_name("__lldb_autogen_nspathstore2");
-    
-    ClangASTContext *ast_ctx = target.GetScratchClangASTContext();
-    
-    if (!ast_ctx)
-        return CompilerType();
-    
-    CompilerType voidstar = ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
-    CompilerType uint32 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
-    
-    return ast_ctx->GetOrCreateStructForIdentifier(g_type_name, {
-        {"isa",voidstar},
-        {"lengthAndRef",uint32},
-        {"buffer",voidstar}
-    });
+static CompilerType GetNSPathStore2Type(Target &target) {
+  static ConstString g_type_name("__lldb_autogen_nspathstore2");
+
+  ClangASTContext *ast_ctx = target.GetScratchClangASTContext();
+
+  if (!ast_ctx)
+    return CompilerType();
+
+  CompilerType voidstar =
+      ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
+  CompilerType uint32 =
+      ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+
+  return ast_ctx->GetOrCreateStructForIdentifier(
+      g_type_name,
+      {{"isa", voidstar}, {"lengthAndRef", uint32}, {"buffer", voidstar}});
 }
 
-bool
-lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
-{
-    static ConstString g_TypeHint("NSString");
-    
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    ConstString class_name_cs = descriptor->GetClassName();
-    const char* class_name = class_name_cs.GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    bool is_tagged_ptr = (0 == strcmp(class_name,"NSTaggedPointerString")) && descriptor->GetTaggedPointerInfo();
-    // for a tagged pointer, the descriptor has everything we need
-    if (is_tagged_ptr)
-        return NSTaggedString_SummaryProvider(valobj, descriptor, stream, summary_options);
-    
-    auto& additionals_map(NSString_Additionals::GetAdditionalSummaries());
-    auto iter = additionals_map.find(class_name_cs), end = additionals_map.end();
-    if (iter != end)
-        return iter->second(valobj, stream, summary_options);
-    
-    // if not a tagged pointer that we know about, try the normal route
-    uint64_t info_bits_location = valobj_addr + ptr_size;
-    if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
-        info_bits_location += 3;
-    
-    Error error;
-    
-    uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
-    if (error.Fail())
-        return false;
-    
-    bool is_mutable = (info_bits & 1) == 1;
-    bool is_inline = (info_bits & 0x60) == 0;
-    bool has_explicit_length = (info_bits & (1 | 4)) != 4;
-    bool is_unicode = (info_bits & 0x10) == 0x10;
-    bool is_path_store = strcmp(class_name,"NSPathStore2") == 0;
-    bool has_null = (info_bits & 8) == 8;
-    
-    size_t explicit_length = 0;
-    if (!has_null && has_explicit_length && !is_path_store)
-    {
-        lldb::addr_t explicit_length_offset = 2*ptr_size;
-        if (is_mutable && !is_inline)
-            explicit_length_offset = explicit_length_offset + ptr_size; //  notInlineMutable.length;
-        else if (is_inline)
-            explicit_length = explicit_length + 0; // inline1.length;
-        else if (!is_inline && !is_mutable)
-            explicit_length_offset = explicit_length_offset + ptr_size; // notInlineImmutable1.length;
-        else
-            explicit_length_offset = 0;
-        
-        if (explicit_length_offset)
-        {
-            explicit_length_offset = valobj_addr + explicit_length_offset;
-            explicit_length = process_sp->ReadUnsignedIntegerFromMemory(explicit_length_offset, 4, 0, error);
-        }
-    }
-    
-    if (strcmp(class_name,"NSString") &&
-        strcmp(class_name,"CFStringRef") &&
-        strcmp(class_name,"CFMutableStringRef") &&
-        strcmp(class_name,"__NSCFConstantString") &&
-        strcmp(class_name,"__NSCFString") &&
-        strcmp(class_name,"NSCFConstantString") &&
-        strcmp(class_name,"NSCFString") &&
-        strcmp(class_name,"NSPathStore2"))
-    {
-        // not one of us - but tell me class name
-        stream.Printf("class name = %s",class_name);
-        return true;
-    }
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(summary_options.GetLanguage()))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
-    options.SetPrefixToken(prefix);
-    options.SetSuffixToken(suffix);
-    
-    if (is_mutable)
-    {
-        uint64_t location = 2 * ptr_size + valobj_addr;
-        location = process_sp->ReadPointerFromMemory(location, error);
-        if (error.Fail())
-            return false;
-        if (has_explicit_length && is_unicode)
-        {
-            options.SetLocation(location);
-            options.SetProcessSP(process_sp);
-            options.SetStream(&stream);
-            options.SetQuote('"');
-            options.SetSourceSize(explicit_length);
-            options.SetNeedsZeroTermination(false);
-            options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
-            options.SetBinaryZeroIsTerminator(false);
-            options.SetLanguage(summary_options.GetLanguage());
-            return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
-        }
-        else
-        {
-            options.SetLocation(location+1);
-            options.SetProcessSP(process_sp);
-            options.SetStream(&stream);
-            options.SetSourceSize(explicit_length);
-            options.SetNeedsZeroTermination(false);
-            options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
-            options.SetBinaryZeroIsTerminator(false);
-            options.SetLanguage(summary_options.GetLanguage());
-            return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
-        }
-    }
-    else if (is_inline && has_explicit_length && !is_unicode && !is_path_store && !is_mutable)
-    {
-        uint64_t location = 3 * ptr_size + valobj_addr;
-        
-        options.SetLocation(location);
-        options.SetProcessSP(process_sp);
-        options.SetStream(&stream);
-        options.SetQuote('"');
-        options.SetSourceSize(explicit_length);
-        options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
-        options.SetLanguage(summary_options.GetLanguage());
-        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII> (options);
-    }
-    else if (is_unicode)
-    {
-        uint64_t location = valobj_addr + 2*ptr_size;
-        if (is_inline)
-        {
-            if (!has_explicit_length)
-            {
-                stream.Printf("found new combo");
-                return true;
-            }
-            else
-                location += ptr_size;
-        }
-        else
-        {
-            location = process_sp->ReadPointerFromMemory(location, error);
-            if (error.Fail())
-                return false;
-        }
-        options.SetLocation(location);
-        options.SetProcessSP(process_sp);
-        options.SetStream(&stream);
-        options.SetQuote('"');
-        options.SetSourceSize(explicit_length);
-        options.SetNeedsZeroTermination(has_explicit_length == false);
-        options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
-        options.SetBinaryZeroIsTerminator(has_explicit_length == false);
-        options.SetLanguage(summary_options.GetLanguage());
-        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options);
-    }
-    else if (is_path_store)
-    {
-        ProcessStructReader reader(valobj.GetProcessSP().get(), valobj.GetValueAsUnsigned(0), GetNSPathStore2Type(*valobj.GetTargetSP()));
-        explicit_length = reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20;
-        lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4;
-        
-        options.SetLocation(location);
-        options.SetProcessSP(process_sp);
-        options.SetStream(&stream);
-        options.SetQuote('"');
-        options.SetSourceSize(explicit_length);
-        options.SetNeedsZeroTermination(has_explicit_length == false);
-        options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
-        options.SetBinaryZeroIsTerminator(has_explicit_length == false);
-        options.SetLanguage(summary_options.GetLanguage());
-        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options);
-    }
-    else if (is_inline)
-    {
-        uint64_t location = valobj_addr + 2*ptr_size;
-        if (!has_explicit_length)
-        {
-            // in this kind of string, the byte before the string content is a length byte
-            // so let's try and use it to handle the embedded NUL case
-            Error error;
-            explicit_length = process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0, error);
-            if (error.Fail() || explicit_length == 0)
-                has_explicit_length = false;
-            else
-                has_explicit_length = true;
-            location++;
-        }
-        options.SetLocation(location);
-        options.SetProcessSP(process_sp);
-        options.SetStream(&stream);
-        options.SetSourceSize(explicit_length);
-        options.SetNeedsZeroTermination(!has_explicit_length);
-        options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
-        options.SetBinaryZeroIsTerminator(!has_explicit_length);
-        options.SetLanguage(summary_options.GetLanguage());
-        if (has_explicit_length)
-            return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
-        else
-            return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
-    }
-    else
-    {
-        uint64_t location = valobj_addr + 2*ptr_size;
-        location = process_sp->ReadPointerFromMemory(location, error);
-        if (error.Fail())
-            return false;
-        if (has_explicit_length && !has_null)
-            explicit_length++; // account for the fact that there is no NULL and we need to have one added
-        options.SetLocation(location);
-        options.SetProcessSP(process_sp);
-        options.SetStream(&stream);
-        options.SetSourceSize(explicit_length);
-        options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
-        options.SetLanguage(summary_options.GetLanguage());
-        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
-    }
-}
+bool lldb_private::formatters::NSStringSummaryProvider(
+    ValueObject &valobj, Stream &stream,
+    const TypeSummaryOptions &summary_options) {
+  static ConstString g_TypeHint("NSString");
 
-bool
-lldb_private::formatters::NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    TargetSP target_sp(valobj.GetTargetSP());
-    if (!target_sp)
-        return false;
-    uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
-    uint64_t pointer_value = valobj.GetValueAsUnsigned(0);
-    if (!pointer_value)
-        return false;
-    pointer_value += addr_size;
-    CompilerType type(valobj.GetCompilerType());
-    ExecutionContext exe_ctx(target_sp,false);
-    ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointer_value, exe_ctx, type));
-    if (!child_ptr_sp)
-        return false;
-    DataExtractor data;
-    Error error;
-    child_ptr_sp->GetData(data, error);
-    if (error.Fail())
-        return false;
-    ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData("string_data", data, exe_ctx, type));
-    child_sp->GetValueAsUnsigned(0);
-    if (child_sp)
-        return NSStringSummaryProvider(*child_sp, stream, options);
+  ProcessSP process_sp = valobj.GetProcessSP();
+  if (!process_sp)
     return false;
-}
 
-bool
-lldb_private::formatters::NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
-    return NSAttributedStringSummaryProvider(valobj, stream, options);
-}
+  ObjCLanguageRuntime *runtime =
+      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
+          lldb::eLanguageTypeObjC);
 
-bool
-lldb_private::formatters::NSTaggedString_SummaryProvider (ValueObject& valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream, const TypeSummaryOptions& summary_options)
-{
-    static ConstString g_TypeHint("NSString");
-    
-    if (!descriptor)
-        return false;
-    uint64_t len_bits = 0, data_bits = 0;
-    if (!descriptor->GetTaggedPointerInfo(&len_bits,&data_bits,nullptr))
-        return false;
-    
-    static const int g_MaxNonBitmaskedLen = 7; //TAGGED_STRING_UNPACKED_MAXLEN
-    static const int g_SixbitMaxLen = 9;
-    static const int g_fiveBitMaxLen = 11;
-    
-    static const char *sixBitToCharLookup = "eilotrm.apdnsIc ufkMShjTRxgC4013" "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
-    
-    if (len_bits > g_fiveBitMaxLen)
-        return false;
-    
-    std::string prefix,suffix;
-    if (Language* language = Language::FindPlugin(summary_options.GetLanguage()))
-    {
-        if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
-        {
-            prefix.clear();
-            suffix.clear();
-        }
-    }
-    
-    // this is a fairly ugly trick - pretend that the numeric value is actually a char*
-    // this works under a few assumptions:
-    // little endian architecture
-    // sizeof(uint64_t) > g_MaxNonBitmaskedLen
-    if (len_bits <= g_MaxNonBitmaskedLen)
-    {
-        stream.Printf("%s",prefix.c_str());
-        stream.Printf("\"%s\"",(const char*)&data_bits);
-        stream.Printf("%s",suffix.c_str());
-        return true;
-    }
-    
-    // if the data is bitmasked, we need to actually process the bytes
-    uint8_t bitmask = 0;
-    uint8_t shift_offset = 0;
-    
-    if (len_bits <= g_SixbitMaxLen)
-    {
-        bitmask = 0x03f;
-        shift_offset = 6;
-    }
+  if (!runtime)
+    return false;
+
+  ObjCLanguageRuntime::ClassDescriptorSP descriptor(
+      runtime->GetClassDescriptor(valobj));
+
+  if (!descriptor.get() || !descriptor->IsValid())
+    return false;
+
+  uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+  lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+  if (!valobj_addr)
+    return false;
+
+  ConstString class_name_cs = descriptor->GetClassName();
+  const char *class_name = class_name_cs.GetCString();
+
+  if (!class_name || !*class_name)
+    return false;
+
+  bool is_tagged_ptr = (0 == strcmp(class_name, "NSTaggedPointerString")) &&
+                       descriptor->GetTaggedPointerInfo();
+  // for a tagged pointer, the descriptor has everything we need
+  if (is_tagged_ptr)
+    return NSTaggedString_SummaryProvider(valobj, descriptor, stream,
+                                          summary_options);
+
+  auto &additionals_map(NSString_Additionals::GetAdditionalSummaries());
+  auto iter = additionals_map.find(class_name_cs), end = additionals_map.end();
+  if (iter != end)
+    return iter->second(valobj, stream, summary_options);
+
+  // if not a tagged pointer that we know about, try the normal route
+  uint64_t info_bits_location = valobj_addr + ptr_size;
+  if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
+    info_bits_location += 3;
+
+  Error error;
+
+  uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(
+      info_bits_location, 1, 0, error);
+  if (error.Fail())
+    return false;
+
+  bool is_mutable = (info_bits & 1) == 1;
+  bool is_inline = (info_bits & 0x60) == 0;
+  bool has_explicit_length = (info_bits & (1 | 4)) != 4;
+  bool is_unicode = (info_bits & 0x10) == 0x10;
+  bool is_path_store = strcmp(class_name, "NSPathStore2") == 0;
+  bool has_null = (info_bits & 8) == 8;
+
+  size_t explicit_length = 0;
+  if (!has_null && has_explicit_length && !is_path_store) {
+    lldb::addr_t explicit_length_offset = 2 * ptr_size;
+    if (is_mutable && !is_inline)
+      explicit_length_offset =
+          explicit_length_offset + ptr_size; //  notInlineMutable.length;
+    else if (is_inline)
+      explicit_length = explicit_length + 0; // inline1.length;
+    else if (!is_inline && !is_mutable)
+      explicit_length_offset =
+          explicit_length_offset + ptr_size; // notInlineImmutable1.length;
     else
-    {
-        bitmask = 0x01f;
-        shift_offset = 5;
+      explicit_length_offset = 0;
+
+    if (explicit_length_offset) {
+      explicit_length_offset = valobj_addr + explicit_length_offset;
+      explicit_length = process_sp->ReadUnsignedIntegerFromMemory(
+          explicit_length_offset, 4, 0, error);
     }
-    
-    std::vector<uint8_t> bytes;
-    bytes.resize(len_bits);
-    for (; len_bits > 0; data_bits >>= shift_offset, --len_bits)
-    {
-        uint8_t packed = data_bits & bitmask;
-        bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
-    }
-    
-    stream.Printf("%s",prefix.c_str());
-    stream.Printf("\"%s\"",&bytes[0]);
-    stream.Printf("%s",suffix.c_str());
+  }
+
+  if (strcmp(class_name, "NSString") && strcmp(class_name, "CFStringRef") &&
+      strcmp(class_name, "CFMutableStringRef") &&
+      strcmp(class_name, "__NSCFConstantString") &&
+      strcmp(class_name, "__NSCFString") &&
+      strcmp(class_name, "NSCFConstantString") &&
+      strcmp(class_name, "NSCFString") && strcmp(class_name, "NSPathStore2")) {
+    // not one of us - but tell me class name
+    stream.Printf("class name = %s", class_name);
     return true;
+  }
+
+  std::string prefix, suffix;
+  if (Language *language =
+          Language::FindPlugin(summary_options.GetLanguage())) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+  options.SetPrefixToken(prefix);
+  options.SetSuffixToken(suffix);
+
+  if (is_mutable) {
+    uint64_t location = 2 * ptr_size + valobj_addr;
+    location = process_sp->ReadPointerFromMemory(location, error);
+    if (error.Fail())
+      return false;
+    if (has_explicit_length && is_unicode) {
+      options.SetLocation(location);
+      options.SetProcessSP(process_sp);
+      options.SetStream(&stream);
+      options.SetQuote('"');
+      options.SetSourceSize(explicit_length);
+      options.SetNeedsZeroTermination(false);
+      options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+                                 TypeSummaryCapping::eTypeSummaryUncapped);
+      options.SetBinaryZeroIsTerminator(false);
+      options.SetLanguage(summary_options.GetLanguage());
+      return StringPrinter::ReadStringAndDumpToStream<
+          StringPrinter::StringElementType::UTF16>(options);
+    } else {
+      options.SetLocation(location + 1);
+      options.SetProcessSP(process_sp);
+      options.SetStream(&stream);
+      options.SetSourceSize(explicit_length);
+      options.SetNeedsZeroTermination(false);
+      options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+                                 TypeSummaryCapping::eTypeSummaryUncapped);
+      options.SetBinaryZeroIsTerminator(false);
+      options.SetLanguage(summary_options.GetLanguage());
+      return StringPrinter::ReadStringAndDumpToStream<
+          StringPrinter::StringElementType::ASCII>(options);
+    }
+  } else if (is_inline && has_explicit_length && !is_unicode &&
+             !is_path_store && !is_mutable) {
+    uint64_t location = 3 * ptr_size + valobj_addr;
+
+    options.SetLocation(location);
+    options.SetProcessSP(process_sp);
+    options.SetStream(&stream);
+    options.SetQuote('"');
+    options.SetSourceSize(explicit_length);
+    options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+                               TypeSummaryCapping::eTypeSummaryUncapped);
+    options.SetLanguage(summary_options.GetLanguage());
+    return StringPrinter::ReadStringAndDumpToStream<
+        StringPrinter::StringElementType::ASCII>(options);
+  } else if (is_unicode) {
+    uint64_t location = valobj_addr + 2 * ptr_size;
+    if (is_inline) {
+      if (!has_explicit_length) {
+        stream.Printf("found new combo");
+        return true;
+      } else
+        location += ptr_size;
+    } else {
+      location = process_sp->ReadPointerFromMemory(location, error);
+      if (error.Fail())
+        return false;
+    }
+    options.SetLocation(location);
+    options.SetProcessSP(process_sp);
+    options.SetStream(&stream);
+    options.SetQuote('"');
+    options.SetSourceSize(explicit_length);
+    options.SetNeedsZeroTermination(has_explicit_length == false);
+    options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+                               TypeSummaryCapping::eTypeSummaryUncapped);
+    options.SetBinaryZeroIsTerminator(has_explicit_length == false);
+    options.SetLanguage(summary_options.GetLanguage());
+    return StringPrinter::ReadStringAndDumpToStream<
+        StringPrinter::StringElementType::UTF16>(options);
+  } else if (is_path_store) {
+    ProcessStructReader reader(valobj.GetProcessSP().get(),
+                               valobj.GetValueAsUnsigned(0),
+                               GetNSPathStore2Type(*valobj.GetTargetSP()));
+    explicit_length =
+        reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20;
+    lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4;
+
+    options.SetLocation(location);
+    options.SetProcessSP(process_sp);
+    options.SetStream(&stream);
+    options.SetQuote('"');
+    options.SetSourceSize(explicit_length);
+    options.SetNeedsZeroTermination(has_explicit_length == false);
+    options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+                               TypeSummaryCapping::eTypeSummaryUncapped);
+    options.SetBinaryZeroIsTerminator(has_explicit_length == false);
+    options.SetLanguage(summary_options.GetLanguage());
+    return StringPrinter::ReadStringAndDumpToStream<
+        StringPrinter::StringElementType::UTF16>(options);
+  } else if (is_inline) {
+    uint64_t location = valobj_addr + 2 * ptr_size;
+    if (!has_explicit_length) {
+      // in this kind of string, the byte before the string content is a length
+      // byte
+      // so let's try and use it to handle the embedded NUL case
+      Error error;
+      explicit_length =
+          process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0, error);
+      if (error.Fail() || explicit_length == 0)
+        has_explicit_length = false;
+      else
+        has_explicit_length = true;
+      location++;
+    }
+    options.SetLocation(location);
+    options.SetProcessSP(process_sp);
+    options.SetStream(&stream);
+    options.SetSourceSize(explicit_length);
+    options.SetNeedsZeroTermination(!has_explicit_length);
+    options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+                               TypeSummaryCapping::eTypeSummaryUncapped);
+    options.SetBinaryZeroIsTerminator(!has_explicit_length);
+    options.SetLanguage(summary_options.GetLanguage());
+    if (has_explicit_length)
+      return StringPrinter::ReadStringAndDumpToStream<
+          StringPrinter::StringElementType::UTF8>(options);
+    else
+      return StringPrinter::ReadStringAndDumpToStream<
+          StringPrinter::StringElementType::ASCII>(options);
+  } else {
+    uint64_t location = valobj_addr + 2 * ptr_size;
+    location = process_sp->ReadPointerFromMemory(location, error);
+    if (error.Fail())
+      return false;
+    if (has_explicit_length && !has_null)
+      explicit_length++; // account for the fact that there is no NULL and we
+                         // need to have one added
+    options.SetLocation(location);
+    options.SetProcessSP(process_sp);
+    options.SetStream(&stream);
+    options.SetSourceSize(explicit_length);
+    options.SetIgnoreMaxLength(summary_options.GetCapping() ==
+                               TypeSummaryCapping::eTypeSummaryUncapped);
+    options.SetLanguage(summary_options.GetLanguage());
+    return StringPrinter::ReadStringAndDumpToStream<
+        StringPrinter::StringElementType::ASCII>(options);
+  }
+}
+
+bool lldb_private::formatters::NSAttributedStringSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  TargetSP target_sp(valobj.GetTargetSP());
+  if (!target_sp)
+    return false;
+  uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
+  uint64_t pointer_value = valobj.GetValueAsUnsigned(0);
+  if (!pointer_value)
+    return false;
+  pointer_value += addr_size;
+  CompilerType type(valobj.GetCompilerType());
+  ExecutionContext exe_ctx(target_sp, false);
+  ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress(
+      "string_ptr", pointer_value, exe_ctx, type));
+  if (!child_ptr_sp)
+    return false;
+  DataExtractor data;
+  Error error;
+  child_ptr_sp->GetData(data, error);
+  if (error.Fail())
+    return false;
+  ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData(
+      "string_data", data, exe_ctx, type));
+  child_sp->GetValueAsUnsigned(0);
+  if (child_sp)
+    return NSStringSummaryProvider(*child_sp, stream, options);
+  return false;
+}
+
+bool lldb_private::formatters::NSMutableAttributedStringSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  return NSAttributedStringSummaryProvider(valobj, stream, options);
+}
+
+bool lldb_private::formatters::NSTaggedString_SummaryProvider(
+    ValueObject &valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor,
+    Stream &stream, const TypeSummaryOptions &summary_options) {
+  static ConstString g_TypeHint("NSString");
+
+  if (!descriptor)
+    return false;
+  uint64_t len_bits = 0, data_bits = 0;
+  if (!descriptor->GetTaggedPointerInfo(&len_bits, &data_bits, nullptr))
+    return false;
+
+  static const int g_MaxNonBitmaskedLen = 7; // TAGGED_STRING_UNPACKED_MAXLEN
+  static const int g_SixbitMaxLen = 9;
+  static const int g_fiveBitMaxLen = 11;
+
+  static const char *sixBitToCharLookup = "eilotrm.apdnsIc ufkMShjTRxgC4013"
+                                          "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
+
+  if (len_bits > g_fiveBitMaxLen)
+    return false;
+
+  std::string prefix, suffix;
+  if (Language *language =
+          Language::FindPlugin(summary_options.GetLanguage())) {
+    if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
+                                            suffix)) {
+      prefix.clear();
+      suffix.clear();
+    }
+  }
+
+  // this is a fairly ugly trick - pretend that the numeric value is actually a
+  // char*
+  // this works under a few assumptions:
+  // little endian architecture
+  // sizeof(uint64_t) > g_MaxNonBitmaskedLen
+  if (len_bits <= g_MaxNonBitmaskedLen) {
+    stream.Printf("%s", prefix.c_str());
+    stream.Printf("\"%s\"", (const char *)&data_bits);
+    stream.Printf("%s", suffix.c_str());
+    return true;
+  }
+
+  // if the data is bitmasked, we need to actually process the bytes
+  uint8_t bitmask = 0;
+  uint8_t shift_offset = 0;
+
+  if (len_bits <= g_SixbitMaxLen) {
+    bitmask = 0x03f;
+    shift_offset = 6;
+  } else {
+    bitmask = 0x01f;
+    shift_offset = 5;
+  }
+
+  std::vector<uint8_t> bytes;
+  bytes.resize(len_bits);
+  for (; len_bits > 0; data_bits >>= shift_offset, --len_bits) {
+    uint8_t packed = data_bits & bitmask;
+    bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
+  }
+
+  stream.Printf("%s", prefix.c_str());
+  stream.Printf("\"%s\"", &bytes[0]);
+  stream.Printf("%s", suffix.c_str());
+  return true;
 }
diff --git a/lldb/source/Plugins/Language/ObjC/NSString.h b/lldb/source/Plugins/Language/ObjC/NSString.h
index 6a767a5..df8480a 100644
--- a/lldb/source/Plugins/Language/ObjC/NSString.h
+++ b/lldb/source/Plugins/Language/ObjC/NSString.h
@@ -1,4 +1,5 @@
-//===-- NSString.h ---------------------------------------------------*- C++ -*-===//
+//===-- NSString.h ---------------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -16,27 +17,26 @@
 #include "lldb/Target/ObjCLanguageRuntime.h"
 
 namespace lldb_private {
-    namespace formatters
-    {
-        bool
-        NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSTaggedString_SummaryProvider (ValueObject& valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream, const TypeSummaryOptions& summary_options);
-        
-        bool
-        NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        bool
-        NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-        
-        class NSString_Additionals
-        {
-        public:
-            static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
-            GetAdditionalSummaries ();
-        };
-    } // namespace formatters
+namespace formatters {
+bool NSStringSummaryProvider(ValueObject &valobj, Stream &stream,
+                             const TypeSummaryOptions &options);
+
+bool NSTaggedString_SummaryProvider(
+    ValueObject &valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor,
+    Stream &stream, const TypeSummaryOptions &summary_options);
+
+bool NSAttributedStringSummaryProvider(ValueObject &valobj, Stream &stream,
+                                       const TypeSummaryOptions &options);
+
+bool NSMutableAttributedStringSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options);
+
+class NSString_Additionals {
+public:
+  static std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
+  GetAdditionalSummaries();
+};
+} // namespace formatters
 } // namespace lldb_private
 
 #endif // liblldb_CF_h_
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 0ecbfd3..8955baa 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -21,10 +21,10 @@
 #include "lldb/Core/ValueObject.h"
 #include "lldb/DataFormatters/DataVisualization.h"
 #include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
 
 #include "CF.h"
 #include "Cocoa.h"
@@ -37,841 +37,1035 @@
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-void
-ObjCLanguage::Initialize()
-{
-    PluginManager::RegisterPlugin (GetPluginNameStatic(),
-                                   "Objective-C Language",
-                                   CreateInstance);
+void ObjCLanguage::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language",
+                                CreateInstance);
 }
 
-void
-ObjCLanguage::Terminate()
-{
-    PluginManager::UnregisterPlugin (CreateInstance);
+void ObjCLanguage::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
 }
 
-lldb_private::ConstString
-ObjCLanguage::GetPluginNameStatic()
-{
-    static ConstString g_name("objc");
-    return g_name;
+lldb_private::ConstString ObjCLanguage::GetPluginNameStatic() {
+  static ConstString g_name("objc");
+  return g_name;
 }
 
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
 
-lldb_private::ConstString
-ObjCLanguage::GetPluginName()
-{
-    return GetPluginNameStatic();
+lldb_private::ConstString ObjCLanguage::GetPluginName() {
+  return GetPluginNameStatic();
 }
 
-uint32_t
-ObjCLanguage::GetPluginVersion()
-{
-    return 1;
-}
+uint32_t ObjCLanguage::GetPluginVersion() { return 1; }
 
 //------------------------------------------------------------------
 // Static Functions
 //------------------------------------------------------------------
 
-Language *
-ObjCLanguage::CreateInstance (lldb::LanguageType language)
-{
-    switch (language)
-    {
-        case lldb::eLanguageTypeObjC:
-            return new ObjCLanguage();
-        default:
-            return nullptr;
+Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) {
+  switch (language) {
+  case lldb::eLanguageTypeObjC:
+    return new ObjCLanguage();
+  default:
+    return nullptr;
+  }
+}
+
+void ObjCLanguage::MethodName::Clear() {
+  m_full.Clear();
+  m_class.Clear();
+  m_category.Clear();
+  m_selector.Clear();
+  m_type = eTypeUnspecified;
+  m_category_is_valid = false;
+}
+
+bool ObjCLanguage::MethodName::SetName(const char *name, bool strict) {
+  Clear();
+  if (name && name[0]) {
+    // If "strict" is true. then the method must be specified with a
+    // '+' or '-' at the beginning. If "strict" is false, then the '+'
+    // or '-' can be omitted
+    bool valid_prefix = false;
+
+    if (name[0] == '+' || name[0] == '-') {
+      valid_prefix = name[1] == '[';
+      if (name[0] == '+')
+        m_type = eTypeClassMethod;
+      else
+        m_type = eTypeInstanceMethod;
+    } else if (!strict) {
+      // "strict" is false, the name just needs to start with '['
+      valid_prefix = name[0] == '[';
     }
-}
 
-void
-ObjCLanguage::MethodName::Clear()
-{
-    m_full.Clear();
-    m_class.Clear();
-    m_category.Clear();
-    m_selector.Clear();
-    m_type = eTypeUnspecified;
-    m_category_is_valid = false;
-}
-
-bool
-ObjCLanguage::MethodName::SetName (const char *name, bool strict)
-{
-    Clear();
-    if (name && name[0])
-    {
-        // If "strict" is true. then the method must be specified with a
-        // '+' or '-' at the beginning. If "strict" is false, then the '+'
-        // or '-' can be omitted
-        bool valid_prefix = false;
-        
-        if (name[0] == '+' || name[0] == '-')
-        {
-            valid_prefix = name[1] == '[';
-            if (name[0] == '+')
-                m_type = eTypeClassMethod;
-            else
-                m_type = eTypeInstanceMethod;
-        }
-        else if (!strict)
-        {
-            // "strict" is false, the name just needs to start with '['
-            valid_prefix = name[0] == '[';
-        }
-        
-        if (valid_prefix)
-        {
-            int name_len = strlen (name);
-            // Objective C methods must have at least:
-            //      "-[" or "+[" prefix
-            //      One character for a class name
-            //      One character for the space between the class name
-            //      One character for the method name
-            //      "]" suffix
-            if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']')
-            {
-                m_full.SetCStringWithLength(name, name_len);
-            }
-        }
+    if (valid_prefix) {
+      int name_len = strlen(name);
+      // Objective C methods must have at least:
+      //      "-[" or "+[" prefix
+      //      One character for a class name
+      //      One character for the space between the class name
+      //      One character for the method name
+      //      "]" suffix
+      if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']') {
+        m_full.SetCStringWithLength(name, name_len);
+      }
     }
-    return IsValid(strict);
+  }
+  return IsValid(strict);
 }
 
-const ConstString &
-ObjCLanguage::MethodName::GetClassName ()
-{
-    if (!m_class)
-    {
-        if (IsValid(false))
-        {
-            const char *full = m_full.GetCString();
-            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
-            const char *paren_pos = strchr (class_start, '(');
-            if (paren_pos)
-            {
-                m_class.SetCStringWithLength (class_start, paren_pos - class_start);
-            }
-            else
-            {
-                // No '(' was found in the full name, we can definitively say
-                // that our category was valid (and empty).
-                m_category_is_valid = true;
-                const char *space_pos = strchr (full, ' ');
-                if (space_pos)
-                {
-                    m_class.SetCStringWithLength (class_start, space_pos - class_start);
-                    if (!m_class_category)
-                    {
-                        // No category in name, so we can also fill in the m_class_category
-                        m_class_category = m_class;
-                    }
-                }
-            }
+const ConstString &ObjCLanguage::MethodName::GetClassName() {
+  if (!m_class) {
+    if (IsValid(false)) {
+      const char *full = m_full.GetCString();
+      const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+      const char *paren_pos = strchr(class_start, '(');
+      if (paren_pos) {
+        m_class.SetCStringWithLength(class_start, paren_pos - class_start);
+      } else {
+        // No '(' was found in the full name, we can definitively say
+        // that our category was valid (and empty).
+        m_category_is_valid = true;
+        const char *space_pos = strchr(full, ' ');
+        if (space_pos) {
+          m_class.SetCStringWithLength(class_start, space_pos - class_start);
+          if (!m_class_category) {
+            // No category in name, so we can also fill in the m_class_category
+            m_class_category = m_class;
+          }
         }
+      }
     }
-    return m_class;
+  }
+  return m_class;
 }
 
-const ConstString &
-ObjCLanguage::MethodName::GetClassNameWithCategory () 
-{
-    if (!m_class_category)
-    {
-        if (IsValid(false))
-        {
-            const char *full = m_full.GetCString();
-            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
-            const char *space_pos = strchr (full, ' ');
-            if (space_pos)
-            {
-                m_class_category.SetCStringWithLength (class_start, space_pos - class_start);
-                // If m_class hasn't been filled in and the class with category doesn't
-                // contain a '(', then we can also fill in the m_class
-                if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr)
-                {
-                    m_class = m_class_category;
-                    // No '(' was found in the full name, we can definitively say
-                    // that our category was valid (and empty).
-                    m_category_is_valid = true;
-
-                }
-            }
+const ConstString &ObjCLanguage::MethodName::GetClassNameWithCategory() {
+  if (!m_class_category) {
+    if (IsValid(false)) {
+      const char *full = m_full.GetCString();
+      const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+      const char *space_pos = strchr(full, ' ');
+      if (space_pos) {
+        m_class_category.SetCStringWithLength(class_start,
+                                              space_pos - class_start);
+        // If m_class hasn't been filled in and the class with category doesn't
+        // contain a '(', then we can also fill in the m_class
+        if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr) {
+          m_class = m_class_category;
+          // No '(' was found in the full name, we can definitively say
+          // that our category was valid (and empty).
+          m_category_is_valid = true;
         }
+      }
     }
-    return m_class_category;
+  }
+  return m_class_category;
 }
 
-const ConstString &
-ObjCLanguage::MethodName::GetSelector ()
-{
-    if (!m_selector)
-    {
-        if (IsValid(false))
-        {
-            const char *full = m_full.GetCString();
-            const char *space_pos = strchr (full, ' ');
-            if (space_pos)
-            {
-                ++space_pos; // skip the space
-                m_selector.SetCStringWithLength (space_pos, m_full.GetLength() - (space_pos - full) - 1);
-            }
-        }
+const ConstString &ObjCLanguage::MethodName::GetSelector() {
+  if (!m_selector) {
+    if (IsValid(false)) {
+      const char *full = m_full.GetCString();
+      const char *space_pos = strchr(full, ' ');
+      if (space_pos) {
+        ++space_pos; // skip the space
+        m_selector.SetCStringWithLength(space_pos, m_full.GetLength() -
+                                                       (space_pos - full) - 1);
+      }
     }
-    return m_selector;
+  }
+  return m_selector;
 }
 
-const ConstString &
-ObjCLanguage::MethodName::GetCategory ()
-{
-    if (!m_category_is_valid && !m_category)
-    {
-        if (IsValid(false))
-        {
-            m_category_is_valid = true;
-            const char *full = m_full.GetCString();
-            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
-            const char *open_paren_pos = strchr (class_start, '(');
-            if (open_paren_pos)
-            {
-                ++open_paren_pos; // Skip the open paren
-                const char *close_paren_pos = strchr (open_paren_pos, ')');
-                if (close_paren_pos)
-                    m_category.SetCStringWithLength (open_paren_pos, close_paren_pos - open_paren_pos);
-            }
-        }
+const ConstString &ObjCLanguage::MethodName::GetCategory() {
+  if (!m_category_is_valid && !m_category) {
+    if (IsValid(false)) {
+      m_category_is_valid = true;
+      const char *full = m_full.GetCString();
+      const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+      const char *open_paren_pos = strchr(class_start, '(');
+      if (open_paren_pos) {
+        ++open_paren_pos; // Skip the open paren
+        const char *close_paren_pos = strchr(open_paren_pos, ')');
+        if (close_paren_pos)
+          m_category.SetCStringWithLength(open_paren_pos,
+                                          close_paren_pos - open_paren_pos);
+      }
     }
-    return m_category;
+  }
+  return m_category;
 }
 
-ConstString
-ObjCLanguage::MethodName::GetFullNameWithoutCategory (bool empty_if_no_category)
-{
-    if (IsValid(false))
-    {
-        if (HasCategory())
-        {
-            StreamString strm;
-            if (m_type == eTypeClassMethod)
-                strm.PutChar('+');
-            else if (m_type == eTypeInstanceMethod)
-                strm.PutChar('-');
-            strm.Printf("[%s %s]", GetClassName().GetCString(), GetSelector().GetCString());
-            return ConstString(strm.GetString().c_str());
-        }
-        
-        if (!empty_if_no_category)
-        {
-            // Just return the full name since it doesn't have a category
-            return GetFullName();
-        }
+ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory(
+    bool empty_if_no_category) {
+  if (IsValid(false)) {
+    if (HasCategory()) {
+      StreamString strm;
+      if (m_type == eTypeClassMethod)
+        strm.PutChar('+');
+      else if (m_type == eTypeInstanceMethod)
+        strm.PutChar('-');
+      strm.Printf("[%s %s]", GetClassName().GetCString(),
+                  GetSelector().GetCString());
+      return ConstString(strm.GetString().c_str());
     }
-    return ConstString();
-}
 
-size_t
-ObjCLanguage::MethodName::GetFullNames (std::vector<ConstString> &names, bool append)
-{
-    if (!append)
-        names.clear();
-    if (IsValid(false))
-    {
-        StreamString strm;
-        const bool is_class_method = m_type == eTypeClassMethod;
-        const bool is_instance_method = m_type == eTypeInstanceMethod;
-        const ConstString &category = GetCategory();
-        if (is_class_method || is_instance_method)
-        {
-            names.push_back (m_full);
-            if (category)
-            {
-                strm.Printf("%c[%s %s]",
-                            is_class_method ? '+' : '-',
-                            GetClassName().GetCString(),
-                            GetSelector().GetCString());
-                names.push_back(ConstString(strm.GetString().c_str()));
-            }
-        }
-        else
-        {
-            const ConstString &class_name = GetClassName();
-            const ConstString &selector = GetSelector();
-            strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
-            names.push_back(ConstString(strm.GetString().c_str()));
-            strm.Clear();
-            strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
-            names.push_back(ConstString(strm.GetString().c_str()));
-            strm.Clear();
-            if (category)
-            {
-                strm.Printf("+[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
-                names.push_back(ConstString(strm.GetString().c_str()));
-                strm.Clear();
-                strm.Printf("-[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
-                names.push_back(ConstString(strm.GetString().c_str()));
-            }
-        }
+    if (!empty_if_no_category) {
+      // Just return the full name since it doesn't have a category
+      return GetFullName();
     }
-    return names.size();
+  }
+  return ConstString();
 }
 
-static void
-LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
-{
-    if (!objc_category_sp)
-        return;
-    
-    TypeSummaryImpl::Flags objc_flags;
-    objc_flags.SetCascades(false)
-    .SetSkipPointers(true)
-    .SetSkipReferences(true)
-    .SetDontShowChildren(true)
-    .SetDontShowValue(true)
-    .SetShowMembersOneLiner(false)
-    .SetHideItemNames(false);
-    
-    lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider,""));
-    objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"),
-                                                       ObjC_BOOL_summary);
-    objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"),
-                                                       ObjC_BOOL_summary);
-    objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"),
-                                                       ObjC_BOOL_summary);
-    
+size_t ObjCLanguage::MethodName::GetFullNames(std::vector<ConstString> &names,
+                                              bool append) {
+  if (!append)
+    names.clear();
+  if (IsValid(false)) {
+    StreamString strm;
+    const bool is_class_method = m_type == eTypeClassMethod;
+    const bool is_instance_method = m_type == eTypeInstanceMethod;
+    const ConstString &category = GetCategory();
+    if (is_class_method || is_instance_method) {
+      names.push_back(m_full);
+      if (category) {
+        strm.Printf("%c[%s %s]", is_class_method ? '+' : '-',
+                    GetClassName().GetCString(), GetSelector().GetCString());
+        names.push_back(ConstString(strm.GetString().c_str()));
+      }
+    } else {
+      const ConstString &class_name = GetClassName();
+      const ConstString &selector = GetSelector();
+      strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
+      names.push_back(ConstString(strm.GetString().c_str()));
+      strm.Clear();
+      strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
+      names.push_back(ConstString(strm.GetString().c_str()));
+      strm.Clear();
+      if (category) {
+        strm.Printf("+[%s(%s) %s]", class_name.GetCString(),
+                    category.GetCString(), selector.GetCString());
+        names.push_back(ConstString(strm.GetString().c_str()));
+        strm.Clear();
+        strm.Printf("-[%s(%s) %s]", class_name.GetCString(),
+                    category.GetCString(), selector.GetCString());
+        names.push_back(ConstString(strm.GetString().c_str()));
+      }
+    }
+  }
+  return names.size();
+}
+
+static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
+  if (!objc_category_sp)
+    return;
+
+  TypeSummaryImpl::Flags objc_flags;
+  objc_flags.SetCascades(false)
+      .SetSkipPointers(true)
+      .SetSkipReferences(true)
+      .SetDontShowChildren(true)
+      .SetDontShowValue(true)
+      .SetShowMembersOneLiner(false)
+      .SetHideItemNames(false);
+
+  lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(
+      objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider, ""));
+  objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"),
+                                                     ObjC_BOOL_summary);
+  objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"),
+                                                     ObjC_BOOL_summary);
+  objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"),
+                                                     ObjC_BOOL_summary);
+
 #ifndef LLDB_DISABLE_PYTHON
-    // we need to skip pointers here since we are special casing a SEL* when retrieving its value
-    objc_flags.SetSkipPointers(true);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("SEL"), objc_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("objc_selector"), objc_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("objc_selector *"), objc_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("SEL *"), objc_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCClassSummaryProvider, "Class summary provider", ConstString("Class"), objc_flags);
-    
-    SyntheticChildren::Flags class_synth_flags;
-    class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
-    
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::ObjCClassSyntheticFrontEndCreator, "Class synthetic children", ConstString("Class"), class_synth_flags);
+  // we need to skip pointers here since we are special casing a SEL* when
+  // retrieving its value
+  objc_flags.SetSkipPointers(true);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::ObjCSELSummaryProvider<false>,
+                "SEL summary provider", ConstString("SEL"), objc_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
+      "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
+      "SEL summary provider", ConstString("objc_selector"), objc_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>,
+      "SEL summary provider", ConstString("objc_selector *"), objc_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::ObjCSELSummaryProvider<true>,
+                "SEL summary provider", ConstString("SEL *"), objc_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::ObjCClassSummaryProvider,
+                "Class summary provider", ConstString("Class"), objc_flags);
+
+  SyntheticChildren::Flags class_synth_flags;
+  class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
+      false);
+
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::ObjCClassSyntheticFrontEndCreator,
+                  "Class synthetic children", ConstString("Class"),
+                  class_synth_flags);
 #endif // LLDB_DISABLE_PYTHON
-    
-    objc_flags.SetSkipPointers(false);
-    objc_flags.SetCascades(true);
-    objc_flags.SetSkipReferences(false);
-    
-    AddStringSummary (objc_category_sp,
-                      "${var.__FuncPtr%A}",
-                      ConstString("__block_literal_generic"),
-                      objc_flags);
-    
-    AddStringSummary(objc_category_sp,
-                     "${var.years} years, ${var.months} months, ${var.days} days, ${var.hours} hours, ${var.minutes} minutes ${var.seconds} seconds",
-                     ConstString("CFGregorianUnits"),
-                     objc_flags);
-    AddStringSummary(objc_category_sp,
-                     "location=${var.location} length=${var.length}",
-                     ConstString("CFRange"),
-                     objc_flags);
-    
-    AddStringSummary(objc_category_sp,
-                     "location=${var.location}, length=${var.length}",
-                     ConstString("NSRange"),
-                     objc_flags);
-    AddStringSummary(objc_category_sp,
-                     "(${var.origin}, ${var.size}), ...",
-                     ConstString("NSRectArray"),
-                     objc_flags);
-    
-    AddOneLineSummary (objc_category_sp,
-                       ConstString("NSPoint"),
-                       objc_flags);
-    AddOneLineSummary (objc_category_sp,
-                       ConstString("NSSize"),
-                       objc_flags);
-    AddOneLineSummary (objc_category_sp,
-                       ConstString("NSRect"),
-                       objc_flags);
-    
-    AddOneLineSummary (objc_category_sp,
-                       ConstString("CGSize"),
-                       objc_flags);
-    AddOneLineSummary (objc_category_sp,
-                       ConstString("CGPoint"),
-                       objc_flags);
-    AddOneLineSummary (objc_category_sp,
-                       ConstString("CGRect"),
-                       objc_flags);
-    
-    AddStringSummary(objc_category_sp,
-                     "red=${var.red} green=${var.green} blue=${var.blue}",
-                     ConstString("RGBColor"),
-                     objc_flags);
-    AddStringSummary(objc_category_sp,
-                     "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
-                     ConstString("Rect"),
-                     objc_flags);
-    AddStringSummary(objc_category_sp,
-                     "{(v=${var.v}, h=${var.h})}",
-                     ConstString("Point"),
-                     objc_flags);
-    AddStringSummary(objc_category_sp,
-                     "${var.month}/${var.day}/${var.year}  ${var.hour} :${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
-                     ConstString("DateTimeRect *"),
-                     objc_flags);
-    AddStringSummary(objc_category_sp,
-                     "${var.ld.month}/${var.ld.day}/${var.ld.year} ${var.ld.hour} :${var.ld.minute} :${var.ld.second} dayOfWeek:${var.ld.dayOfWeek}",
-                     ConstString("LongDateRect"),
-                     objc_flags);
-    AddStringSummary(objc_category_sp,
-                     "(x=${var.x}, y=${var.y})",
-                     ConstString("HIPoint"),
-                     objc_flags);
-    AddStringSummary(objc_category_sp,
-                     "origin=${var.origin} size=${var.size}",
-                     ConstString("HIRect"),
-                     objc_flags);
-    
-    TypeSummaryImpl::Flags appkit_flags;
-    appkit_flags.SetCascades(true)
-    .SetSkipPointers(false)
-    .SetSkipReferences(false)
-    .SetDontShowChildren(true)
-    .SetDontShowValue(false)
-    .SetShowMembersOneLiner(false)
-    .SetHideItemNames(false);
-    
-    appkit_flags.SetDontShowChildren(false);
-    
+
+  objc_flags.SetSkipPointers(false);
+  objc_flags.SetCascades(true);
+  objc_flags.SetSkipReferences(false);
+
+  AddStringSummary(objc_category_sp, "${var.__FuncPtr%A}",
+                   ConstString("__block_literal_generic"), objc_flags);
+
+  AddStringSummary(objc_category_sp, "${var.years} years, ${var.months} "
+                                     "months, ${var.days} days, ${var.hours} "
+                                     "hours, ${var.minutes} minutes "
+                                     "${var.seconds} seconds",
+                   ConstString("CFGregorianUnits"), objc_flags);
+  AddStringSummary(objc_category_sp,
+                   "location=${var.location} length=${var.length}",
+                   ConstString("CFRange"), objc_flags);
+
+  AddStringSummary(objc_category_sp,
+                   "location=${var.location}, length=${var.length}",
+                   ConstString("NSRange"), objc_flags);
+  AddStringSummary(objc_category_sp, "(${var.origin}, ${var.size}), ...",
+                   ConstString("NSRectArray"), objc_flags);
+
+  AddOneLineSummary(objc_category_sp, ConstString("NSPoint"), objc_flags);
+  AddOneLineSummary(objc_category_sp, ConstString("NSSize"), objc_flags);
+  AddOneLineSummary(objc_category_sp, ConstString("NSRect"), objc_flags);
+
+  AddOneLineSummary(objc_category_sp, ConstString("CGSize"), objc_flags);
+  AddOneLineSummary(objc_category_sp, ConstString("CGPoint"), objc_flags);
+  AddOneLineSummary(objc_category_sp, ConstString("CGRect"), objc_flags);
+
+  AddStringSummary(objc_category_sp,
+                   "red=${var.red} green=${var.green} blue=${var.blue}",
+                   ConstString("RGBColor"), objc_flags);
+  AddStringSummary(
+      objc_category_sp,
+      "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
+      ConstString("Rect"), objc_flags);
+  AddStringSummary(objc_category_sp, "{(v=${var.v}, h=${var.h})}",
+                   ConstString("Point"), objc_flags);
+  AddStringSummary(objc_category_sp,
+                   "${var.month}/${var.day}/${var.year}  ${var.hour} "
+                   ":${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
+                   ConstString("DateTimeRect *"), objc_flags);
+  AddStringSummary(objc_category_sp, "${var.ld.month}/${var.ld.day}/"
+                                     "${var.ld.year} ${var.ld.hour} "
+                                     ":${var.ld.minute} :${var.ld.second} "
+                                     "dayOfWeek:${var.ld.dayOfWeek}",
+                   ConstString("LongDateRect"), objc_flags);
+  AddStringSummary(objc_category_sp, "(x=${var.x}, y=${var.y})",
+                   ConstString("HIPoint"), objc_flags);
+  AddStringSummary(objc_category_sp, "origin=${var.origin} size=${var.size}",
+                   ConstString("HIRect"), objc_flags);
+
+  TypeSummaryImpl::Flags appkit_flags;
+  appkit_flags.SetCascades(true)
+      .SetSkipPointers(false)
+      .SetSkipReferences(false)
+      .SetDontShowChildren(true)
+      .SetDontShowValue(false)
+      .SetShowMembersOneLiner(false)
+      .SetHideItemNames(false);
+
+  appkit_flags.SetDontShowChildren(false);
+
 #ifndef LLDB_DISABLE_PYTHON
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArray0"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSSingleObjectArrayI"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSMutableDictionary"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSSingleEntryDictionaryI"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSSet summary", ConstString("NSSet"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSError_SummaryProvider, "NSError summary provider", ConstString("NSError"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSException_SummaryProvider, "NSException summary provider", ConstString("NSException"), appkit_flags);
-    
-    // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", ConstString("$_lldb_typegen_nspair"), appkit_flags);
-    
-    appkit_flags.SetDontShowChildren(true);
-    
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayI"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArray0"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSSingleObjectArrayI"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSArray"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("CFMutableArrayRef"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("CFArrayRef"), ScriptedSyntheticChildren::Flags());
-    
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryM"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryI"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSSingleEntryDictionaryI"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSCFDictionary"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSDictionary"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSMutableDictionary"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFDictionaryRef"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), ScriptedSyntheticChildren::Flags());
-    
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSErrorSyntheticFrontEndCreator, "NSError synthetic children", ConstString("NSError"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSExceptionSyntheticFrontEndCreator, "NSException synthetic children", ConstString("NSException"), ScriptedSyntheticChildren::Flags());
-    
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("NSSet"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSSetI synthetic children", ConstString("__NSSetI"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSSetM synthetic children", ConstString("__NSSetM"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSMutableSet synthetic children", ConstString("NSMutableSet"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSOrderedSet synthetic children", ConstString("NSOrderedSet"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"), ScriptedSyntheticChildren::Flags());
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), ScriptedSyntheticChildren::Flags());
-    
-    AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, "NSIndexPath synthetic children", ConstString("NSIndexPath"), ScriptedSyntheticChildren::Flags());
-    
-    AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFBagRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("__CFBag"), appkit_flags);
-    AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("const struct __CFBag"), appkit_flags);
-    AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__CFString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSMutableString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSTaggedPointerString"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSAttributedStringSummaryProvider, "NSAttributedString summary provider", ConstString("NSAttributedString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSMutableAttributedString"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSConcreteMutableAttributedString"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider, "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("_NSInlineData"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider, "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSNotification"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSConcreteNotification"), appkit_flags);
-        
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("NSURL"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("NSDate"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("CFTimeZoneRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
-    
-    // CFAbsoluteTime is actually a double rather than a pointer to an object
-    // we do not care about the numeric value, since it is probably meaningless to users
-    appkit_flags.SetDontShowValue(true);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::CFAbsoluteTimeSummaryProvider, "CFAbsoluteTime summary provider", ConstString("CFAbsoluteTime"), appkit_flags);
-    appkit_flags.SetDontShowValue(false);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, "NSIndexSet summary provider", ConstString("NSMutableIndexSet"), appkit_flags);
-    
-    AddStringSummary(objc_category_sp,
-                     "@\"${var.month%d}/${var.day%d}/${var.year%d} ${var.hour%d}:${var.minute%d}:${var.second}\"",
-                     ConstString("CFGregorianDate"),
-                     appkit_flags);
-    
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("CFBitVectorRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("CFMutableBitVectorRef"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("__CFBitVector"), appkit_flags);
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("__CFMutableBitVector"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+      "NSArray summary provider", ConstString("NSArray"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+      "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+      "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+      "NSArray summary provider", ConstString("__NSArray0"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSArraySummaryProvider,
+                "NSArray summary provider",
+                ConstString("__NSSingleObjectArrayI"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+      "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+      "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+      "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSArraySummaryProvider,
+                "NSArray summary provider", ConstString("CFMutableArrayRef"),
+                appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDictionarySummaryProvider<false>,
+                "NSDictionary summary provider", ConstString("NSDictionary"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDictionarySummaryProvider<false>,
+                "NSDictionary summary provider",
+                ConstString("NSMutableDictionary"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDictionarySummaryProvider<false>,
+                "NSDictionary summary provider",
+                ConstString("__NSCFDictionary"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDictionarySummaryProvider<false>,
+                "NSDictionary summary provider", ConstString("__NSDictionaryI"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDictionarySummaryProvider<false>,
+                "NSDictionary summary provider",
+                ConstString("__NSSingleEntryDictionaryI"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDictionarySummaryProvider<false>,
+                "NSDictionary summary provider", ConstString("__NSDictionaryM"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDictionarySummaryProvider<true>,
+                "NSDictionary summary provider", ConstString("CFDictionaryRef"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDictionarySummaryProvider<true>,
+                "NSDictionary summary provider",
+                ConstString("CFMutableDictionaryRef"), appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSSetSummaryProvider<false>,
+                "NSSet summary", ConstString("NSSet"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+      "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSSetSummaryProvider<true>,
+                "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>,
+      "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSSetSummaryProvider<false>,
+                "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSSetSummaryProvider<false>,
+                "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSSetSummaryProvider<false>,
+                "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+      "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+      "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+      "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+      "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
+      "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags);
+
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSError_SummaryProvider,
+      "NSError summary provider", ConstString("NSError"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSException_SummaryProvider,
+      "NSException summary provider", ConstString("NSException"), appkit_flags);
+
+  // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}",
+  // ConstString("$_lldb_typegen_nspair"), appkit_flags);
+
+  appkit_flags.SetDontShowChildren(true);
+
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children", ConstString("__NSArrayM"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children", ConstString("__NSArrayI"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children", ConstString("__NSArray0"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children",
+                  ConstString("__NSSingleObjectArrayI"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children", ConstString("NSArray"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children", ConstString("NSMutableArray"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children", ConstString("__NSCFArray"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children",
+                  ConstString("CFMutableArrayRef"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+                  "NSArray synthetic children", ConstString("CFArrayRef"),
+                  ScriptedSyntheticChildren::Flags());
+
+  AddCXXSynthetic(
+      objc_category_sp,
+      lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+      "NSDictionary synthetic children", ConstString("__NSDictionaryM"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp,
+      lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+      "NSDictionary synthetic children", ConstString("__NSDictionaryI"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp,
+      lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+      "NSDictionary synthetic children",
+      ConstString("__NSSingleEntryDictionaryI"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp,
+      lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+      "NSDictionary synthetic children", ConstString("__NSCFDictionary"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp,
+      lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+      "NSDictionary synthetic children", ConstString("NSDictionary"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp,
+      lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+      "NSDictionary synthetic children", ConstString("NSMutableDictionary"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp,
+      lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+      "NSDictionary synthetic children", ConstString("CFDictionaryRef"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp,
+      lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
+      "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"),
+      ScriptedSyntheticChildren::Flags());
+
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSErrorSyntheticFrontEndCreator,
+                  "NSError synthetic children", ConstString("NSError"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSExceptionSyntheticFrontEndCreator,
+                  "NSException synthetic children", ConstString("NSException"),
+                  ScriptedSyntheticChildren::Flags());
+
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+                  "NSSet synthetic children", ConstString("NSSet"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+                  "__NSSetI synthetic children", ConstString("__NSSetI"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+                  "__NSSetM synthetic children", ConstString("__NSSetM"),
+                  ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+      "NSMutableSet synthetic children", ConstString("NSMutableSet"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+      "NSOrderedSet synthetic children", ConstString("NSOrderedSet"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+      "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"),
+      ScriptedSyntheticChildren::Flags());
+  AddCXXSynthetic(
+      objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
+      "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"),
+      ScriptedSyntheticChildren::Flags());
+
+  AddCXXSynthetic(objc_category_sp,
+                  lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator,
+                  "NSIndexPath synthetic children", ConstString("NSIndexPath"),
+                  ScriptedSyntheticChildren::Flags());
+
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
+      "CFBag summary provider", ConstString("CFBagRef"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFBagSummaryProvider,
+                "CFBag summary provider", ConstString("__CFBag"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFBagSummaryProvider,
+                "CFBag summary provider", ConstString("const struct __CFBag"),
+                appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
+      "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFBinaryHeapSummaryProvider,
+                "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFBinaryHeapSummaryProvider,
+                "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"),
+                appkit_flags);
+
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+      "NSString summary provider", ConstString("NSString"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+      "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+      "NSString summary provider", ConstString("__CFString"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSStringSummaryProvider,
+                "NSString summary provider", ConstString("CFMutableStringRef"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSStringSummaryProvider,
+                "NSString summary provider", ConstString("NSMutableString"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSStringSummaryProvider,
+                "NSString summary provider",
+                ConstString("__NSCFConstantString"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+      "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSStringSummaryProvider,
+                "NSString summary provider", ConstString("NSCFConstantString"),
+                appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+      "NSString summary provider", ConstString("NSCFString"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
+      "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSStringSummaryProvider,
+                "NSString summary provider",
+                ConstString("NSTaggedPointerString"), appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSAttributedStringSummaryProvider,
+                "NSAttributedString summary provider",
+                ConstString("NSAttributedString"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp,
+      lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
+      "NSMutableAttributedString summary provider",
+      ConstString("NSMutableAttributedString"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp,
+      lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
+      "NSMutableAttributedString summary provider",
+      ConstString("NSConcreteMutableAttributedString"), appkit_flags);
+
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider,
+      "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDataSummaryProvider<false>,
+                "NSData summary provider", ConstString("NSData"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
+      "NSData summary provider", ConstString("_NSInlineData"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
+      "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDataSummaryProvider<false>,
+                "NSData summary provider", ConstString("NSConcreteMutableData"),
+                appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
+      "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
+      "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
+      "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
+      "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
+
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider,
+      "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSNotificationSummaryProvider,
+                "NSNotification summary provider",
+                ConstString("NSNotification"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSNotificationSummaryProvider,
+                "NSNotification summary provider",
+                ConstString("NSConcreteNotification"), appkit_flags);
+
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+      "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+      "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+      "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+      "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+      "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
+      "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSURLSummaryProvider,
+                "NSURL summary provider", ConstString("NSURL"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSURLSummaryProvider,
+      "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSDateSummaryProvider,
+                "NSDate summary provider", ConstString("NSDate"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
+      "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
+      "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
+      "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
+
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
+      "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSTimeZoneSummaryProvider,
+                "NSTimeZone summary provider", ConstString("CFTimeZoneRef"),
+                appkit_flags);
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
+      "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
+
+  // CFAbsoluteTime is actually a double rather than a pointer to an object
+  // we do not care about the numeric value, since it is probably meaningless to
+  // users
+  appkit_flags.SetDontShowValue(true);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFAbsoluteTimeSummaryProvider,
+                "CFAbsoluteTime summary provider",
+                ConstString("CFAbsoluteTime"), appkit_flags);
+  appkit_flags.SetDontShowValue(false);
+
+  AddCXXSummary(
+      objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider,
+      "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSIndexSetSummaryProvider,
+                "NSIndexSet summary provider", ConstString("NSMutableIndexSet"),
+                appkit_flags);
+
+  AddStringSummary(objc_category_sp,
+                   "@\"${var.month%d}/${var.day%d}/${var.year%d} "
+                   "${var.hour%d}:${var.minute%d}:${var.second}\"",
+                   ConstString("CFGregorianDate"), appkit_flags);
+
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFBitVectorSummaryProvider,
+                "CFBitVector summary provider", ConstString("CFBitVectorRef"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFBitVectorSummaryProvider,
+                "CFBitVector summary provider",
+                ConstString("CFMutableBitVectorRef"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFBitVectorSummaryProvider,
+                "CFBitVector summary provider", ConstString("__CFBitVector"),
+                appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CFBitVectorSummaryProvider,
+                "CFBitVector summary provider",
+                ConstString("__CFMutableBitVector"), appkit_flags);
 #endif // LLDB_DISABLE_PYTHON
 }
 
-static void
-LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp)
-{
-    if (!objc_category_sp)
-        return;
+static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) {
+  if (!objc_category_sp)
+    return;
 
-    TypeSummaryImpl::Flags cm_flags;
-    cm_flags.SetCascades(true)
-    .SetDontShowChildren(false)
-    .SetDontShowValue(false)
-    .SetHideItemNames(false)
-    .SetShowMembersOneLiner(false)
-    .SetSkipPointers(false)
-    .SetSkipReferences(false);
-    
+  TypeSummaryImpl::Flags cm_flags;
+  cm_flags.SetCascades(true)
+      .SetDontShowChildren(false)
+      .SetDontShowValue(false)
+      .SetHideItemNames(false)
+      .SetShowMembersOneLiner(false)
+      .SetSkipPointers(false)
+      .SetSkipReferences(false);
+
 #ifndef LLDB_DISABLE_PYTHON
-    AddCXXSummary(objc_category_sp, lldb_private::formatters::CMTimeSummaryProvider, "CMTime summary provider", ConstString("CMTime"), cm_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::CMTimeSummaryProvider,
+                "CMTime summary provider", ConstString("CMTime"), cm_flags);
 #endif // LLDB_DISABLE_PYTHON
 }
 
-lldb::TypeCategoryImplSP
-ObjCLanguage::GetFormatters ()
-{
-    static std::once_flag g_initialize;
-    static TypeCategoryImplSP g_category;
-    
-    std::call_once(g_initialize, [this] () -> void {
-        DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
-        if (g_category)
-        {
-            LoadCoreMediaFormatters(g_category);
-            LoadObjCFormatters(g_category);
-        }
-    });
-    return g_category;
+lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() {
+  static std::once_flag g_initialize;
+  static TypeCategoryImplSP g_category;
+
+  std::call_once(g_initialize, [this]() -> void {
+    DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
+    if (g_category) {
+      LoadCoreMediaFormatters(g_category);
+      LoadObjCFormatters(g_category);
+    }
+  });
+  return g_category;
 }
 
 std::vector<ConstString>
-ObjCLanguage::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
-{
-    std::vector<ConstString> result;
-    
-    if (use_dynamic == lldb::eNoDynamicValues)
-        return result;
-    
-    CompilerType compiler_type(valobj.GetCompilerType());
-    
-    const bool check_cpp = false;
-    const bool check_objc = true;
-    bool canBeObjCDynamic = compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
-    
-    if (canBeObjCDynamic)
-    {
-        do {
-            lldb::ProcessSP process_sp = valobj.GetProcessSP();
-            if (!process_sp)
-                break;
-            ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
-            if (runtime == nullptr)
-                break;
-            ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj));
-            if (!objc_class_sp)
-                break;
-            if (ConstString name = objc_class_sp->GetClassName())
-                result.push_back(name);
-        } while (false);
-    }
-    
+ObjCLanguage::GetPossibleFormattersMatches(ValueObject &valobj,
+                                           lldb::DynamicValueType use_dynamic) {
+  std::vector<ConstString> result;
+
+  if (use_dynamic == lldb::eNoDynamicValues)
     return result;
+
+  CompilerType compiler_type(valobj.GetCompilerType());
+
+  const bool check_cpp = false;
+  const bool check_objc = true;
+  bool canBeObjCDynamic =
+      compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
+
+  if (canBeObjCDynamic) {
+    do {
+      lldb::ProcessSP process_sp = valobj.GetProcessSP();
+      if (!process_sp)
+        break;
+      ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
+      if (runtime == nullptr)
+        break;
+      ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp(
+          runtime->GetClassDescriptor(valobj));
+      if (!objc_class_sp)
+        break;
+      if (ConstString name = objc_class_sp->GetClassName())
+        result.push_back(name);
+    } while (false);
+  }
+
+  return result;
 }
 
-std::unique_ptr<Language::TypeScavenger>
-ObjCLanguage::GetTypeScavenger ()
-{
-    class ObjCTypeScavenger : public Language::TypeScavenger
-    {
-    private:
-        class ObjCScavengerResult : public Language::TypeScavenger::Result
-        {
-        public:
-            ObjCScavengerResult (CompilerType type) :
-                Language::TypeScavenger::Result(),
-                m_compiler_type(type)
-            {
-            }
-            
-            bool
-            IsValid () override
-            {
-                return m_compiler_type.IsValid();
-            }
-            
-            bool
-            DumpToStream (Stream& stream,
-                          bool print_help_if_available) override
-            {
-                if (IsValid())
-                {
-                    m_compiler_type.DumpTypeDescription(&stream);
-                    stream.EOL();
-                    return true;
-                }
-                return false;
-            }
+std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {
+  class ObjCTypeScavenger : public Language::TypeScavenger {
+  private:
+    class ObjCScavengerResult : public Language::TypeScavenger::Result {
+    public:
+      ObjCScavengerResult(CompilerType type)
+          : Language::TypeScavenger::Result(), m_compiler_type(type) {}
 
-            ~ObjCScavengerResult() override = default;
+      bool IsValid() override { return m_compiler_type.IsValid(); }
 
-        private:
-            CompilerType m_compiler_type;
-        };
-        
-    protected:
-        ObjCTypeScavenger() = default;
-        
-        ~ObjCTypeScavenger() override = default;
-        
-        bool
-        Find_Impl (ExecutionContextScope *exe_scope,
-                   const char *key,
-                   ResultSet &results) override
-        {
-            bool result = false;
-            
-            Target* target = exe_scope->CalculateTarget().get();
-            if (target)
-            {
-                if (auto clang_modules_decl_vendor = target->GetClangModulesDeclVendor())
-                {
-                    std::vector <clang::NamedDecl*> decls;
-                    ConstString key_cs(key);
-                    
-                    if (clang_modules_decl_vendor->FindDecls(key_cs, false, UINT32_MAX, decls) > 0 &&
-                        !decls.empty())
-                    {
-                        CompilerType module_type = ClangASTContext::GetTypeForDecl(decls.front());
-                        result = true;
-                        std::unique_ptr<Language::TypeScavenger::Result> result(new ObjCScavengerResult(module_type));
-                        results.insert(std::move(result));
-                    }
-                }
-            }
-            
-            if (!result)
-            {
-                Process* process = exe_scope->CalculateProcess().get();
-                if (process)
-                {
-                    const bool create_on_demand = false;
-                    auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
-                    if (objc_runtime)
-                    {
-                        auto decl_vendor = objc_runtime->GetDeclVendor();
-                        if (decl_vendor)
-                        {
-                            std::vector<clang::NamedDecl *> decls;
-                            ConstString name(key);
-                            decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
-                            for (auto decl : decls)
-                            {
-                                if (decl)
-                                {
-                                    if (CompilerType candidate = ClangASTContext::GetTypeForDecl(decl))
-                                    {
-                                        result = true;
-                                        std::unique_ptr<Language::TypeScavenger::Result> result(new ObjCScavengerResult(candidate));
-                                        results.insert(std::move(result));
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            return result;
+      bool DumpToStream(Stream &stream, bool print_help_if_available) override {
+        if (IsValid()) {
+          m_compiler_type.DumpTypeDescription(&stream);
+          stream.EOL();
+          return true;
         }
+        return false;
+      }
 
-        friend class lldb_private::ObjCLanguage;
+      ~ObjCScavengerResult() override = default;
+
+    private:
+      CompilerType m_compiler_type;
     };
-    
-    return std::unique_ptr<TypeScavenger>(new ObjCTypeScavenger());
+
+  protected:
+    ObjCTypeScavenger() = default;
+
+    ~ObjCTypeScavenger() override = default;
+
+    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+                   ResultSet &results) override {
+      bool result = false;
+
+      Target *target = exe_scope->CalculateTarget().get();
+      if (target) {
+        if (auto clang_modules_decl_vendor =
+                target->GetClangModulesDeclVendor()) {
+          std::vector<clang::NamedDecl *> decls;
+          ConstString key_cs(key);
+
+          if (clang_modules_decl_vendor->FindDecls(key_cs, false, UINT32_MAX,
+                                                   decls) > 0 &&
+              !decls.empty()) {
+            CompilerType module_type =
+                ClangASTContext::GetTypeForDecl(decls.front());
+            result = true;
+            std::unique_ptr<Language::TypeScavenger::Result> result(
+                new ObjCScavengerResult(module_type));
+            results.insert(std::move(result));
+          }
+        }
+      }
+
+      if (!result) {
+        Process *process = exe_scope->CalculateProcess().get();
+        if (process) {
+          const bool create_on_demand = false;
+          auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
+          if (objc_runtime) {
+            auto decl_vendor = objc_runtime->GetDeclVendor();
+            if (decl_vendor) {
+              std::vector<clang::NamedDecl *> decls;
+              ConstString name(key);
+              decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
+              for (auto decl : decls) {
+                if (decl) {
+                  if (CompilerType candidate =
+                          ClangASTContext::GetTypeForDecl(decl)) {
+                    result = true;
+                    std::unique_ptr<Language::TypeScavenger::Result> result(
+                        new ObjCScavengerResult(candidate));
+                    results.insert(std::move(result));
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return result;
+    }
+
+    friend class lldb_private::ObjCLanguage;
+  };
+
+  return std::unique_ptr<TypeScavenger>(new ObjCTypeScavenger());
 }
 
-bool
-ObjCLanguage::GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint,
-                                        std::string& prefix, std::string& suffix)
-{
-    static ConstString g_CFBag("CFBag");
-    static ConstString g_CFBinaryHeap("CFBinaryHeap");
-    
-    static ConstString g_NSNumberChar("NSNumber:char");
-    static ConstString g_NSNumberShort("NSNumber:short");
-    static ConstString g_NSNumberInt("NSNumber:int");
-    static ConstString g_NSNumberLong("NSNumber:long");
-    static ConstString g_NSNumberFloat("NSNumber:float");
-    static ConstString g_NSNumberDouble("NSNumber:double");
-    
-    static ConstString g_NSData("NSData");
-    static ConstString g_NSArray("NSArray");
-    static ConstString g_NSString("NSString");
-    static ConstString g_NSStringStar("NSString*");
-    
-    if (type_hint.IsEmpty())
-        return false;
-    
-    prefix.clear();
-    suffix.clear();
-    
-    if (type_hint == g_CFBag ||
-        type_hint == g_CFBinaryHeap)
-    {
-        prefix = "@";
-        return true;
-    }
-    
-    if (type_hint == g_NSNumberChar)
-    {
-        prefix = "(char)";
-        return true;
-    }
-    if (type_hint == g_NSNumberShort)
-    {
-        prefix = "(short)";
-        return true;
-    }
-    if (type_hint == g_NSNumberInt)
-    {
-        prefix = "(int)";
-        return true;
-    }
-    if (type_hint == g_NSNumberLong)
-    {
-        prefix = "(long)";
-        return true;
-    }
-    if (type_hint == g_NSNumberFloat)
-    {
-        prefix = "(float)";
-        return true;
-    }
-    if (type_hint == g_NSNumberDouble)
-    {
-        prefix = "(double)";
-        return true;
-    }
-    
-    if (type_hint == g_NSData ||
-        type_hint == g_NSArray)
-    {
-        prefix = "@\"";
-        suffix = "\"";
-        return true;
-    }
-    
-    if (type_hint == g_NSString ||
-        type_hint == g_NSStringStar)
-    {
-        prefix = "@";
-        return true;
-    }
-    
+bool ObjCLanguage::GetFormatterPrefixSuffix(ValueObject &valobj,
+                                            ConstString type_hint,
+                                            std::string &prefix,
+                                            std::string &suffix) {
+  static ConstString g_CFBag("CFBag");
+  static ConstString g_CFBinaryHeap("CFBinaryHeap");
+
+  static ConstString g_NSNumberChar("NSNumber:char");
+  static ConstString g_NSNumberShort("NSNumber:short");
+  static ConstString g_NSNumberInt("NSNumber:int");
+  static ConstString g_NSNumberLong("NSNumber:long");
+  static ConstString g_NSNumberFloat("NSNumber:float");
+  static ConstString g_NSNumberDouble("NSNumber:double");
+
+  static ConstString g_NSData("NSData");
+  static ConstString g_NSArray("NSArray");
+  static ConstString g_NSString("NSString");
+  static ConstString g_NSStringStar("NSString*");
+
+  if (type_hint.IsEmpty())
     return false;
+
+  prefix.clear();
+  suffix.clear();
+
+  if (type_hint == g_CFBag || type_hint == g_CFBinaryHeap) {
+    prefix = "@";
+    return true;
+  }
+
+  if (type_hint == g_NSNumberChar) {
+    prefix = "(char)";
+    return true;
+  }
+  if (type_hint == g_NSNumberShort) {
+    prefix = "(short)";
+    return true;
+  }
+  if (type_hint == g_NSNumberInt) {
+    prefix = "(int)";
+    return true;
+  }
+  if (type_hint == g_NSNumberLong) {
+    prefix = "(long)";
+    return true;
+  }
+  if (type_hint == g_NSNumberFloat) {
+    prefix = "(float)";
+    return true;
+  }
+  if (type_hint == g_NSNumberDouble) {
+    prefix = "(double)";
+    return true;
+  }
+
+  if (type_hint == g_NSData || type_hint == g_NSArray) {
+    prefix = "@\"";
+    suffix = "\"";
+    return true;
+  }
+
+  if (type_hint == g_NSString || type_hint == g_NSStringStar) {
+    prefix = "@";
+    return true;
+  }
+
+  return false;
 }
 
-bool
-ObjCLanguage::IsNilReference (ValueObject& valobj)
-{
-    const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
-    bool isObjCpointer = (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);
-    if (!isObjCpointer)
-        return false;
-    bool canReadValue = true;
-    bool isZero = valobj.GetValueAsUnsigned(0,&canReadValue) == 0;
-    return canReadValue && isZero;
+bool ObjCLanguage::IsNilReference(ValueObject &valobj) {
+  const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
+  bool isObjCpointer =
+      (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);
+  if (!isObjCpointer)
+    return false;
+  bool canReadValue = true;
+  bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
+  return canReadValue && isZero;
 }
diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index b1435d2..c5010b6 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -17,195 +17,143 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/lldb-private.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Target/Language.h"
+#include "lldb/lldb-private.h"
 
 namespace lldb_private {
-    
-class ObjCLanguage :
-    public Language
-{
+
+class ObjCLanguage : public Language {
 public:
-    class MethodName
-    {
-    public:
-        enum Type
-        {
-            eTypeUnspecified,
-            eTypeClassMethod,
-            eTypeInstanceMethod
-        };
-        
-        MethodName () :
-            m_full(),
-            m_class(),
-            m_category(),
-            m_selector(),
-            m_type (eTypeUnspecified),
-            m_category_is_valid (false)
-        {
-        }
+  class MethodName {
+  public:
+    enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
 
-        MethodName (const char *name, bool strict) :
-            m_full(),
-            m_class(),
-            m_category(),
-            m_selector(),
-            m_type (eTypeUnspecified),
-            m_category_is_valid (false)
-        {
-            SetName (name, strict);
-        }
+    MethodName()
+        : m_full(), m_class(), m_category(), m_selector(),
+          m_type(eTypeUnspecified), m_category_is_valid(false) {}
 
-        void
-        Clear();
-
-        bool
-        IsValid (bool strict) const
-        {
-            // If "strict" is true, the name must have everything specified including
-            // the leading "+" or "-" on the method name
-            if (strict && m_type == eTypeUnspecified)
-                return false;
-            // Other than that, m_full will only be filled in if the objective C
-            // name is valid.
-            return (bool)m_full;
-        }
-        
-        bool
-        HasCategory()
-        {
-            return !GetCategory().IsEmpty();
-        }
-
-        Type
-        GetType () const
-        {
-            return m_type;
-        }
-        
-        const ConstString &
-        GetFullName () const
-        {
-            return m_full;
-        }
-        
-        ConstString
-        GetFullNameWithoutCategory (bool empty_if_no_category);
-
-        bool
-        SetName (const char *name, bool strict);
-
-        const ConstString &
-        GetClassName ();
-
-        const ConstString &
-        GetClassNameWithCategory ();
-
-        const ConstString &
-        GetCategory ();
-        
-        const ConstString &
-        GetSelector ();
-
-        // Get all possible names for a method. Examples:
-        // If name is "+[NSString(my_additions) myStringWithCString:]"
-        //  names[0] => "+[NSString(my_additions) myStringWithCString:]"
-        //  names[1] => "+[NSString myStringWithCString:]"
-        // If name is specified without the leading '+' or '-' like "[NSString(my_additions) myStringWithCString:]"
-        //  names[0] => "+[NSString(my_additions) myStringWithCString:]"
-        //  names[1] => "-[NSString(my_additions) myStringWithCString:]"
-        //  names[2] => "+[NSString myStringWithCString:]"
-        //  names[3] => "-[NSString myStringWithCString:]"
-        size_t
-        GetFullNames (std::vector<ConstString> &names, bool append);
-
-    protected:
-        ConstString m_full;     // Full name:   "+[NSString(my_additions) myStringWithCString:]"
-        ConstString m_class;    // Class name:  "NSString"
-        ConstString m_class_category; // Class with category: "NSString(my_additions)"
-        ConstString m_category; // Category:    "my_additions"
-        ConstString m_selector; // Selector:    "myStringWithCString:"
-        Type m_type;
-        bool m_category_is_valid;
-    };
-
-    ObjCLanguage() = default;
-
-    ~ObjCLanguage() override = default;
-
-    lldb::LanguageType
-    GetLanguageType () const override
-    {
-        return lldb::eLanguageTypeObjC;
+    MethodName(const char *name, bool strict)
+        : m_full(), m_class(), m_category(), m_selector(),
+          m_type(eTypeUnspecified), m_category_is_valid(false) {
+      SetName(name, strict);
     }
-    
-    lldb::TypeCategoryImplSP
-    GetFormatters () override;
-    
-    std::vector<ConstString>
-    GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic) override;
-    
-    std::unique_ptr<TypeScavenger>
-    GetTypeScavenger () override;
-    
-    bool
-    GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint,
-                              std::string& prefix, std::string& suffix) override;
-    
-    bool
-    IsNilReference (ValueObject& valobj) override;
-    
-    //------------------------------------------------------------------
-    // Static Functions
-    //------------------------------------------------------------------
-    static void
-    Initialize();
-    
-    static void
-    Terminate();
-    
-    static lldb_private::Language *
-    CreateInstance (lldb::LanguageType language);
-    
-    static lldb_private::ConstString
-    GetPluginNameStatic();
-    
-    static bool
-    IsPossibleObjCMethodName (const char *name)
-    {
-        if (!name)
-            return false;
-        bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
-        bool ends_right = (name[strlen(name) - 1] == ']');
-        return (starts_right && ends_right);
+
+    void Clear();
+
+    bool IsValid(bool strict) const {
+      // If "strict" is true, the name must have everything specified including
+      // the leading "+" or "-" on the method name
+      if (strict && m_type == eTypeUnspecified)
+        return false;
+      // Other than that, m_full will only be filled in if the objective C
+      // name is valid.
+      return (bool)m_full;
     }
-    
-    static bool
-    IsPossibleObjCSelector (const char *name)
-    {
-        if (!name)
-            return false;
-            
-        if (strchr(name, ':') == nullptr)
-            return true;
-        else if (name[strlen(name) - 1] == ':')
-            return true;
-        else
-            return false;
-    }
-    
-    //------------------------------------------------------------------
-    // PluginInterface protocol
-    //------------------------------------------------------------------
+
+    bool HasCategory() { return !GetCategory().IsEmpty(); }
+
+    Type GetType() const { return m_type; }
+
+    const ConstString &GetFullName() const { return m_full; }
+
+    ConstString GetFullNameWithoutCategory(bool empty_if_no_category);
+
+    bool SetName(const char *name, bool strict);
+
+    const ConstString &GetClassName();
+
+    const ConstString &GetClassNameWithCategory();
+
+    const ConstString &GetCategory();
+
+    const ConstString &GetSelector();
+
+    // Get all possible names for a method. Examples:
+    // If name is "+[NSString(my_additions) myStringWithCString:]"
+    //  names[0] => "+[NSString(my_additions) myStringWithCString:]"
+    //  names[1] => "+[NSString myStringWithCString:]"
+    // If name is specified without the leading '+' or '-' like
+    // "[NSString(my_additions) myStringWithCString:]"
+    //  names[0] => "+[NSString(my_additions) myStringWithCString:]"
+    //  names[1] => "-[NSString(my_additions) myStringWithCString:]"
+    //  names[2] => "+[NSString myStringWithCString:]"
+    //  names[3] => "-[NSString myStringWithCString:]"
+    size_t GetFullNames(std::vector<ConstString> &names, bool append);
+
+  protected:
     ConstString
-    GetPluginName() override;
-    
-    uint32_t
-    GetPluginVersion() override;
+        m_full; // Full name:   "+[NSString(my_additions) myStringWithCString:]"
+    ConstString m_class; // Class name:  "NSString"
+    ConstString
+        m_class_category;   // Class with category: "NSString(my_additions)"
+    ConstString m_category; // Category:    "my_additions"
+    ConstString m_selector; // Selector:    "myStringWithCString:"
+    Type m_type;
+    bool m_category_is_valid;
+  };
+
+  ObjCLanguage() = default;
+
+  ~ObjCLanguage() override = default;
+
+  lldb::LanguageType GetLanguageType() const override {
+    return lldb::eLanguageTypeObjC;
+  }
+
+  lldb::TypeCategoryImplSP GetFormatters() override;
+
+  std::vector<ConstString>
+  GetPossibleFormattersMatches(ValueObject &valobj,
+                               lldb::DynamicValueType use_dynamic) override;
+
+  std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
+
+  bool GetFormatterPrefixSuffix(ValueObject &valobj, ConstString type_hint,
+                                std::string &prefix,
+                                std::string &suffix) override;
+
+  bool IsNilReference(ValueObject &valobj) override;
+
+  //------------------------------------------------------------------
+  // Static Functions
+  //------------------------------------------------------------------
+  static void Initialize();
+
+  static void Terminate();
+
+  static lldb_private::Language *CreateInstance(lldb::LanguageType language);
+
+  static lldb_private::ConstString GetPluginNameStatic();
+
+  static bool IsPossibleObjCMethodName(const char *name) {
+    if (!name)
+      return false;
+    bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
+    bool ends_right = (name[strlen(name) - 1] == ']');
+    return (starts_right && ends_right);
+  }
+
+  static bool IsPossibleObjCSelector(const char *name) {
+    if (!name)
+      return false;
+
+    if (strchr(name, ':') == nullptr)
+      return true;
+    else if (name[strlen(name) - 1] == ':')
+      return true;
+    else
+      return false;
+  }
+
+  //------------------------------------------------------------------
+  // PluginInterface protocol
+  //------------------------------------------------------------------
+  ConstString GetPluginName() override;
+
+  uint32_t GetPluginVersion() override;
 };
-    
+
 } // namespace lldb_private
 
 #endif // liblldb_ObjCLanguage_h_
