@@ -133,13 +133,30 @@ bool lldb_private::formatters::NSTimeZoneSummaryProvider(
133133 return true ;
134134 }
135135 } else if (class_name == " _NSSwiftTimeZone" ) {
136+ // CFTimeZoneRef is declared as follows:
137+ // typedef const struct CF_BRIDGED_TYPE(NSTimeZone) __CFTimeZone *
138+ // CFTimeZoneRef;
139+ // From the available debug info, this appears to lldb as pointer to an
140+ // opaque type, not an ObjC object. As a result, lldb does not correctly
141+ // determine the correct dynamic type (because it doesn't try ObjC). With no
142+ // dynamic type, this summary provider cannot access the inner `identifier`
143+ // property.
144+ //
145+ // The fix here is to explicitly cast the value as `id`, and get the dynamic
146+ // value from there.
147+ ValueObjectSP dyn_valobj_sp;
148+ if (valobj.GetTypeName () == " CFTimeZoneRef" ) {
149+ auto id_type =
150+ valobj.GetCompilerType ().GetBasicTypeFromAST (lldb::eBasicTypeObjCID);
151+ dyn_valobj_sp = valobj.Cast (id_type)->GetDynamicValue (
152+ DynamicValueType::eDynamicDontRunTarget);
153+ }
154+
155+ ValueObject &time_zone = dyn_valobj_sp ? *dyn_valobj_sp : valobj;
136156 llvm::ArrayRef<ConstString> identifier_path = {
137- ConstString (" timeZone" ),
138- ConstString (" _timeZone" ),
139- ConstString (" some" ),
140- ConstString (" identifier" ),
141- };
142- if (auto identifier_sp = valobj.GetChildAtNamePath (identifier_path)) {
157+ ConstString (" some" ), ConstString (" timeZone" ), ConstString (" _timeZone" ),
158+ ConstString (" some" ), ConstString (" identifier" )};
159+ if (auto identifier_sp = time_zone.GetChildAtNamePath (identifier_path)) {
143160 std::string desc;
144161 if (identifier_sp->GetSummaryAsCString (desc, options)) {
145162 stream.PutCString (desc);
0 commit comments