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
Initialize()38 void ObjCLanguage::Initialize() {
39 PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language",
40 CreateInstance);
41 }
42
Terminate()43 void ObjCLanguage::Terminate() {
44 PluginManager::UnregisterPlugin(CreateInstance);
45 }
46
GetPluginNameStatic()47 lldb_private::ConstString ObjCLanguage::GetPluginNameStatic() {
48 static ConstString g_name("objc");
49 return g_name;
50 }
51
52 //------------------------------------------------------------------
53 // PluginInterface protocol
54 //------------------------------------------------------------------
55
GetPluginName()56 lldb_private::ConstString ObjCLanguage::GetPluginName() {
57 return GetPluginNameStatic();
58 }
59
GetPluginVersion()60 uint32_t ObjCLanguage::GetPluginVersion() { return 1; }
61
62 //------------------------------------------------------------------
63 // Static Functions
64 //------------------------------------------------------------------
65
CreateInstance(lldb::LanguageType language)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
Clear()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
SetName(llvm::StringRef name,bool strict)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
SetName(const char * name,bool strict)119 bool ObjCLanguage::MethodName::SetName(const char *name, bool strict) {
120 return SetName(llvm::StringRef(name), strict);
121 }
122
GetClassName()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
GetClassNameWithCategory()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
GetSelector()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
GetCategory()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
GetFullNameWithoutCategory(bool empty_if_no_category)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
GetFullNames(std::vector<ConstString> & names,bool append)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
LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)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
LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp)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
GetFormatters()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>
GetPossibleFormattersMatches(ValueObject & valobj,lldb::DynamicValueType use_dynamic)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
GetTypeScavenger()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
GetFormatterPrefixSuffix(ValueObject & valobj,ConstString type_hint,std::string & prefix,std::string & suffix)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
IsNilReference(ValueObject & valobj)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
IsSourceFile(llvm::StringRef file_path) const1109 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 }
1117