]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
Update Apache Serf to 1.3.9 to support OpenSSL 1.1.1.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Language / ObjC / ObjCLanguage.cpp
1 //===-- ObjCLanguage.cpp ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C Includes
11 // C++ Includes
12 #include <mutex>
13
14 // Other libraries and framework includes
15 // Project includes
16 #include "ObjCLanguage.h"
17
18 #include "lldb/Core/PluginManager.h"
19 #include "lldb/Core/ValueObject.h"
20 #include "lldb/DataFormatters/DataVisualization.h"
21 #include "lldb/DataFormatters/FormattersHelpers.h"
22 #include "lldb/Symbol/ClangASTContext.h"
23 #include "lldb/Symbol/CompilerType.h"
24 #include "lldb/Target/ObjCLanguageRuntime.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Utility/ConstString.h"
27 #include "lldb/Utility/StreamString.h"
28
29 #include "llvm/Support/Threading.h"
30
31 #include "CF.h"
32 #include "Cocoa.h"
33 #include "CoreMedia.h"
34 #include "NSDictionary.h"
35 #include "NSSet.h"
36 #include "NSString.h"
37
38 using namespace lldb;
39 using namespace lldb_private;
40 using namespace lldb_private::formatters;
41
42 void ObjCLanguage::Initialize() {
43   PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language",
44                                 CreateInstance);
45 }
46
47 void ObjCLanguage::Terminate() {
48   PluginManager::UnregisterPlugin(CreateInstance);
49 }
50
51 lldb_private::ConstString ObjCLanguage::GetPluginNameStatic() {
52   static ConstString g_name("objc");
53   return g_name;
54 }
55
56 //------------------------------------------------------------------
57 // PluginInterface protocol
58 //------------------------------------------------------------------
59
60 lldb_private::ConstString ObjCLanguage::GetPluginName() {
61   return GetPluginNameStatic();
62 }
63
64 uint32_t ObjCLanguage::GetPluginVersion() { return 1; }
65
66 //------------------------------------------------------------------
67 // Static Functions
68 //------------------------------------------------------------------
69
70 Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) {
71   switch (language) {
72   case lldb::eLanguageTypeObjC:
73     return new ObjCLanguage();
74   default:
75     return nullptr;
76   }
77 }
78
79 void ObjCLanguage::MethodName::Clear() {
80   m_full.Clear();
81   m_class.Clear();
82   m_category.Clear();
83   m_selector.Clear();
84   m_type = eTypeUnspecified;
85   m_category_is_valid = false;
86 }
87
88 bool ObjCLanguage::MethodName::SetName(llvm::StringRef name, bool strict) {
89   Clear();
90   if (name.empty())
91     return IsValid(strict);
92
93   // If "strict" is true. then the method must be specified with a
94   // '+' or '-' at the beginning. If "strict" is false, then the '+'
95   // or '-' can be omitted
96   bool valid_prefix = false;
97
98   if (name.size() > 1 && (name[0] == '+' || name[0] == '-')) {
99     valid_prefix = name[1] == '[';
100     if (name[0] == '+')
101       m_type = eTypeClassMethod;
102     else
103       m_type = eTypeInstanceMethod;
104   } else if (!strict) {
105     // "strict" is false, the name just needs to start with '['
106     valid_prefix = name[0] == '[';
107   }
108
109   if (valid_prefix) {
110     int name_len = name.size();
111     // Objective C methods must have at least:
112     //      "-[" or "+[" prefix
113     //      One character for a class name
114     //      One character for the space between the class name
115     //      One character for the method name
116     //      "]" suffix
117     if (name_len >= (5 + (strict ? 1 : 0)) && name.back() == ']') {
118       m_full.SetString(name);
119     }
120   }
121   return IsValid(strict);
122 }
123
124 bool ObjCLanguage::MethodName::SetName(const char *name, bool strict) {
125   return SetName(llvm::StringRef(name), strict);
126 }
127
128 const ConstString &ObjCLanguage::MethodName::GetClassName() {
129   if (!m_class) {
130     if (IsValid(false)) {
131       const char *full = m_full.GetCString();
132       const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
133       const char *paren_pos = strchr(class_start, '(');
134       if (paren_pos) {
135         m_class.SetCStringWithLength(class_start, paren_pos - class_start);
136       } else {
137         // No '(' was found in the full name, we can definitively say
138         // that our category was valid (and empty).
139         m_category_is_valid = true;
140         const char *space_pos = strchr(full, ' ');
141         if (space_pos) {
142           m_class.SetCStringWithLength(class_start, space_pos - class_start);
143           if (!m_class_category) {
144             // No category in name, so we can also fill in the m_class_category
145             m_class_category = m_class;
146           }
147         }
148       }
149     }
150   }
151   return m_class;
152 }
153
154 const ConstString &ObjCLanguage::MethodName::GetClassNameWithCategory() {
155   if (!m_class_category) {
156     if (IsValid(false)) {
157       const char *full = m_full.GetCString();
158       const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
159       const char *space_pos = strchr(full, ' ');
160       if (space_pos) {
161         m_class_category.SetCStringWithLength(class_start,
162                                               space_pos - class_start);
163         // If m_class hasn't been filled in and the class with category doesn't
164         // contain a '(', then we can also fill in the m_class
165         if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr) {
166           m_class = m_class_category;
167           // No '(' was found in the full name, we can definitively say
168           // that our category was valid (and empty).
169           m_category_is_valid = true;
170         }
171       }
172     }
173   }
174   return m_class_category;
175 }
176
177 const ConstString &ObjCLanguage::MethodName::GetSelector() {
178   if (!m_selector) {
179     if (IsValid(false)) {
180       const char *full = m_full.GetCString();
181       const char *space_pos = strchr(full, ' ');
182       if (space_pos) {
183         ++space_pos; // skip the space
184         m_selector.SetCStringWithLength(space_pos, m_full.GetLength() -
185                                                        (space_pos - full) - 1);
186       }
187     }
188   }
189   return m_selector;
190 }
191
192 const ConstString &ObjCLanguage::MethodName::GetCategory() {
193   if (!m_category_is_valid && !m_category) {
194     if (IsValid(false)) {
195       m_category_is_valid = true;
196       const char *full = m_full.GetCString();
197       const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
198       const char *open_paren_pos = strchr(class_start, '(');
199       if (open_paren_pos) {
200         ++open_paren_pos; // Skip the open paren
201         const char *close_paren_pos = strchr(open_paren_pos, ')');
202         if (close_paren_pos)
203           m_category.SetCStringWithLength(open_paren_pos,
204                                           close_paren_pos - open_paren_pos);
205       }
206     }
207   }
208   return m_category;
209 }
210
211 ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory(
212     bool empty_if_no_category) {
213   if (IsValid(false)) {
214     if (HasCategory()) {
215       StreamString strm;
216       if (m_type == eTypeClassMethod)
217         strm.PutChar('+');
218       else if (m_type == eTypeInstanceMethod)
219         strm.PutChar('-');
220       strm.Printf("[%s %s]", GetClassName().GetCString(),
221                   GetSelector().GetCString());
222       return ConstString(strm.GetString());
223     }
224
225     if (!empty_if_no_category) {
226       // Just return the full name since it doesn't have a category
227       return GetFullName();
228     }
229   }
230   return ConstString();
231 }
232
233 size_t ObjCLanguage::MethodName::GetFullNames(std::vector<ConstString> &names,
234                                               bool append) {
235   if (!append)
236     names.clear();
237   if (IsValid(false)) {
238     StreamString strm;
239     const bool is_class_method = m_type == eTypeClassMethod;
240     const bool is_instance_method = m_type == eTypeInstanceMethod;
241     const ConstString &category = GetCategory();
242     if (is_class_method || is_instance_method) {
243       names.push_back(m_full);
244       if (category) {
245         strm.Printf("%c[%s %s]", is_class_method ? '+' : '-',
246                     GetClassName().GetCString(), GetSelector().GetCString());
247         names.emplace_back(strm.GetString());
248       }
249     } else {
250       const ConstString &class_name = GetClassName();
251       const ConstString &selector = GetSelector();
252       strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
253       names.emplace_back(strm.GetString());
254       strm.Clear();
255       strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
256       names.emplace_back(strm.GetString());
257       strm.Clear();
258       if (category) {
259         strm.Printf("+[%s(%s) %s]", class_name.GetCString(),
260                     category.GetCString(), selector.GetCString());
261         names.emplace_back(strm.GetString());
262         strm.Clear();
263         strm.Printf("-[%s(%s) %s]", class_name.GetCString(),
264                     category.GetCString(), selector.GetCString());
265         names.emplace_back(strm.GetString());
266       }
267     }
268   }
269   return names.size();
270 }
271
272 static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
273   if (!objc_category_sp)
274     return;
275
276   TypeSummaryImpl::Flags objc_flags;
277   objc_flags.SetCascades(false)
278       .SetSkipPointers(true)
279       .SetSkipReferences(true)
280       .SetDontShowChildren(true)
281       .SetDontShowValue(true)
282       .SetShowMembersOneLiner(false)
283       .SetHideItemNames(false);
284
285   lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(
286       objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider, ""));
287   objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"),
288                                                      ObjC_BOOL_summary);
289   objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"),
290                                                      ObjC_BOOL_summary);
291   objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"),
292                                                      ObjC_BOOL_summary);
293
294 #ifndef LLDB_DISABLE_PYTHON
295   // we need to skip pointers here since we are special casing a SEL* when
296   // retrieving its value
297   objc_flags.SetSkipPointers(true);
298   AddCXXSummary(objc_category_sp,
299                 lldb_private::formatters::ObjCSELSummaryProvider<false>,
300                 "SEL summary provider", ConstString("SEL"), objc_flags);
301   AddCXXSummary(
302       objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
303       "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
304   AddCXXSummary(
305       objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
306       "SEL summary provider", ConstString("objc_selector"), objc_flags);
307   AddCXXSummary(
308       objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>,
309       "SEL summary provider", ConstString("objc_selector *"), objc_flags);
310   AddCXXSummary(objc_category_sp,
311                 lldb_private::formatters::ObjCSELSummaryProvider<true>,
312                 "SEL summary provider", ConstString("SEL *"), objc_flags);
313
314   AddCXXSummary(objc_category_sp,
315                 lldb_private::formatters::ObjCClassSummaryProvider,
316                 "Class summary provider", ConstString("Class"), objc_flags);
317
318   SyntheticChildren::Flags class_synth_flags;
319   class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
320       false);
321
322   AddCXXSynthetic(objc_category_sp,
323                   lldb_private::formatters::ObjCClassSyntheticFrontEndCreator,
324                   "Class synthetic children", ConstString("Class"),
325                   class_synth_flags);
326 #endif // LLDB_DISABLE_PYTHON
327
328   objc_flags.SetSkipPointers(false);
329   objc_flags.SetCascades(true);
330   objc_flags.SetSkipReferences(false);
331
332   AddStringSummary(objc_category_sp, "${var.__FuncPtr%A}",
333                    ConstString("__block_literal_generic"), objc_flags);
334
335   AddStringSummary(objc_category_sp, "${var.years} years, ${var.months} "
336                                      "months, ${var.days} days, ${var.hours} "
337                                      "hours, ${var.minutes} minutes "
338                                      "${var.seconds} seconds",
339                    ConstString("CFGregorianUnits"), objc_flags);
340   AddStringSummary(objc_category_sp,
341                    "location=${var.location} length=${var.length}",
342                    ConstString("CFRange"), objc_flags);
343
344   AddStringSummary(objc_category_sp,
345                    "location=${var.location}, length=${var.length}",
346                    ConstString("NSRange"), objc_flags);
347   AddStringSummary(objc_category_sp, "(${var.origin}, ${var.size}), ...",
348                    ConstString("NSRectArray"), objc_flags);
349
350   AddOneLineSummary(objc_category_sp, ConstString("NSPoint"), objc_flags);
351   AddOneLineSummary(objc_category_sp, ConstString("NSSize"), objc_flags);
352   AddOneLineSummary(objc_category_sp, ConstString("NSRect"), objc_flags);
353
354   AddOneLineSummary(objc_category_sp, ConstString("CGSize"), objc_flags);
355   AddOneLineSummary(objc_category_sp, ConstString("CGPoint"), objc_flags);
356   AddOneLineSummary(objc_category_sp, ConstString("CGRect"), objc_flags);
357
358   AddStringSummary(objc_category_sp,
359                    "red=${var.red} green=${var.green} blue=${var.blue}",
360                    ConstString("RGBColor"), objc_flags);
361   AddStringSummary(
362       objc_category_sp,
363       "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
364       ConstString("Rect"), objc_flags);
365   AddStringSummary(objc_category_sp, "{(v=${var.v}, h=${var.h})}",
366                    ConstString("Point"), objc_flags);
367   AddStringSummary(objc_category_sp,
368                    "${var.month}/${var.day}/${var.year}  ${var.hour} "
369                    ":${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
370                    ConstString("DateTimeRect *"), objc_flags);
371   AddStringSummary(objc_category_sp, "${var.ld.month}/${var.ld.day}/"
372                                      "${var.ld.year} ${var.ld.hour} "
373                                      ":${var.ld.minute} :${var.ld.second} "
374                                      "dayOfWeek:${var.ld.dayOfWeek}",
375                    ConstString("LongDateRect"), objc_flags);
376   AddStringSummary(objc_category_sp, "(x=${var.x}, y=${var.y})",
377                    ConstString("HIPoint"), objc_flags);
378   AddStringSummary(objc_category_sp, "origin=${var.origin} size=${var.size}",
379                    ConstString("HIRect"), objc_flags);
380
381   TypeSummaryImpl::Flags appkit_flags;
382   appkit_flags.SetCascades(true)
383       .SetSkipPointers(false)
384       .SetSkipReferences(false)
385       .SetDontShowChildren(true)
386       .SetDontShowValue(false)
387       .SetShowMembersOneLiner(false)
388       .SetHideItemNames(false);
389
390   appkit_flags.SetDontShowChildren(false);
391
392 #ifndef LLDB_DISABLE_PYTHON
393   AddCXXSummary(
394       objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
395       "NSArray summary provider", ConstString("NSArray"), appkit_flags);
396   AddCXXSummary(
397       objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
398       "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
399   AddCXXSummary(
400       objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
401       "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
402   AddCXXSummary(
403       objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
404       "NSArray summary provider", ConstString("__NSArray0"), appkit_flags);
405   AddCXXSummary(objc_category_sp,
406                 lldb_private::formatters::NSArraySummaryProvider,
407                 "NSArray summary provider",
408                 ConstString("__NSSingleObjectArrayI"), appkit_flags);
409   AddCXXSummary(
410       objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
411       "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
412   AddCXXSummary(
413       objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
414       "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
415   AddCXXSummary(
416       objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
417       "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
418   AddCXXSummary(objc_category_sp,
419                 lldb_private::formatters::NSArraySummaryProvider,
420                 "NSArray summary provider", ConstString("CFMutableArrayRef"),
421                 appkit_flags);
422
423   AddCXXSummary(objc_category_sp,
424                 lldb_private::formatters::NSDictionarySummaryProvider<false>,
425                 "NSDictionary summary provider", ConstString("NSDictionary"),
426                 appkit_flags);
427   AddCXXSummary(objc_category_sp,
428                 lldb_private::formatters::NSDictionarySummaryProvider<false>,
429                 "NSDictionary summary provider",
430                 ConstString("NSMutableDictionary"), appkit_flags);
431   AddCXXSummary(objc_category_sp,
432                 lldb_private::formatters::NSDictionarySummaryProvider<false>,
433                 "NSDictionary summary provider",
434                 ConstString("__NSCFDictionary"), appkit_flags);
435   AddCXXSummary(objc_category_sp,
436                 lldb_private::formatters::NSDictionarySummaryProvider<false>,
437                 "NSDictionary summary provider", ConstString("__NSDictionaryI"),
438                 appkit_flags);
439   AddCXXSummary(objc_category_sp,
440                 lldb_private::formatters::NSDictionarySummaryProvider<false>,
441                 "NSDictionary summary provider",
442                 ConstString("__NSSingleEntryDictionaryI"), appkit_flags);
443   AddCXXSummary(objc_category_sp,
444                 lldb_private::formatters::NSDictionarySummaryProvider<false>,
445                 "NSDictionary summary provider", ConstString("__NSDictionaryM"),
446                 appkit_flags);
447   AddCXXSummary(objc_category_sp,
448                 lldb_private::formatters::NSDictionarySummaryProvider<true>,
449                 "NSDictionary summary provider", ConstString("CFDictionaryRef"),
450                 appkit_flags);
451   AddCXXSummary(objc_category_sp,
452                 lldb_private::formatters::NSDictionarySummaryProvider<true>,
453                 "NSDictionary summary provider",
454                 ConstString("CFMutableDictionaryRef"), appkit_flags);
455
456   AddCXXSummary(objc_category_sp,
457                 lldb_private::formatters::NSSetSummaryProvider<false>,
458                 "NSSet summary", ConstString("NSSet"), appkit_flags);
459   AddCXXSummary(
460       objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
461       "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
462   AddCXXSummary(objc_category_sp,
463                 lldb_private::formatters::NSSetSummaryProvider<true>,
464                 "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
465   AddCXXSummary(
466       objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>,
467       "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
468   AddCXXSummary(objc_category_sp,
469                 lldb_private::formatters::NSSetSummaryProvider<false>,
470                 "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
471   AddCXXSummary(objc_category_sp,
472                 lldb_private::formatters::NSSetSummaryProvider<false>,
473                 "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
474   AddCXXSummary(objc_category_sp,
475                 lldb_private::formatters::NSSetSummaryProvider<false>,
476                 "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
477   AddCXXSummary(
478       objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
479       "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
480   AddCXXSummary(
481       objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
482       "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
483   AddCXXSummary(
484       objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
485       "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags);
486   AddCXXSummary(
487       objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
488       "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags);
489   AddCXXSummary(
490       objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
491       "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags);
492
493   AddCXXSummary(
494       objc_category_sp, lldb_private::formatters::NSError_SummaryProvider,
495       "NSError summary provider", ConstString("NSError"), appkit_flags);
496   AddCXXSummary(
497       objc_category_sp, lldb_private::formatters::NSException_SummaryProvider,
498       "NSException summary provider", ConstString("NSException"), appkit_flags);
499
500   // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}",
501   // ConstString("$_lldb_typegen_nspair"), appkit_flags);
502
503   appkit_flags.SetDontShowChildren(true);
504
505   AddCXXSynthetic(objc_category_sp,
506                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
507                   "NSArray synthetic children", ConstString("__NSArrayM"),
508                   ScriptedSyntheticChildren::Flags());
509   AddCXXSynthetic(objc_category_sp,
510                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
511                   "NSArray synthetic children", ConstString("__NSArrayI"),
512                   ScriptedSyntheticChildren::Flags());
513   AddCXXSynthetic(objc_category_sp,
514                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
515                   "NSArray synthetic children", ConstString("__NSArray0"),
516                   ScriptedSyntheticChildren::Flags());
517   AddCXXSynthetic(objc_category_sp,
518                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
519                   "NSArray synthetic children",
520                   ConstString("__NSSingleObjectArrayI"),
521                   ScriptedSyntheticChildren::Flags());
522   AddCXXSynthetic(objc_category_sp,
523                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
524                   "NSArray synthetic children", ConstString("NSArray"),
525                   ScriptedSyntheticChildren::Flags());
526   AddCXXSynthetic(objc_category_sp,
527                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
528                   "NSArray synthetic children", ConstString("NSMutableArray"),
529                   ScriptedSyntheticChildren::Flags());
530   AddCXXSynthetic(objc_category_sp,
531                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
532                   "NSArray synthetic children", ConstString("__NSCFArray"),
533                   ScriptedSyntheticChildren::Flags());
534   AddCXXSynthetic(objc_category_sp,
535                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
536                   "NSArray synthetic children",
537                   ConstString("CFMutableArrayRef"),
538                   ScriptedSyntheticChildren::Flags());
539   AddCXXSynthetic(objc_category_sp,
540                   lldb_private::formatters::NSArraySyntheticFrontEndCreator,
541                   "NSArray synthetic children", ConstString("CFArrayRef"),
542                   ScriptedSyntheticChildren::Flags());
543
544   AddCXXSynthetic(
545       objc_category_sp,
546       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
547       "NSDictionary synthetic children", ConstString("__NSDictionaryM"),
548       ScriptedSyntheticChildren::Flags());
549   AddCXXSynthetic(
550       objc_category_sp,
551       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
552       "NSDictionary synthetic children", ConstString("__NSDictionaryI"),
553       ScriptedSyntheticChildren::Flags());
554   AddCXXSynthetic(
555       objc_category_sp,
556       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
557       "NSDictionary synthetic children",
558       ConstString("__NSSingleEntryDictionaryI"),
559       ScriptedSyntheticChildren::Flags());
560   AddCXXSynthetic(
561       objc_category_sp,
562       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
563       "NSDictionary synthetic children", ConstString("__NSCFDictionary"),
564       ScriptedSyntheticChildren::Flags());
565   AddCXXSynthetic(
566       objc_category_sp,
567       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
568       "NSDictionary synthetic children", ConstString("NSDictionary"),
569       ScriptedSyntheticChildren::Flags());
570   AddCXXSynthetic(
571       objc_category_sp,
572       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
573       "NSDictionary synthetic children", ConstString("NSMutableDictionary"),
574       ScriptedSyntheticChildren::Flags());
575   AddCXXSynthetic(
576       objc_category_sp,
577       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
578       "NSDictionary synthetic children", ConstString("CFDictionaryRef"),
579       ScriptedSyntheticChildren::Flags());
580   AddCXXSynthetic(
581       objc_category_sp,
582       lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
583       "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"),
584       ScriptedSyntheticChildren::Flags());
585
586   AddCXXSynthetic(objc_category_sp,
587                   lldb_private::formatters::NSErrorSyntheticFrontEndCreator,
588                   "NSError synthetic children", ConstString("NSError"),
589                   ScriptedSyntheticChildren::Flags());
590   AddCXXSynthetic(objc_category_sp,
591                   lldb_private::formatters::NSExceptionSyntheticFrontEndCreator,
592                   "NSException synthetic children", ConstString("NSException"),
593                   ScriptedSyntheticChildren::Flags());
594
595   AddCXXSynthetic(objc_category_sp,
596                   lldb_private::formatters::NSSetSyntheticFrontEndCreator,
597                   "NSSet synthetic children", ConstString("NSSet"),
598                   ScriptedSyntheticChildren::Flags());
599   AddCXXSynthetic(objc_category_sp,
600                   lldb_private::formatters::NSSetSyntheticFrontEndCreator,
601                   "__NSSetI synthetic children", ConstString("__NSSetI"),
602                   ScriptedSyntheticChildren::Flags());
603   AddCXXSynthetic(objc_category_sp,
604                   lldb_private::formatters::NSSetSyntheticFrontEndCreator,
605                   "__NSSetM synthetic children", ConstString("__NSSetM"),
606                   ScriptedSyntheticChildren::Flags());
607   AddCXXSynthetic(
608       objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
609       "NSMutableSet synthetic children", ConstString("NSMutableSet"),
610       ScriptedSyntheticChildren::Flags());
611   AddCXXSynthetic(
612       objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
613       "NSOrderedSet synthetic children", ConstString("NSOrderedSet"),
614       ScriptedSyntheticChildren::Flags());
615   AddCXXSynthetic(
616       objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
617       "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"),
618       ScriptedSyntheticChildren::Flags());
619   AddCXXSynthetic(
620       objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
621       "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"),
622       ScriptedSyntheticChildren::Flags());
623
624   AddCXXSynthetic(objc_category_sp,
625                   lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator,
626                   "NSIndexPath synthetic children", ConstString("NSIndexPath"),
627                   ScriptedSyntheticChildren::Flags());
628
629   AddCXXSummary(
630       objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
631       "CFBag summary provider", ConstString("CFBagRef"), appkit_flags);
632   AddCXXSummary(objc_category_sp,
633                 lldb_private::formatters::CFBagSummaryProvider,
634                 "CFBag summary provider", ConstString("__CFBag"), appkit_flags);
635   AddCXXSummary(objc_category_sp,
636                 lldb_private::formatters::CFBagSummaryProvider,
637                 "CFBag summary provider", ConstString("const struct __CFBag"),
638                 appkit_flags);
639   AddCXXSummary(
640       objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
641       "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags);
642
643   AddCXXSummary(objc_category_sp,
644                 lldb_private::formatters::CFBinaryHeapSummaryProvider,
645                 "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"),
646                 appkit_flags);
647   AddCXXSummary(objc_category_sp,
648                 lldb_private::formatters::CFBinaryHeapSummaryProvider,
649                 "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"),
650                 appkit_flags);
651
652   AddCXXSummary(
653       objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
654       "NSString summary provider", ConstString("NSString"), appkit_flags);
655   AddCXXSummary(
656       objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
657       "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
658   AddCXXSummary(
659       objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
660       "NSString summary provider", ConstString("__CFString"), appkit_flags);
661   AddCXXSummary(objc_category_sp,
662                 lldb_private::formatters::NSStringSummaryProvider,
663                 "NSString summary provider", ConstString("CFMutableStringRef"),
664                 appkit_flags);
665   AddCXXSummary(objc_category_sp,
666                 lldb_private::formatters::NSStringSummaryProvider,
667                 "NSString summary provider", ConstString("NSMutableString"),
668                 appkit_flags);
669   AddCXXSummary(objc_category_sp,
670                 lldb_private::formatters::NSStringSummaryProvider,
671                 "NSString summary provider",
672                 ConstString("__NSCFConstantString"), appkit_flags);
673   AddCXXSummary(
674       objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
675       "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
676   AddCXXSummary(objc_category_sp,
677                 lldb_private::formatters::NSStringSummaryProvider,
678                 "NSString summary provider", ConstString("NSCFConstantString"),
679                 appkit_flags);
680   AddCXXSummary(
681       objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
682       "NSString summary provider", ConstString("NSCFString"), appkit_flags);
683   AddCXXSummary(
684       objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
685       "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
686   AddCXXSummary(objc_category_sp,
687                 lldb_private::formatters::NSStringSummaryProvider,
688                 "NSString summary provider",
689                 ConstString("NSTaggedPointerString"), appkit_flags);
690
691   AddCXXSummary(objc_category_sp,
692                 lldb_private::formatters::NSAttributedStringSummaryProvider,
693                 "NSAttributedString summary provider",
694                 ConstString("NSAttributedString"), appkit_flags);
695   AddCXXSummary(
696       objc_category_sp,
697       lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
698       "NSMutableAttributedString summary provider",
699       ConstString("NSMutableAttributedString"), appkit_flags);
700   AddCXXSummary(
701       objc_category_sp,
702       lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
703       "NSMutableAttributedString summary provider",
704       ConstString("NSConcreteMutableAttributedString"), appkit_flags);
705
706   AddCXXSummary(
707       objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider,
708       "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
709
710   AddCXXSummary(objc_category_sp,
711                 lldb_private::formatters::NSDataSummaryProvider<false>,
712                 "NSData summary provider", ConstString("NSData"), appkit_flags);
713   AddCXXSummary(
714       objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
715       "NSData summary provider", ConstString("_NSInlineData"), appkit_flags);
716   AddCXXSummary(
717       objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
718       "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
719   AddCXXSummary(objc_category_sp,
720                 lldb_private::formatters::NSDataSummaryProvider<false>,
721                 "NSData summary provider", ConstString("NSConcreteMutableData"),
722                 appkit_flags);
723   AddCXXSummary(
724       objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
725       "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
726   AddCXXSummary(
727       objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
728       "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
729   AddCXXSummary(
730       objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
731       "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
732   AddCXXSummary(
733       objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
734       "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
735
736   AddCXXSummary(
737       objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider,
738       "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags);
739
740   AddCXXSummary(objc_category_sp,
741                 lldb_private::formatters::NSNotificationSummaryProvider,
742                 "NSNotification summary provider",
743                 ConstString("NSNotification"), appkit_flags);
744   AddCXXSummary(objc_category_sp,
745                 lldb_private::formatters::NSNotificationSummaryProvider,
746                 "NSNotification summary provider",
747                 ConstString("NSConcreteNotification"), appkit_flags);
748
749   AddCXXSummary(
750       objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
751       "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
752   AddCXXSummary(
753       objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
754       "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
755   AddCXXSummary(
756       objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
757       "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
758   AddCXXSummary(
759       objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
760       "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
761   AddCXXSummary(
762       objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
763       "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
764   AddCXXSummary(
765       objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
766       "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
767
768   AddCXXSummary(objc_category_sp,
769                 lldb_private::formatters::NSURLSummaryProvider,
770                 "NSURL summary provider", ConstString("NSURL"), appkit_flags);
771   AddCXXSummary(
772       objc_category_sp, lldb_private::formatters::NSURLSummaryProvider,
773       "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
774
775   AddCXXSummary(objc_category_sp,
776                 lldb_private::formatters::NSDateSummaryProvider,
777                 "NSDate summary provider", ConstString("NSDate"), appkit_flags);
778   AddCXXSummary(
779       objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
780       "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
781   AddCXXSummary(
782       objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
783       "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
784   AddCXXSummary(
785       objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
786       "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
787
788   AddCXXSummary(
789       objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
790       "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags);
791   AddCXXSummary(objc_category_sp,
792                 lldb_private::formatters::NSTimeZoneSummaryProvider,
793                 "NSTimeZone summary provider", ConstString("CFTimeZoneRef"),
794                 appkit_flags);
795   AddCXXSummary(
796       objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
797       "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
798
799   // CFAbsoluteTime is actually a double rather than a pointer to an object
800   // we do not care about the numeric value, since it is probably meaningless to
801   // users
802   appkit_flags.SetDontShowValue(true);
803   AddCXXSummary(objc_category_sp,
804                 lldb_private::formatters::CFAbsoluteTimeSummaryProvider,
805                 "CFAbsoluteTime summary provider",
806                 ConstString("CFAbsoluteTime"), appkit_flags);
807   appkit_flags.SetDontShowValue(false);
808
809   AddCXXSummary(
810       objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider,
811       "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags);
812   AddCXXSummary(objc_category_sp,
813                 lldb_private::formatters::NSIndexSetSummaryProvider,
814                 "NSIndexSet summary provider", ConstString("NSMutableIndexSet"),
815                 appkit_flags);
816
817   AddStringSummary(objc_category_sp,
818                    "@\"${var.month%d}/${var.day%d}/${var.year%d} "
819                    "${var.hour%d}:${var.minute%d}:${var.second}\"",
820                    ConstString("CFGregorianDate"), appkit_flags);
821
822   AddCXXSummary(objc_category_sp,
823                 lldb_private::formatters::CFBitVectorSummaryProvider,
824                 "CFBitVector summary provider", ConstString("CFBitVectorRef"),
825                 appkit_flags);
826   AddCXXSummary(objc_category_sp,
827                 lldb_private::formatters::CFBitVectorSummaryProvider,
828                 "CFBitVector summary provider",
829                 ConstString("CFMutableBitVectorRef"), appkit_flags);
830   AddCXXSummary(objc_category_sp,
831                 lldb_private::formatters::CFBitVectorSummaryProvider,
832                 "CFBitVector summary provider", ConstString("__CFBitVector"),
833                 appkit_flags);
834   AddCXXSummary(objc_category_sp,
835                 lldb_private::formatters::CFBitVectorSummaryProvider,
836                 "CFBitVector summary provider",
837                 ConstString("__CFMutableBitVector"), appkit_flags);
838 #endif // LLDB_DISABLE_PYTHON
839 }
840
841 static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) {
842   if (!objc_category_sp)
843     return;
844
845   TypeSummaryImpl::Flags cm_flags;
846   cm_flags.SetCascades(true)
847       .SetDontShowChildren(false)
848       .SetDontShowValue(false)
849       .SetHideItemNames(false)
850       .SetShowMembersOneLiner(false)
851       .SetSkipPointers(false)
852       .SetSkipReferences(false);
853
854 #ifndef LLDB_DISABLE_PYTHON
855   AddCXXSummary(objc_category_sp,
856                 lldb_private::formatters::CMTimeSummaryProvider,
857                 "CMTime summary provider", ConstString("CMTime"), cm_flags);
858 #endif // LLDB_DISABLE_PYTHON
859 }
860
861 lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() {
862   static llvm::once_flag g_initialize;
863   static TypeCategoryImplSP g_category;
864
865   llvm::call_once(g_initialize, [this]() -> void {
866     DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
867     if (g_category) {
868       LoadCoreMediaFormatters(g_category);
869       LoadObjCFormatters(g_category);
870     }
871   });
872   return g_category;
873 }
874
875 std::vector<ConstString>
876 ObjCLanguage::GetPossibleFormattersMatches(ValueObject &valobj,
877                                            lldb::DynamicValueType use_dynamic) {
878   std::vector<ConstString> result;
879
880   if (use_dynamic == lldb::eNoDynamicValues)
881     return result;
882
883   CompilerType compiler_type(valobj.GetCompilerType());
884
885   const bool check_cpp = false;
886   const bool check_objc = true;
887   bool canBeObjCDynamic =
888       compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
889
890   if (canBeObjCDynamic) {
891     do {
892       lldb::ProcessSP process_sp = valobj.GetProcessSP();
893       if (!process_sp)
894         break;
895       ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
896       if (runtime == nullptr)
897         break;
898       ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp(
899           runtime->GetClassDescriptor(valobj));
900       if (!objc_class_sp)
901         break;
902       if (ConstString name = objc_class_sp->GetClassName())
903         result.push_back(name);
904     } while (false);
905   }
906
907   return result;
908 }
909
910 std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {
911   class ObjCScavengerResult : public Language::TypeScavenger::Result {
912   public:
913     ObjCScavengerResult(CompilerType type)
914         : Language::TypeScavenger::Result(), m_compiler_type(type) {}
915
916     bool IsValid() override { return m_compiler_type.IsValid(); }
917
918     bool DumpToStream(Stream &stream, bool print_help_if_available) override {
919       if (IsValid()) {
920         m_compiler_type.DumpTypeDescription(&stream);
921         stream.EOL();
922         return true;
923       }
924       return false;
925     }
926
927   private:
928     CompilerType m_compiler_type;
929   };
930
931   class ObjCRuntimeScavenger : public Language::TypeScavenger {
932   protected:
933     bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
934                    ResultSet &results) override {
935       bool result = false;
936
937       Process *process = exe_scope->CalculateProcess().get();
938       if (process) {
939         const bool create_on_demand = false;
940         auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
941         if (objc_runtime) {
942           auto decl_vendor = objc_runtime->GetDeclVendor();
943           if (decl_vendor) {
944             std::vector<clang::NamedDecl *> decls;
945             ConstString name(key);
946             decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
947             for (auto decl : decls) {
948               if (decl) {
949                 if (CompilerType candidate =
950                         ClangASTContext::GetTypeForDecl(decl)) {
951                   result = true;
952                   std::unique_ptr<Language::TypeScavenger::Result> result(
953                       new ObjCScavengerResult(candidate));
954                   results.insert(std::move(result));
955                 }
956               }
957             }
958           }
959         }
960       }
961
962       return result;
963     }
964
965     friend class lldb_private::ObjCLanguage;
966   };
967
968   class ObjCModulesScavenger : public Language::TypeScavenger {
969   protected:
970     bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
971                    ResultSet &results) override {
972       bool result = false;
973
974       Target *target = exe_scope->CalculateTarget().get();
975       if (target) {
976         if (auto clang_modules_decl_vendor =
977                 target->GetClangModulesDeclVendor()) {
978           std::vector<clang::NamedDecl *> decls;
979           ConstString key_cs(key);
980
981           if (clang_modules_decl_vendor->FindDecls(key_cs, false, UINT32_MAX,
982                                                    decls) > 0 &&
983               !decls.empty()) {
984             CompilerType module_type =
985                 ClangASTContext::GetTypeForDecl(decls.front());
986             result = true;
987             std::unique_ptr<Language::TypeScavenger::Result> result(
988                 new ObjCScavengerResult(module_type));
989             results.insert(std::move(result));
990           }
991         }
992       }
993
994       return result;
995     }
996
997     friend class lldb_private::ObjCLanguage;
998   };
999   
1000   class ObjCDebugInfoScavenger : public Language::ImageListTypeScavenger {
1001   public:
1002     virtual CompilerType AdjustForInclusion(CompilerType &candidate) override {
1003       LanguageType lang_type(candidate.GetMinimumLanguage());
1004       if (!Language::LanguageIsObjC(lang_type))
1005         return CompilerType();
1006       if (candidate.IsTypedefType())
1007         return candidate.GetTypedefedType();
1008       return candidate;
1009     }
1010   };
1011
1012   return std::unique_ptr<TypeScavenger>(
1013       new Language::EitherTypeScavenger<ObjCModulesScavenger,
1014                                         ObjCRuntimeScavenger,
1015                                         ObjCDebugInfoScavenger>());
1016 }
1017
1018 bool ObjCLanguage::GetFormatterPrefixSuffix(ValueObject &valobj,
1019                                             ConstString type_hint,
1020                                             std::string &prefix,
1021                                             std::string &suffix) {
1022   static ConstString g_CFBag("CFBag");
1023   static ConstString g_CFBinaryHeap("CFBinaryHeap");
1024
1025   static ConstString g_NSNumberChar("NSNumber:char");
1026   static ConstString g_NSNumberShort("NSNumber:short");
1027   static ConstString g_NSNumberInt("NSNumber:int");
1028   static ConstString g_NSNumberLong("NSNumber:long");
1029   static ConstString g_NSNumberInt128("NSNumber:int128_t");
1030   static ConstString g_NSNumberFloat("NSNumber:float");
1031   static ConstString g_NSNumberDouble("NSNumber:double");
1032
1033   static ConstString g_NSData("NSData");
1034   static ConstString g_NSArray("NSArray");
1035   static ConstString g_NSString("NSString");
1036   static ConstString g_NSStringStar("NSString*");
1037
1038   if (type_hint.IsEmpty())
1039     return false;
1040
1041   prefix.clear();
1042   suffix.clear();
1043
1044   if (type_hint == g_CFBag || type_hint == g_CFBinaryHeap) {
1045     prefix = "@";
1046     return true;
1047   }
1048
1049   if (type_hint == g_NSNumberChar) {
1050     prefix = "(char)";
1051     return true;
1052   }
1053   if (type_hint == g_NSNumberShort) {
1054     prefix = "(short)";
1055     return true;
1056   }
1057   if (type_hint == g_NSNumberInt) {
1058     prefix = "(int)";
1059     return true;
1060   }
1061   if (type_hint == g_NSNumberLong) {
1062     prefix = "(long)";
1063     return true;
1064   }
1065   if (type_hint == g_NSNumberInt128) {
1066     prefix = "(int128_t)";
1067     return true;
1068   }
1069   if (type_hint == g_NSNumberFloat) {
1070     prefix = "(float)";
1071     return true;
1072   }
1073   if (type_hint == g_NSNumberDouble) {
1074     prefix = "(double)";
1075     return true;
1076   }
1077
1078   if (type_hint == g_NSData || type_hint == g_NSArray) {
1079     prefix = "@\"";
1080     suffix = "\"";
1081     return true;
1082   }
1083
1084   if (type_hint == g_NSString || type_hint == g_NSStringStar) {
1085     prefix = "@";
1086     return true;
1087   }
1088
1089   return false;
1090 }
1091
1092 bool ObjCLanguage::IsNilReference(ValueObject &valobj) {
1093   const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
1094   bool isObjCpointer =
1095       (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);
1096   if (!isObjCpointer)
1097     return false;
1098   bool canReadValue = true;
1099   bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
1100   return canReadValue && isZero;
1101 }