diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -687,6 +687,11 @@ language_flags); } + if (!valobj && synthetic_array_member) + valobj = GetSyntheticValue() + ->GetChildAtIndex(synthetic_index, synthetic_array_member) + .get(); + return valobj; } @@ -2824,6 +2829,27 @@ child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid, language_flags); } + + // In case of incomplete child compiler type, use the pointee type and try + // to recreate a new ValueObjectChild using it. + if (!m_deref_valobj) { + if (HasSyntheticValue()) { + child_compiler_type = compiler_type.GetPointeeType(); + + if (child_compiler_type) { + ConstString child_name; + if (!child_name_str.empty()) + child_name.SetCString(child_name_str.c_str()); + + m_deref_valobj = new ValueObjectChild( + *this, child_compiler_type, child_name, child_byte_size, + child_byte_offset, child_bitfield_bit_size, + child_bitfield_bit_offset, child_is_base_class, + child_is_deref_of_parent, eAddressTypeInvalid, language_flags); + } + } + } + } else if (HasSyntheticValue()) { m_deref_valobj = GetSyntheticValue() diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp --- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -53,7 +53,9 @@ m_might_have_children(eLazyBoolCalculate), m_provides_value(eLazyBoolCalculate) { SetName(parent.GetName()); - CopyValueData(m_parent); + // Copying the data of an incomplete type won't work as it has no byte size. + if (m_parent->GetCompilerType().IsCompleteType()) + CopyValueData(m_parent); CreateSynthFilter(); } @@ -219,7 +221,9 @@ GetName().AsCString()); m_provides_value = eLazyBoolNo; - CopyValueData(m_parent); + // Copying the data of an incomplete type won't work as it has no byte size. + if (m_parent->GetCompilerType().IsCompleteType()) + CopyValueData(m_parent); } SetValueIsValid(true); diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp --- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -408,7 +408,8 @@ static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable"); static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI"); static const ConstString g_Dictionary0("__NSDictionary0"); - static const ConstString g_DictionaryCF("__NSCFDictionary"); + static const ConstString g_DictionaryCF("__CFDictionary"); + static const ConstString g_DictionaryNSCF("__NSCFDictionary"); static const ConstString g_DictionaryCFRef("CFDictionaryRef"); if (class_name.IsEmpty()) @@ -420,6 +421,7 @@ ptr_size, 0, error); if (error.Fail()) return false; + value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) { AppleObjCRuntime *apple_runtime = @@ -439,7 +441,9 @@ value = 1; } else if (class_name == g_Dictionary0) { value = 0; - } else if (class_name == g_DictionaryCF || class_name == g_DictionaryCFRef) { + } else if (class_name == g_DictionaryCF || + class_name == g_DictionaryNSCF || + class_name == g_DictionaryCFRef) { ExecutionContext exe_ctx(process_sp); CFBasicHash cfbh; if (!cfbh.Update(valobj_addr, exe_ctx)) @@ -503,7 +507,8 @@ static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable"); static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy"); static const ConstString g_Dictionary0("__NSDictionary0"); - static const ConstString g_DictionaryCF("__NSCFDictionary"); + static const ConstString g_DictionaryCF("__CFDictionary"); + static const ConstString g_DictionaryNSCF("__NSCFDictionary"); static const ConstString g_DictionaryCFRef("CFDictionaryRef"); if (class_name.IsEmpty()) @@ -523,7 +528,9 @@ 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_DictionaryCFRef) { + } else if (class_name == g_DictionaryCF || + class_name == g_DictionaryNSCF || + class_name == g_DictionaryCFRef) { return (new NSCFDictionarySyntheticFrontEnd(valobj_sp)); } else { auto &map(NSDictionary_Additionals::GetAdditionalSynthetics()); diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/lldb/source/Plugins/Language/ObjC/NSSet.cpp --- a/lldb/source/Plugins/Language/ObjC/NSSet.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSSet.cpp @@ -282,6 +282,7 @@ static const ConstString g_OrderedSetI("__NSOrderedSetI"); static const ConstString g_SetM("__NSSetM"); static const ConstString g_SetCF("__NSCFSet"); + static const ConstString g_SetCFRef("CFSetRef"); if (class_name.IsEmpty()) return false; @@ -306,7 +307,7 @@ } if (error.Fail()) return false; - } else if (class_name == g_SetCF) { + } else if (class_name == g_SetCF || class_name == g_SetCFRef) { ExecutionContext exe_ctx(process_sp); CFBasicHash cfbh; if (!cfbh.Update(valobj_addr, exe_ctx)) @@ -367,6 +368,7 @@ static const ConstString g_OrderedSetI("__NSOrderedSetI"); static const ConstString g_SetM("__NSSetM"); static const ConstString g_SetCF("__NSCFSet"); + static const ConstString g_SetCFRef("CFSetRef"); if (class_name.IsEmpty()) return nullptr; @@ -386,7 +388,7 @@ } else { return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp)); } - } else if (class_name == g_SetCF) { + } else if (class_name == g_SetCF || class_name == g_SetCFRef) { return (new NSCFSetSyntheticFrontEnd(valobj_sp)); } else { auto &map(NSSet_Additionals::GetAdditionalSynthetics()); diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -448,6 +448,10 @@ appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider, + "NSDictionary summary provider", ConstString("__CFDictionary"), + appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDictionarySummaryProvider, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags); @@ -468,6 +472,9 @@ "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider, + "__CFSet summary", ConstString("__CFSet"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider, @@ -584,6 +591,11 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic( + objc_category_sp, + lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, + "NSDictionary synthetic children", ConstString("__CFDictionary"), + ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSErrorSyntheticFrontEndCreator, @@ -610,6 +622,10 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSCFSet synthetic children", ConstString("__NSCFSet"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "CFSetRef synthetic children", ConstString("CFSetRef"), + ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, @@ -627,6 +643,10 @@ objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "__CFSet synthetic children", ConstString("__CFSet"), + ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, 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 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSContainer.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSContainer.py @@ -32,7 +32,7 @@ '(NSDictionary *) nscfDictionary = ', ' 4 key/value pairs', '(CFDictionaryRef) cfDictionaryRef = ', - ' 3 key/value pairs', + ' 2 key/value pairs', '(NSDictionary *) newMutableDictionary = ', ' 21 key/value pairs', '(CFArrayRef) cfarray_ref = ', @@ -57,10 +57,23 @@ self.expect( - 'frame var nscfSet', + 'frame variable -d run-target *cfDictionaryRef', + patterns=[ + '\(const __CFDictionary\) \*cfDictionaryRef =', + 'key = 0x.* @"foo"', + 'value = 0x.* @"foo"', + 'key = 0x.* @"bar"', + 'value = 0x.* @"bar"', + ]) + + + self.expect( + 'frame var nscfSet cfSetRef', substrs=[ '(NSSet *) nscfSet = ', '2 elements', + '(CFSetRef) cfSetRef = ', + '2 elements', ]) self.expect( @@ -72,6 +85,14 @@ ]) self.expect( + 'frame variable -d run-target *cfSetRef', + patterns=[ + '\(const __CFSet\) \*cfSetRef =', + '\[0\] = 0x.* @".*"', + '\[1\] = 0x.* @".*"', + ]) + + self.expect( 'frame variable iset1 iset2 imset', substrs=['4 indexes', '512 indexes', '10 indexes']) 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 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m @@ -482,8 +482,7 @@ CFDictionaryCreate(nil, (void *)cfKeys, (void *)cfValues, 2, nil, nil)); NSDictionary *nscfDictionary = CFBridgingRelease( CFDictionaryCreate(nil, (void *)cfKeys, (void *)cfValues, 4, nil, nil)); - CFDictionaryRef cfDictionaryRef = - CFDictionaryCreate(nil, (void *)cfKeys, (void *)cfValues, 3, nil, nil); + CFDictionaryRef cfDictionaryRef = (__bridge CFDictionaryRef)nsDictionary; NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"hello world from foo" @@ -542,6 +541,7 @@ [nsmutableset addObject:str4]; NSSet *nscfSet = CFBridgingRelease(CFSetCreate(nil, (void *)cfValues, 2, nil)); + CFSetRef cfSetRef = (__bridge CFSetRef)nscfSet; CFDataRef data_ref = CFDataCreate(kCFAllocatorDefault, [immutableData bytes], 5);