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