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