@@ -133,13 +133,30 @@ bool lldb_private::formatters::NSTimeZoneSummaryProvider(
133
133
return true ;
134
134
}
135
135
} 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;
136
156
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)) {
143
160
std::string desc;
144
161
if (identifier_sp->GetSummaryAsCString (desc, options)) {
145
162
stream.PutCString (desc);
0 commit comments