1 //===-- ObjCLanguage.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 #include "ObjCLanguage.h"
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"
25 #include "llvm/Support/Threading.h"
29 #include "CoreMedia.h"
30 #include "NSDictionary.h"
35 using namespace lldb_private;
36 using namespace lldb_private::formatters;
38 void ObjCLanguage::Initialize() {
39 PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language",
43 void ObjCLanguage::Terminate() {
44 PluginManager::UnregisterPlugin(CreateInstance);
47 lldb_private::ConstString ObjCLanguage::GetPluginNameStatic() {
48 static ConstString g_name("objc");
52 //------------------------------------------------------------------
53 // PluginInterface protocol
54 //------------------------------------------------------------------
56 lldb_private::ConstString ObjCLanguage::GetPluginName() {
57 return GetPluginNameStatic();
60 uint32_t ObjCLanguage::GetPluginVersion() { return 1; }
62 //------------------------------------------------------------------
64 //------------------------------------------------------------------
66 Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) {
68 case lldb::eLanguageTypeObjC:
69 return new ObjCLanguage();
75 void ObjCLanguage::MethodName::Clear() {
80 m_type = eTypeUnspecified;
81 m_category_is_valid = false;
84 bool ObjCLanguage::MethodName::SetName(llvm::StringRef name, bool strict) {
87 return IsValid(strict);
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;
93 if (name.size() > 1 && (name[0] == '+' || name[0] == '-')) {
94 valid_prefix = name[1] == '[';
96 m_type = eTypeClassMethod;
98 m_type = eTypeInstanceMethod;
100 // "strict" is false, the name just needs to start with '['
101 valid_prefix = name[0] == '[';
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
112 if (name_len >= (5 + (strict ? 1 : 0)) && name.back() == ']') {
113 m_full.SetString(name);
116 return IsValid(strict);
119 bool ObjCLanguage::MethodName::SetName(const char *name, bool strict) {
120 return SetName(llvm::StringRef(name), strict);
123 const ConstString &ObjCLanguage::MethodName::GetClassName() {
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, '(');
130 m_class.SetCStringWithLength(class_start, paren_pos - class_start);
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, ' ');
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;
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, ' ');
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;
169 return m_class_category;
172 const ConstString &ObjCLanguage::MethodName::GetSelector() {
174 if (IsValid(false)) {
175 const char *full = m_full.GetCString();
176 const char *space_pos = strchr(full, ' ');
178 ++space_pos; // skip the space
179 m_selector.SetCStringWithLength(space_pos, m_full.GetLength() -
180 (space_pos - full) - 1);
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, ')');
198 m_category.SetCStringWithLength(open_paren_pos,
199 close_paren_pos - open_paren_pos);
206 ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory(
207 bool empty_if_no_category) {
208 if (IsValid(false)) {
211 if (m_type == eTypeClassMethod)
213 else if (m_type == eTypeInstanceMethod)
215 strm.Printf("[%s %s]", GetClassName().GetCString(),
216 GetSelector().GetCString());
217 return ConstString(strm.GetString());
220 if (!empty_if_no_category) {
221 // Just return the full name since it doesn't have a category
222 return GetFullName();
225 return ConstString();
228 size_t ObjCLanguage::MethodName::GetFullNames(std::vector<ConstString> &names,
232 if (IsValid(false)) {
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);
240 strm.Printf("%c[%s %s]", is_class_method ? '+' : '-',
241 GetClassName().GetCString(), GetSelector().GetCString());
242 names.emplace_back(strm.GetString());
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());
250 strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
251 names.emplace_back(strm.GetString());
254 strm.Printf("+[%s(%s) %s]", class_name.GetCString(),
255 category.GetCString(), selector.GetCString());
256 names.emplace_back(strm.GetString());
258 strm.Printf("-[%s(%s) %s]", class_name.GetCString(),
259 category.GetCString(), selector.GetCString());
260 names.emplace_back(strm.GetString());
267 static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
268 if (!objc_category_sp)
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);
280 lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(
281 objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider, ""));
282 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"),
284 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"),
286 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"),
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);
297 objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
298 "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
300 objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
301 "SEL summary provider", ConstString("objc_selector"), objc_flags);
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);
309 AddCXXSummary(objc_category_sp,
310 lldb_private::formatters::ObjCClassSummaryProvider,
311 "Class summary provider", ConstString("Class"), objc_flags);
313 SyntheticChildren::Flags class_synth_flags;
314 class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
317 AddCXXSynthetic(objc_category_sp,
318 lldb_private::formatters::ObjCClassSyntheticFrontEndCreator,
319 "Class synthetic children", ConstString("Class"),
321 #endif // LLDB_DISABLE_PYTHON
323 objc_flags.SetSkipPointers(false);
324 objc_flags.SetCascades(true);
325 objc_flags.SetSkipReferences(false);
327 AddStringSummary(objc_category_sp, "${var.__FuncPtr%A}",
328 ConstString("__block_literal_generic"), objc_flags);
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);
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);
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);
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);
353 AddStringSummary(objc_category_sp,
354 "red=${var.red} green=${var.green} blue=${var.blue}",
355 ConstString("RGBColor"), objc_flags);
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);
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);
385 appkit_flags.SetDontShowChildren(false);
387 #ifndef LLDB_DISABLE_PYTHON
389 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
390 "NSArray summary provider", ConstString("NSArray"), appkit_flags);
392 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
393 "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
395 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
396 "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
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);
405 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
406 "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
408 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
409 "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
411 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
412 "NSArray summary provider", ConstString("_NSCallStackArray"), appkit_flags);
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"),
421 AddCXXSummary(objc_category_sp,
422 lldb_private::formatters::NSDictionarySummaryProvider<false>,
423 "NSDictionary summary provider", ConstString("NSDictionary"),
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"),
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"),
445 AddCXXSummary(objc_category_sp,
446 lldb_private::formatters::NSDictionarySummaryProvider<true>,
447 "NSDictionary summary provider", ConstString("CFDictionaryRef"),
449 AddCXXSummary(objc_category_sp,
450 lldb_private::formatters::NSDictionarySummaryProvider<true>,
451 "NSDictionary summary provider",
452 ConstString("CFMutableDictionaryRef"), appkit_flags);
454 AddCXXSummary(objc_category_sp,
455 lldb_private::formatters::NSSetSummaryProvider<false>,
456 "NSSet summary", ConstString("NSSet"), appkit_flags);
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);
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);
476 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
477 "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
479 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
480 "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
482 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
483 "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags);
485 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
486 "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags);
488 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
489 "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags);
492 objc_category_sp, lldb_private::formatters::NSError_SummaryProvider,
493 "NSError summary provider", ConstString("NSError"), appkit_flags);
495 objc_category_sp, lldb_private::formatters::NSException_SummaryProvider,
496 "NSException summary provider", ConstString("NSException"), appkit_flags);
498 // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}",
499 // ConstString("$_lldb_typegen_nspair"), appkit_flags);
501 appkit_flags.SetDontShowChildren(true);
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());
548 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
549 "NSDictionary synthetic children", ConstString("__NSDictionaryM"),
550 ScriptedSyntheticChildren::Flags());
553 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
554 "NSDictionary synthetic children", ConstString("__NSDictionaryI"),
555 ScriptedSyntheticChildren::Flags());
558 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
559 "NSDictionary synthetic children",
560 ConstString("__NSSingleEntryDictionaryI"),
561 ScriptedSyntheticChildren::Flags());
564 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
565 "NSDictionary synthetic children", ConstString("__NSCFDictionary"),
566 ScriptedSyntheticChildren::Flags());
569 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
570 "NSDictionary synthetic children", ConstString("NSDictionary"),
571 ScriptedSyntheticChildren::Flags());
574 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
575 "NSDictionary synthetic children", ConstString("NSMutableDictionary"),
576 ScriptedSyntheticChildren::Flags());
579 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
580 "NSDictionary synthetic children", ConstString("CFDictionaryRef"),
581 ScriptedSyntheticChildren::Flags());
584 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
585 "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"),
586 ScriptedSyntheticChildren::Flags());
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());
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());
610 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
611 "NSMutableSet synthetic children", ConstString("NSMutableSet"),
612 ScriptedSyntheticChildren::Flags());
614 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
615 "NSOrderedSet synthetic children", ConstString("NSOrderedSet"),
616 ScriptedSyntheticChildren::Flags());
618 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
619 "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"),
620 ScriptedSyntheticChildren::Flags());
622 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
623 "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"),
624 ScriptedSyntheticChildren::Flags());
626 AddCXXSynthetic(objc_category_sp,
627 lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator,
628 "NSIndexPath synthetic children", ConstString("NSIndexPath"),
629 ScriptedSyntheticChildren::Flags());
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"),
642 objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
643 "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags);
645 AddCXXSummary(objc_category_sp,
646 lldb_private::formatters::CFBinaryHeapSummaryProvider,
647 "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"),
649 AddCXXSummary(objc_category_sp,
650 lldb_private::formatters::CFBinaryHeapSummaryProvider,
651 "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"),
655 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
656 "NSString summary provider", ConstString("NSString"), appkit_flags);
658 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
659 "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
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"),
667 AddCXXSummary(objc_category_sp,
668 lldb_private::formatters::NSStringSummaryProvider,
669 "NSString summary provider", ConstString("NSMutableString"),
671 AddCXXSummary(objc_category_sp,
672 lldb_private::formatters::NSStringSummaryProvider,
673 "NSString summary provider",
674 ConstString("__NSCFConstantString"), appkit_flags);
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"),
683 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
684 "NSString summary provider", ConstString("NSCFString"), appkit_flags);
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);
693 AddCXXSummary(objc_category_sp,
694 lldb_private::formatters::NSAttributedStringSummaryProvider,
695 "NSAttributedString summary provider",
696 ConstString("NSAttributedString"), appkit_flags);
699 lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
700 "NSMutableAttributedString summary provider",
701 ConstString("NSMutableAttributedString"), appkit_flags);
704 lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
705 "NSMutableAttributedString summary provider",
706 ConstString("NSConcreteMutableAttributedString"), appkit_flags);
709 objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider,
710 "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
712 AddCXXSummary(objc_category_sp,
713 lldb_private::formatters::NSDataSummaryProvider<false>,
714 "NSData summary provider", ConstString("NSData"), appkit_flags);
716 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
717 "NSData summary provider", ConstString("_NSInlineData"), appkit_flags);
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"),
726 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
727 "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
729 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
730 "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
732 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
733 "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
735 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
736 "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
739 objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider,
740 "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags);
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);
752 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
753 "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
755 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
756 "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
758 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
759 "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
761 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
762 "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
764 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
765 "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
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);
774 AddCXXSummary(objc_category_sp,
775 lldb_private::formatters::NSURLSummaryProvider,
776 "NSURL summary provider", ConstString("NSURL"), appkit_flags);
778 objc_category_sp, lldb_private::formatters::NSURLSummaryProvider,
779 "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
781 AddCXXSummary(objc_category_sp,
782 lldb_private::formatters::NSDateSummaryProvider,
783 "NSDate summary provider", ConstString("NSDate"), appkit_flags);
785 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
786 "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
788 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
789 "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
791 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
792 "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
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"),
802 objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
803 "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
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
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);
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"),
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);
828 AddCXXSummary(objc_category_sp,
829 lldb_private::formatters::CFBitVectorSummaryProvider,
830 "CFBitVector summary provider", ConstString("CFBitVectorRef"),
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"),
840 AddCXXSummary(objc_category_sp,
841 lldb_private::formatters::CFBitVectorSummaryProvider,
842 "CFBitVector summary provider",
843 ConstString("__CFMutableBitVector"), appkit_flags);
844 #endif // LLDB_DISABLE_PYTHON
847 static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) {
848 if (!objc_category_sp)
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);
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
867 lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() {
868 static llvm::once_flag g_initialize;
869 static TypeCategoryImplSP g_category;
871 llvm::call_once(g_initialize, [this]() -> void {
872 DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
874 LoadCoreMediaFormatters(g_category);
875 LoadObjCFormatters(g_category);
881 std::vector<ConstString>
882 ObjCLanguage::GetPossibleFormattersMatches(ValueObject &valobj,
883 lldb::DynamicValueType use_dynamic) {
884 std::vector<ConstString> result;
886 if (use_dynamic == lldb::eNoDynamicValues)
889 CompilerType compiler_type(valobj.GetCompilerType());
891 const bool check_cpp = false;
892 const bool check_objc = true;
893 bool canBeObjCDynamic =
894 compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
896 if (canBeObjCDynamic) {
898 lldb::ProcessSP process_sp = valobj.GetProcessSP();
901 ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
902 if (runtime == nullptr)
904 ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp(
905 runtime->GetClassDescriptor(valobj));
908 if (ConstString name = objc_class_sp->GetClassName())
909 result.push_back(name);
916 std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {
917 class ObjCScavengerResult : public Language::TypeScavenger::Result {
919 ObjCScavengerResult(CompilerType type)
920 : Language::TypeScavenger::Result(), m_compiler_type(type) {}
922 bool IsValid() override { return m_compiler_type.IsValid(); }
924 bool DumpToStream(Stream &stream, bool print_help_if_available) override {
926 m_compiler_type.DumpTypeDescription(&stream);
934 CompilerType m_compiler_type;
937 class ObjCRuntimeScavenger : public Language::TypeScavenger {
939 bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
940 ResultSet &results) override {
943 Process *process = exe_scope->CalculateProcess().get();
945 const bool create_on_demand = false;
946 auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
948 auto decl_vendor = objc_runtime->GetDeclVendor();
950 std::vector<clang::NamedDecl *> decls;
951 ConstString name(key);
952 decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
953 for (auto decl : decls) {
955 if (CompilerType candidate =
956 ClangASTContext::GetTypeForDecl(decl)) {
958 std::unique_ptr<Language::TypeScavenger::Result> result(
959 new ObjCScavengerResult(candidate));
960 results.insert(std::move(result));
971 friend class lldb_private::ObjCLanguage;
974 class ObjCModulesScavenger : public Language::TypeScavenger {
976 bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
977 ResultSet &results) override {
980 Target *target = exe_scope->CalculateTarget().get();
982 if (auto clang_modules_decl_vendor =
983 target->GetClangModulesDeclVendor()) {
984 std::vector<clang::NamedDecl *> decls;
985 ConstString key_cs(key);
987 if (clang_modules_decl_vendor->FindDecls(key_cs, false, UINT32_MAX,
990 CompilerType module_type =
991 ClangASTContext::GetTypeForDecl(decls.front());
993 std::unique_ptr<Language::TypeScavenger::Result> result(
994 new ObjCScavengerResult(module_type));
995 results.insert(std::move(result));
1003 friend class lldb_private::ObjCLanguage;
1006 class ObjCDebugInfoScavenger : public Language::ImageListTypeScavenger {
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();
1018 return std::unique_ptr<TypeScavenger>(
1019 new Language::EitherTypeScavenger<ObjCModulesScavenger,
1020 ObjCRuntimeScavenger,
1021 ObjCDebugInfoScavenger>());
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");
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");
1039 static ConstString g_NSData("NSData");
1040 static ConstString g_NSArray("NSArray");
1041 static ConstString g_NSString("NSString");
1042 static ConstString g_NSStringStar("NSString*");
1044 if (type_hint.IsEmpty())
1050 if (type_hint == g_CFBag || type_hint == g_CFBinaryHeap) {
1055 if (type_hint == g_NSNumberChar) {
1059 if (type_hint == g_NSNumberShort) {
1063 if (type_hint == g_NSNumberInt) {
1067 if (type_hint == g_NSNumberLong) {
1071 if (type_hint == g_NSNumberInt128) {
1072 prefix = "(int128_t)";
1075 if (type_hint == g_NSNumberFloat) {
1079 if (type_hint == g_NSNumberDouble) {
1080 prefix = "(double)";
1084 if (type_hint == g_NSData || type_hint == g_NSArray) {
1090 if (type_hint == g_NSString || type_hint == g_NSStringStar) {
1098 bool ObjCLanguage::IsNilReference(ValueObject &valobj) {
1099 const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
1100 bool isObjCpointer =
1101 (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);
1104 bool canReadValue = true;
1105 bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
1106 return canReadValue && isZero;
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))