[Lldb-commits] [lldb] 34d78b6 - [lldb] Upstream support for Foundation constant classes

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Fri Aug 6 16:08:57 PDT 2021


Author: Jonas Devlieghere
Date: 2021-08-06T16:08:48-07:00
New Revision: 34d78b6a6755946e547afc47d38b59b6a2854457

URL: https://github.com/llvm/llvm-project/commit/34d78b6a6755946e547afc47d38b59b6a2854457
DIFF: https://github.com/llvm/llvm-project/commit/34d78b6a6755946e547afc47d38b59b6a2854457.diff

LOG: [lldb] Upstream support for Foundation constant classes

Upstream support for NSConstantArray, NSConstantIntegerNumber,
NSConstant{Float,Double}Number and NSConstantDictionary.

We would've upstreamed this earlier but testing it requires
-fno-constant-nsnumber-literals, -fno-constant-nsarray-literals and
-fno-constant-nsdictionary-literals which haven't been upstreamed yet.
As a temporary workaround use the system compiler (xcrun clang) for the
constant variant of the tests.

I'm just upstreaming this. The patch and the tests were all authored by
Fred Riss.

Differential revision: https://reviews.llvm.org/D107660

Added: 
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSNumber.py

Modified: 
    lldb/source/Plugins/Language/ObjC/Cocoa.cpp
    lldb/source/Plugins/Language/ObjC/NSArray.cpp
    lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
    lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/ObjCDataFormatterTestCase.py
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSBundle.py
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSContainer.py
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSData.py
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSError.py
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSURL.py
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjNSException.py
    lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m
    lldb/test/API/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
    lldb/test/API/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
    lldb/test/API/functionalities/data-formatter/poarray/TestPrintObjectArray.py
    lldb/test/API/lang/objc/orderedset/TestOrderedSet.py
    lldb/test/API/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
index 1479f4f0c151..e5dcf8441bb6 100644
--- a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Cocoa.h"
+#include "objc/runtime.h"
 
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/Core/Mangled.h"
@@ -456,6 +457,72 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
   if (class_name == "NSDecimalNumber")
     return NSDecimalNumberSummaryProvider(valobj, stream, options);
 
+  if (class_name == "NSConstantIntegerNumber") {
+    Status error;
+    int64_t value = process_sp->ReadSignedIntegerFromMemory(
+        valobj_addr + 2 * ptr_size, 8, 0, error);
+    if (error.Fail())
+      return false;
+    uint64_t encoding_addr = process_sp->ReadUnsignedIntegerFromMemory(
+        valobj_addr + ptr_size, ptr_size, 0, error);
+    if (error.Fail())
+      return false;
+    char encoding =
+        process_sp->ReadUnsignedIntegerFromMemory(encoding_addr, 1, 0, error);
+    if (error.Fail())
+      return false;
+
+    switch (encoding) {
+    case _C_CHR:
+      NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
+      return true;
+    case _C_SHT:
+      NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage());
+      return true;
+    case _C_INT:
+      NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
+      return true;
+    case _C_LNG:
+    case _C_LNG_LNG:
+      NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
+      return true;
+
+    case _C_UCHR:
+    case _C_USHT:
+    case _C_UINT:
+    case _C_ULNG:
+    case _C_ULNG_LNG:
+      stream.Printf("%" PRIu64, value);
+      return true;
+    }
+
+    return false;
+  }
+
+  if (class_name == "NSConstantFloatNumber") {
+    Status error;
+    uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(
+        valobj_addr + ptr_size, 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());
+    return true;
+  }
+
+  if (class_name == "NSConstantDoubleNumber") {
+    Status error;
+    uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(
+        valobj_addr + ptr_size, 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());
+    return true;
+  }
+
   if (class_name == "NSNumber" || class_name == "__NSCFNumber") {
     int64_t value = 0;
     uint64_t i_bits = 0;

diff  --git a/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
index b0398dd19c02..f18b59fb11ff 100644
--- a/lldb/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
@@ -280,6 +280,22 @@ namespace Foundation1436 {
     }
 }
 
+namespace ConstantArray {
+
+struct ConstantArray32 {
+  uint64_t used;
+  uint32_t list;
+};
+
+struct ConstantArray64 {
+  uint64_t used;
+  uint64_t list;
+};
+
+using NSConstantArraySyntheticFrontEnd =
+    GenericNSArrayISyntheticFrontEnd<ConstantArray32, ConstantArray64, false>;
+} // namespace ConstantArray
+
 class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
   NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
@@ -356,6 +372,7 @@ bool lldb_private::formatters::NSArraySummaryProvider(
   static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
   static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
   static const ConstString g_NSCallStackArray("_NSCallStackArray");
+  static const ConstString g_NSConstantArray("NSConstantArray");
 
   if (class_name.IsEmpty())
     return false;
@@ -366,6 +383,12 @@ bool lldb_private::formatters::NSArraySummaryProvider(
                                                       ptr_size, 0, error);
     if (error.Fail())
       return false;
+  } else if (class_name == g_NSConstantArray) {
+    Status error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 8,
+                                                      0, error);
+    if (error.Fail())
+      return false;
   } else if (class_name == g_NSArrayM) {
     AppleObjCRuntime *apple_runtime =
     llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
@@ -803,6 +826,7 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
   ConstString class_name(descriptor->GetClassName());
 
   static const ConstString g_NSArrayI("__NSArrayI");
+  static const ConstString g_NSConstantArray("NSConstantArray");
   static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer");
   static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM");
   static const ConstString g_NSArrayM("__NSArrayM");
@@ -823,6 +847,8 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
     return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_NSArrayI_Transfer) {
       return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp));
+  } else if (class_name == g_NSConstantArray) {
+    return new ConstantArray::NSConstantArraySyntheticFrontEnd(valobj_sp);
   } else if (class_name == g_NSFrozenArrayM) {
     return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_NSArray0) {

diff  --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
index 326f47a10660..d8bf034e731b 100644
--- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -142,6 +142,38 @@ class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
   std::vector<DictionaryItemDescriptor> m_children;
 };
 
+class NSConstantDictionarySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSConstantDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  size_t CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+  bool Update() override;
+
+  bool MightHaveChildren() override;
+
+  size_t GetIndexOfChildWithName(ConstString name) override;
+
+private:
+  ExecutionContextRef m_exe_ctx_ref;
+  CompilerType m_pair_type;
+  uint8_t m_ptr_size = 8;
+  lldb::ByteOrder m_order = lldb::eByteOrderInvalid;
+  unsigned int m_size = 0;
+  lldb::addr_t m_keys_ptr = LLDB_INVALID_ADDRESS;
+  lldb::addr_t m_objects_ptr = LLDB_INVALID_ADDRESS;
+
+  struct DictionaryItemDescriptor {
+    lldb::addr_t key_ptr;
+    lldb::addr_t val_ptr;
+    lldb::ValueObjectSP valobj_sp;
+  };
+
+  std::vector<DictionaryItemDescriptor> m_children;
+};
+
 class NSCFDictionarySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
   NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
@@ -416,6 +448,7 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
   static const ConstString g_DictionaryCF("__CFDictionary");
   static const ConstString g_DictionaryNSCF("__NSCFDictionary");
   static const ConstString g_DictionaryCFRef("CFDictionaryRef");
+  static const ConstString g_ConstantDictionary("NSConstantDictionary");
 
   if (class_name.IsEmpty())
     return false;
@@ -428,8 +461,14 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
       return false;
 
     value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
-  } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy 
-             || class_name == g_DictionaryMFrozen) {
+  } else if (class_name == g_ConstantDictionary) {
+    Status error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(
+        valobj_addr + 2 * ptr_size, ptr_size, 0, error);
+    if (error.Fail())
+      return false;
+  } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy ||
+             class_name == g_DictionaryMFrozen) {
     AppleObjCRuntime *apple_runtime =
     llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
     Status error;
@@ -447,8 +486,7 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
     value = 1;
   } else if (class_name == g_Dictionary0) {
     value = 0;
-  } else if (class_name == g_DictionaryCF ||
-             class_name == g_DictionaryNSCF ||
+  } else if (class_name == g_DictionaryCF || class_name == g_DictionaryNSCF ||
              class_name == g_DictionaryCFRef) {
     ExecutionContext exe_ctx(process_sp);
     CFBasicHash cfbh;
@@ -517,12 +555,15 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
   static const ConstString g_DictionaryCF("__CFDictionary");
   static const ConstString g_DictionaryNSCF("__NSCFDictionary");
   static const ConstString g_DictionaryCFRef("CFDictionaryRef");
+  static const ConstString g_ConstantDictionary("NSConstantDictionary");
 
   if (class_name.IsEmpty())
     return nullptr;
 
   if (class_name == g_DictionaryI) {
     return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
+  } else if (class_name == g_ConstantDictionary) {
+    return (new NSConstantDictionarySyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_DictionaryM || class_name == g_DictionaryMFrozen) {
     if (runtime->GetFoundationVersion() >= 1437) {
       return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp));
@@ -532,11 +573,10 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator(
       return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
     }
   } else if (class_name == g_DictionaryMLegacy) {
-      return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
+    return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_Dictionary1) {
     return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
-  } else if (class_name == g_DictionaryCF ||
-             class_name == g_DictionaryNSCF ||
+  } else if (class_name == g_DictionaryCF || class_name == g_DictionaryNSCF ||
              class_name == g_DictionaryCFRef) {
     return (new NSCFDictionarySyntheticFrontEnd(valobj_sp));
   } else {
@@ -830,6 +870,120 @@ lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::GetChildAtIndex(
   return dict_item.valobj_sp;
 }
 
+lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd::
+    NSConstantDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp) {}
+
+size_t lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd::
+    GetIndexOfChildWithName(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::NSConstantDictionarySyntheticFrontEnd::
+    CalculateNumChildren() {
+  return m_size;
+}
+
+bool lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd::Update() {
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  if (!valobj_sp)
+    return false;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  Status error;
+  error.Clear();
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
+    return false;
+  m_ptr_size = process_sp->GetAddressByteSize();
+  m_order = process_sp->GetByteOrder();
+  uint64_t valobj_addr = valobj_sp->GetValueAsUnsigned(0);
+  m_size = process_sp->ReadUnsignedIntegerFromMemory(
+      valobj_addr + 2 * m_ptr_size, m_ptr_size, 0, error);
+  if (error.Fail())
+    return false;
+  m_keys_ptr =
+      process_sp->ReadPointerFromMemory(valobj_addr + 3 * m_ptr_size, error);
+  if (error.Fail())
+    return false;
+  m_objects_ptr =
+      process_sp->ReadPointerFromMemory(valobj_addr + 4 * m_ptr_size, error);
+  return !error.Fail();
+}
+
+bool lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd::
+    MightHaveChildren() {
+  return true;
+}
+
+lldb::ValueObjectSP lldb_private::formatters::
+    NSConstantDictionarySyntheticFrontEnd::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;
+    ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+    if (!process_sp)
+      return lldb::ValueObjectSP();
+
+    for (unsigned int child = 0; child < num_children; ++child) {
+      Status error;
+      key_at_idx = process_sp->ReadPointerFromMemory(
+          m_keys_ptr + child * m_ptr_size, error);
+      if (error.Fail())
+        return lldb::ValueObjectSP();
+      val_at_idx = process_sp->ReadPointerFromMemory(
+          m_objects_ptr + child * m_ptr_size, error);
+      if (error.Fail())
+        return lldb::ValueObjectSP();
+      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.GetString(), 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) {}

diff  --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 379c53432b7b..613b2fb2d8a5 100644
--- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -403,6 +403,9 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
   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("NSConstantArray"), appkit_flags);
   AddCXXSummary(
       objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
       "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
@@ -437,6 +440,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP 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("NSConstantDictionary"), appkit_flags);
   AddCXXSummary(objc_category_sp,
                 lldb_private::formatters::NSDictionarySummaryProvider<false>,
                 "NSDictionary summary provider",
@@ -543,6 +550,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP 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("NSConstantArray"),
+                  ScriptedSyntheticChildren::Flags());
   AddCXXSynthetic(objc_category_sp,
                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
                   "NSArray synthetic children", ConstString("NSMutableArray"),
@@ -570,6 +581,11 @@ static void LoadObjCFormatters(TypeCategoryImplSP 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("NSConstantDictionary"),
+      ScriptedSyntheticChildren::Flags());
   AddCXXSynthetic(
       objc_category_sp,
       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
@@ -791,6 +807,18 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
   AddCXXSummary(
       objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
       "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSNumberSummaryProvider,
+                "NSNumber summary provider",
+                ConstString("NSConstantIntegerNumber"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSNumberSummaryProvider,
+                "NSNumber summary provider",
+                ConstString("NSConstantDoubleNumber"), appkit_flags);
+  AddCXXSummary(objc_category_sp,
+                lldb_private::formatters::NSNumberSummaryProvider,
+                "NSNumber summary provider",
+                ConstString("NSConstantFloatNumber"), appkit_flags);
   AddCXXSummary(
       objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
       "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/ObjCDataFormatterTestCase.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/ObjCDataFormatterTestCase.py
index c31af352037f..db7f823493f1 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/ObjCDataFormatterTestCase.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/ObjCDataFormatterTestCase.py
@@ -14,8 +14,19 @@ class ObjCDataFormatterTestCase(TestBase):
 
    mydir = TestBase.compute_mydir(__file__)
 
-   def appkit_tester_impl(self, commands):
-      self.build()
+   def appkit_tester_impl(self, commands, use_constant_classes):
+      if use_constant_classes:
+         self.build()
+      else:
+         disable_constant_classes = {
+            'CC':
+            'xcrun clang', # FIXME: Remove when flags are available upstream.
+            'CFLAGS_EXTRAS':
+            '-fno-constant-nsnumber-literals ' +
+            '-fno-constant-nsarray-literals ' +
+            '-fno-constant-nsdictionary-literals'
+         }
+         self.build(dictionary=disable_constant_classes)
       self.appkit_common_data_formatters_command()
       commands()
 

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSBundle.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSBundle.py
index 673366fcbb3e..84fd49b07b86 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSBundle.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSBundle.py
@@ -16,7 +16,12 @@ class ObjCDataFormatterNSBundle(ObjCDataFormatterTestCase):
 
     def test_nsbundle_with_run_command(self):
         """Test formatters for NSBundle."""
-        self.appkit_tester_impl(self.nsbundle_data_formatter_commands)
+        self.appkit_tester_impl(self.nsbundle_data_formatter_commands, True)
+
+    @skipUnlessDarwin
+    def test_nsbundle_with_run_command_no_sonct(self):
+        """Test formatters for NSBundle."""
+        self.appkit_tester_impl(self.nsbundle_data_formatter_commands, False)
 
     def nsbundle_data_formatter_commands(self):
         self.expect(

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSContainer.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSContainer.py
index 26ebf28929ff..375aefe36422 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSContainer.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSContainer.py
@@ -16,7 +16,7 @@ class ObjCDataFormatterNSContainer(ObjCDataFormatterTestCase):
 
     def test_nscontainers_with_run_command(self):
         """Test formatters for  NS container classes."""
-        self.appkit_tester_impl(self.nscontainers_data_formatter_commands)
+        self.appkit_tester_impl(self.nscontainers_data_formatter_commands, False)
 
     def nscontainers_data_formatter_commands(self):
         self.expect(

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSData.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSData.py
index f1c5554eebfb..846e1d9bb69a 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSData.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSData.py
@@ -16,7 +16,12 @@ class ObjCDataFormatterNSData(ObjCDataFormatterTestCase):
 
     def test_nsdata_with_run_command(self):
         """Test formatters for  NSData."""
-        self.appkit_tester_impl(self.nsdata_data_formatter_commands)
+        self.appkit_tester_impl(self.nsdata_data_formatter_commands, True)
+
+    @skipUnlessDarwin
+    def test_nsdata_with_run_command_no_const(self):
+        """Test formatters for  NSData."""
+        self.appkit_tester_impl(self.nsdata_data_formatter_commands, False)
 
     def nsdata_data_formatter_commands(self):
         self.expect(

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py
index 622bb4a327ed..06996b1c151b 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py
@@ -17,7 +17,7 @@ class ObjCDataFormatterNSDate(ObjCDataFormatterTestCase):
 
     def test_nsdate_with_run_command(self):
         """Test formatters for  NSDate."""
-        self.appkit_tester_impl(self.nsdate_data_formatter_commands)
+        self.appkit_tester_impl(self.nsdate_data_formatter_commands, False)
 
     def nsdate_data_formatter_commands(self):
         self.expect(

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSError.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSError.py
index 92f1f46deba4..8a3773a590ea 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSError.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSError.py
@@ -16,7 +16,12 @@ class ObjCDataFormatterNSError(ObjCDataFormatterTestCase):
 
     def test_nserror_with_run_command(self):
         """Test formatters for NSError."""
-        self.appkit_tester_impl(self.nserror_data_formatter_commands)
+        self.appkit_tester_impl(self.nserror_data_formatter_commands, True)
+
+    @skipUnlessDarwin
+    def test_nserror_with_run_command_no_const(self):
+        """Test formatters for NSError."""
+        self.appkit_tester_impl(self.nserror_data_formatter_commands, False)
 
     def nserror_data_formatter_commands(self):
         self.expect(

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSNumber.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSNumber.py
new file mode 100644
index 000000000000..47e272d4fe2e
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSNumber.py
@@ -0,0 +1,67 @@
+# encoding: utf-8
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+from ObjCDataFormatterTestCase import ObjCDataFormatterTestCase
+
+
+class ObjCDataFormatterNSNumber(ObjCDataFormatterTestCase):
+
+    @skipUnlessDarwin
+    def test_nsnumber_with_run_command(self):
+        """Test formatters for  NS container classes."""
+        self.appkit_tester_impl(self.nscontainers_data_formatter_commands, True)
+
+    @skipUnlessDarwin
+    def test_nsnumber_with_run_command_no_const(self):
+        """Test formatters for  NS container classes."""
+        self.appkit_tester_impl(self.nscontainers_data_formatter_commands, False)
+
+    def nscontainers_data_formatter_commands(self):
+        self.expect(
+            'frame variable newArray nsDictionary newDictionary nscfDictionary cfDictionaryRef newMutableDictionary cfarray_ref mutable_array_ref',
+            substrs=[
+                '(NSArray *) newArray = ', '@"50 elements"',
+                '(NSDictionary *) nsDictionary = ', ' 2 key/value pairs',
+                '(NSDictionary *) newDictionary = ', ' 12 key/value pairs',
+                '(CFDictionaryRef) cfDictionaryRef = ', ' 2 key/value pairs',
+                '(NSDictionary *) newMutableDictionary = ', ' 21 key/value pairs',
+                '(CFArrayRef) cfarray_ref = ', '@"3 elements"',
+                '(CFMutableArrayRef) mutable_array_ref = ', '@"11 elements"'
+            ])
+
+        numbers = [ ("num1", "(int)5"),
+                    ("num2", "(float)3.140000"),
+                    ("num3", "(double)3.14"),
+                    ("num4", "(int128_t)18446744073709551614"),
+                    ("num5", "(char)65"),
+                    ("num6", "(long)255"),
+                    ("num7", "(long)2000000"),
+                    ("num8_Y", "YES"),
+                    ("num8_N", "NO"),
+                    ("num9", "(short)-31616"),
+                    ("num_at1", "(int)12"),
+                    ("num_at2", "(int)-12"),
+                    ("num_at3", "(double)12.5"),
+                    ("num_at4", "(double)-12.5"),
+                    ("num_at5", "(char)97"),
+                    ("num_at6", "(float)42.123"),
+                    ("num_at7", "(double)43.123"),
+                    ("num_at8", "(long)12345"),
+                    ("num_at9", "17375808098308635870"),
+                    ("num_at9b", "-1070935975400915746"),
+                    ("num_at10", "YES"),
+                    ("num_at11", "NO"),
+        ]
+
+        for var, res in numbers:
+            self.expect('frame variable ' + var, substrs=[res])
+

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSURL.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSURL.py
index b746c4907236..c16e0986b082 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSURL.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSURL.py
@@ -16,7 +16,12 @@ class ObjCDataFormatterNSURL(ObjCDataFormatterTestCase):
 
     def test_nsurl_with_run_command(self):
         """Test formatters for NSURL."""
-        self.appkit_tester_impl(self.nsurl_data_formatter_commands)
+        self.appkit_tester_impl(self.nsurl_data_formatter_commands, True)
+
+    @skipUnlessDarwin
+    def test_nsurl_with_run_command_no_const(self):
+        """Test formatters for NSURL."""
+        self.appkit_tester_impl(self.nsurl_data_formatter_commands, False)
 
     def nsurl_data_formatter_commands(self):
         self.expect(

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjNSException.py b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjNSException.py
index cf4144458dde..664425d05f05 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjNSException.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjNSException.py
@@ -16,7 +16,12 @@ class ObjCDataFormatterNSException(ObjCDataFormatterTestCase):
 
     def test_nsexception_with_run_command(self):
         """Test formatters for NSException."""
-        self.appkit_tester_impl(self.nsexception_data_formatter_commands)
+        self.appkit_tester_impl(self.nsexception_data_formatter_commands, True)
+
+    @skipUnlessDarwin
+    def test_nsexception_with_run_command_no_const(self):
+        """Test formatters for NSException."""
+        self.appkit_tester_impl(self.nsexception_data_formatter_commands, False)
 
     def nsexception_data_formatter_commands(self):
         self.expect(

diff  --git a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m
index e1e6d1a1b759..0ca5cf98bd3a 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m
@@ -154,6 +154,14 @@ int main(int argc, const char *argv[]) {
   NSNumber *num_at2 = @-12;
   NSNumber *num_at3 = @12.5;
   NSNumber *num_at4 = @-12.5;
+  NSNumber *num_at5 = @'a';
+  NSNumber *num_at6 = @42.123f;
+  NSNumber *num_at7 = @43.123;
+  NSNumber *num_at8 = @12345ll;
+  NSNumber *num_at9 = @0xF1234567890abcdeull;
+  NSNumber *num_at9b = @-1070935975400915746;
+  NSNumber *num_at10 = @YES;
+  NSNumber *num_at11 = @NO;
 
   NSDecimalNumber *decimal_number =
       [NSDecimalNumber decimalNumberWithMantissa:123456

diff  --git a/lldb/test/API/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py b/lldb/test/API/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
index b77d01a8086c..eb54f53bd811 100644
--- a/lldb/test/API/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
+++ b/lldb/test/API/functionalities/data-formatter/nsdictionarysynth/TestNSDictionarySynthetic.py
@@ -24,6 +24,23 @@ def setUp(self):
     def test_rdar11988289_with_run_command(self):
         """Test that NSDictionary reports its synthetic children properly."""
         self.build()
+        self.run_tests()
+
+    @skipUnlessDarwin
+    def test_rdar11988289_with_run_command_no_const(self):
+        """Test that NSDictionary reports its synthetic children properly."""
+        disable_constant_classes = {
+            'CC':
+            'xcrun clang',  # FIXME: Remove when flags are available upstream.
+            'CFLAGS_EXTRAS':
+            '-fno-constant-nsnumber-literals ' +
+            '-fno-constant-nsarray-literals ' +
+            '-fno-constant-nsdictionary-literals'
+        }
+        self.build(dictionary=disable_constant_classes)
+        self.run_tests()
+
+    def run_tests(self):
         self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
 
         lldbutil.run_break_set_by_file_and_line(

diff  --git a/lldb/test/API/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py b/lldb/test/API/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
index feac24be836d..219ed2c3aacb 100644
--- a/lldb/test/API/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
+++ b/lldb/test/API/functionalities/data-formatter/nssetsynth/TestNSSetSynthetic.py
@@ -24,6 +24,23 @@ def setUp(self):
     def test_rdar12529957_with_run_command(self):
         """Test that NSSet reports its synthetic children properly."""
         self.build()
+        self.run_tests()
+
+    @skipUnlessDarwin
+    def test_rdar12529957_with_run_command_no_const(self):
+        """Test that NSSet reports its synthetic children properly."""
+        disable_constant_classes = {
+            'CC':
+            'xcrun clang',  # FIXME: Remove when flags are available upstream.
+            'CFLAGS_EXTRAS':
+            '-fno-constant-nsnumber-literals ' +
+            '-fno-constant-nsarray-literals ' +
+            '-fno-constant-nsdictionary-literals'
+        }
+        self.build(dictionary=disable_constant_classes)
+        self.run_tests()
+
+    def run_tests(self):
         self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
 
         lldbutil.run_break_set_by_file_and_line(

diff  --git a/lldb/test/API/functionalities/data-formatter/poarray/TestPrintObjectArray.py b/lldb/test/API/functionalities/data-formatter/poarray/TestPrintObjectArray.py
index 626e6cd16e8f..3fcb2794b952 100644
--- a/lldb/test/API/functionalities/data-formatter/poarray/TestPrintObjectArray.py
+++ b/lldb/test/API/functionalities/data-formatter/poarray/TestPrintObjectArray.py
@@ -20,6 +20,20 @@ def test_print_array(self):
         self.build()
         self.printarray_data_formatter_commands()
 
+    @skipUnlessDarwin
+    def test_print_array_no_const(self):
+        """Test that expr -O -Z works"""
+        disable_constant_classes = {
+            'CC':
+            'xcrun clang',  # FIXME: Remove when flags are available upstream.
+            'CFLAGS_EXTRAS':
+            '-fno-constant-nsnumber-literals ' +
+            '-fno-constant-nsarray-literals ' +
+            '-fno-constant-nsdictionary-literals'
+        }
+        self.build(dictionary=disable_constant_classes)
+        self.printarray_data_formatter_commands()
+
     def setUp(self):
         # Call super's setUp().
         TestBase.setUp(self)

diff  --git a/lldb/test/API/lang/objc/orderedset/TestOrderedSet.py b/lldb/test/API/lang/objc/orderedset/TestOrderedSet.py
index 80cb97a9d108..ac7af265b27c 100644
--- a/lldb/test/API/lang/objc/orderedset/TestOrderedSet.py
+++ b/lldb/test/API/lang/objc/orderedset/TestOrderedSet.py
@@ -8,6 +8,22 @@ class TestOrderedSet(TestBase):
 
   def test_ordered_set(self):
     self.build()
+    self.run_tests()
+
+  @skipUnlessDarwin
+  def test_ordered_set_no_const(self):
+    disable_constant_classes = {
+        'CC':
+        'xcrun clang',  # FIXME: Remove when flags are available upstream.
+        'CFLAGS_EXTRAS':
+        '-fno-constant-nsnumber-literals ' +
+        '-fno-constant-nsarray-literals ' +
+        '-fno-constant-nsdictionary-literals'
+    }
+    self.build(dictionary=disable_constant_classes)
+    self.run_tests()
+
+  def run_tests(self):
     src_file = "main.m"
     src_file_spec = lldb.SBFileSpec(src_file)
     (target, process, thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(self,

diff  --git a/lldb/test/API/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py b/lldb/test/API/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py
index d50cbb39246b..88d2536a1618 100644
--- a/lldb/test/API/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py
+++ b/lldb/test/API/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py
@@ -21,9 +21,27 @@ def setUp(self):
         # Find the line number to break inside main().
         self.line = line_number('main.m', '// break here')
 
+    @skipUnlessDarwin
     @expectedFailureAll(oslist=['watchos'], bugnumber="rdar://problem/34642736") # bug in NSDictionary formatting on watchos
     def test_single_entry_dict(self):
         self.build()
+        self.run_tests()
+
+    @skipUnlessDarwin
+    @expectedFailureAll(oslist=['watchos'], bugnumber="rdar://problem/34642736") # bug in NSDictionary formatting on watchos
+    def test_single_entry_dict_no_const(self):
+        disable_constant_classes = {
+            'CC':
+            'xcrun clang',  # FIXME: Remove when flags are available upstream.
+            'CFLAGS_EXTRAS':
+            '-fno-constant-nsnumber-literals ' +
+            '-fno-constant-nsarray-literals ' +
+            '-fno-constant-nsdictionary-literals'
+        }
+        self.build(dictionary=disable_constant_classes)
+        self.run_tests()
+
+    def run_tests(self):
         exe = self.getBuildArtifact("a.out")
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 


        


More information about the lldb-commits mailing list