1 //===-- ObjCLanguage.cpp ----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 #include "ObjCLanguage.h"
13 #include "lldb/Core/PluginManager.h"
14 #include "lldb/Core/ValueObject.h"
15 #include "lldb/DataFormatters/DataVisualization.h"
16 #include "lldb/DataFormatters/FormattersHelpers.h"
17 #include "lldb/Symbol/ClangASTContext.h"
18 #include "lldb/Symbol/CompilerType.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/ConstString.h"
21 #include "lldb/Utility/StreamString.h"
23 #include "llvm/Support/Threading.h"
25 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.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 // PluginInterface protocol
54 lldb_private::ConstString ObjCLanguage::GetPluginName() {
55 return GetPluginNameStatic();
58 uint32_t ObjCLanguage::GetPluginVersion() { return 1; }
62 Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) {
64 case lldb::eLanguageTypeObjC:
65 return new ObjCLanguage();
71 void ObjCLanguage::MethodName::Clear() {
76 m_type = eTypeUnspecified;
77 m_category_is_valid = false;
80 bool ObjCLanguage::MethodName::SetName(llvm::StringRef name, bool strict) {
83 return IsValid(strict);
85 // If "strict" is true. then the method must be specified with a '+' or '-'
86 // at the beginning. If "strict" is false, then the '+' or '-' can be omitted
87 bool valid_prefix = false;
89 if (name.size() > 1 && (name[0] == '+' || name[0] == '-')) {
90 valid_prefix = name[1] == '[';
92 m_type = eTypeClassMethod;
94 m_type = eTypeInstanceMethod;
96 // "strict" is false, the name just needs to start with '['
97 valid_prefix = name[0] == '[';
101 int name_len = name.size();
102 // Objective-C methods must have at least:
103 // "-[" or "+[" prefix
104 // One character for a class name
105 // One character for the space between the class name
106 // One character for the method name
108 if (name_len >= (5 + (strict ? 1 : 0)) && name.back() == ']') {
109 m_full.SetString(name);
112 return IsValid(strict);
115 bool ObjCLanguage::MethodName::SetName(const char *name, bool strict) {
116 return SetName(llvm::StringRef(name), strict);
119 ConstString ObjCLanguage::MethodName::GetClassName() {
121 if (IsValid(false)) {
122 const char *full = m_full.GetCString();
123 const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
124 const char *paren_pos = strchr(class_start, '(');
126 m_class.SetCStringWithLength(class_start, paren_pos - class_start);
128 // No '(' was found in the full name, we can definitively say that our
129 // category was valid (and empty).
130 m_category_is_valid = true;
131 const char *space_pos = strchr(full, ' ');
133 m_class.SetCStringWithLength(class_start, space_pos - class_start);
134 if (!m_class_category) {
135 // No category in name, so we can also fill in the m_class_category
136 m_class_category = m_class;
145 ConstString ObjCLanguage::MethodName::GetClassNameWithCategory() {
146 if (!m_class_category) {
147 if (IsValid(false)) {
148 const char *full = m_full.GetCString();
149 const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
150 const char *space_pos = strchr(full, ' ');
152 m_class_category.SetCStringWithLength(class_start,
153 space_pos - class_start);
154 // If m_class hasn't been filled in and the class with category doesn't
155 // contain a '(', then we can also fill in the m_class
156 if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr) {
157 m_class = m_class_category;
158 // No '(' was found in the full name, we can definitively say that
159 // our category was valid (and empty).
160 m_category_is_valid = true;
165 return m_class_category;
168 ConstString ObjCLanguage::MethodName::GetSelector() {
170 if (IsValid(false)) {
171 const char *full = m_full.GetCString();
172 const char *space_pos = strchr(full, ' ');
174 ++space_pos; // skip the space
175 m_selector.SetCStringWithLength(space_pos, m_full.GetLength() -
176 (space_pos - full) - 1);
183 ConstString ObjCLanguage::MethodName::GetCategory() {
184 if (!m_category_is_valid && !m_category) {
185 if (IsValid(false)) {
186 m_category_is_valid = true;
187 const char *full = m_full.GetCString();
188 const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
189 const char *open_paren_pos = strchr(class_start, '(');
190 if (open_paren_pos) {
191 ++open_paren_pos; // Skip the open paren
192 const char *close_paren_pos = strchr(open_paren_pos, ')');
194 m_category.SetCStringWithLength(open_paren_pos,
195 close_paren_pos - open_paren_pos);
202 ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory(
203 bool empty_if_no_category) {
204 if (IsValid(false)) {
207 if (m_type == eTypeClassMethod)
209 else if (m_type == eTypeInstanceMethod)
211 strm.Printf("[%s %s]", GetClassName().GetCString(),
212 GetSelector().GetCString());
213 return ConstString(strm.GetString());
216 if (!empty_if_no_category) {
217 // Just return the full name since it doesn't have a category
218 return GetFullName();
221 return ConstString();
224 std::vector<ConstString>
225 ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {
226 std::vector<ConstString> variant_names;
227 ObjCLanguage::MethodName objc_method(method_name.GetCString(), false);
228 if (!objc_method.IsValid(false)) {
229 return variant_names;
232 const bool is_class_method =
233 objc_method.GetType() == MethodName::eTypeClassMethod;
234 const bool is_instance_method =
235 objc_method.GetType() == MethodName::eTypeInstanceMethod;
236 ConstString name_sans_category =
237 objc_method.GetFullNameWithoutCategory(/*empty_if_no_category*/ true);
239 if (is_class_method || is_instance_method) {
240 if (name_sans_category)
241 variant_names.emplace_back(name_sans_category);
245 strm.Printf("+%s", objc_method.GetFullName().GetCString());
246 variant_names.emplace_back(strm.GetString());
249 strm.Printf("-%s", objc_method.GetFullName().GetCString());
250 variant_names.emplace_back(strm.GetString());
253 if (name_sans_category) {
254 strm.Printf("+%s", name_sans_category.GetCString());
255 variant_names.emplace_back(strm.GetString());
258 strm.Printf("-%s", name_sans_category.GetCString());
259 variant_names.emplace_back(strm.GetString());
263 return variant_names;
266 static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
267 if (!objc_category_sp)
270 TypeSummaryImpl::Flags objc_flags;
271 objc_flags.SetCascades(false)
272 .SetSkipPointers(true)
273 .SetSkipReferences(true)
274 .SetDontShowChildren(true)
275 .SetDontShowValue(true)
276 .SetShowMembersOneLiner(false)
277 .SetHideItemNames(false);
279 lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(
280 objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider, ""));
281 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"),
283 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"),
285 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"),
288 // we need to skip pointers here since we are special casing a SEL* when
289 // retrieving its value
290 objc_flags.SetSkipPointers(true);
291 AddCXXSummary(objc_category_sp,
292 lldb_private::formatters::ObjCSELSummaryProvider<false>,
293 "SEL summary provider", ConstString("SEL"), objc_flags);
295 objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
296 "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
298 objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>,
299 "SEL summary provider", ConstString("objc_selector"), objc_flags);
301 objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>,
302 "SEL summary provider", ConstString("objc_selector *"), objc_flags);
303 AddCXXSummary(objc_category_sp,
304 lldb_private::formatters::ObjCSELSummaryProvider<true>,
305 "SEL summary provider", ConstString("SEL *"), objc_flags);
307 AddCXXSummary(objc_category_sp,
308 lldb_private::formatters::ObjCClassSummaryProvider,
309 "Class summary provider", ConstString("Class"), objc_flags);
311 SyntheticChildren::Flags class_synth_flags;
312 class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
315 AddCXXSynthetic(objc_category_sp,
316 lldb_private::formatters::ObjCClassSyntheticFrontEndCreator,
317 "Class synthetic children", ConstString("Class"),
320 objc_flags.SetSkipPointers(false);
321 objc_flags.SetCascades(true);
322 objc_flags.SetSkipReferences(false);
324 AddStringSummary(objc_category_sp, "${var.__FuncPtr%A}",
325 ConstString("__block_literal_generic"), objc_flags);
327 AddStringSummary(objc_category_sp, "${var.years} years, ${var.months} "
328 "months, ${var.days} days, ${var.hours} "
329 "hours, ${var.minutes} minutes "
330 "${var.seconds} seconds",
331 ConstString("CFGregorianUnits"), objc_flags);
332 AddStringSummary(objc_category_sp,
333 "location=${var.location} length=${var.length}",
334 ConstString("CFRange"), objc_flags);
336 AddStringSummary(objc_category_sp,
337 "location=${var.location}, length=${var.length}",
338 ConstString("NSRange"), objc_flags);
339 AddStringSummary(objc_category_sp, "(${var.origin}, ${var.size}), ...",
340 ConstString("NSRectArray"), objc_flags);
342 AddOneLineSummary(objc_category_sp, ConstString("NSPoint"), objc_flags);
343 AddOneLineSummary(objc_category_sp, ConstString("NSSize"), objc_flags);
344 AddOneLineSummary(objc_category_sp, ConstString("NSRect"), objc_flags);
346 AddOneLineSummary(objc_category_sp, ConstString("CGSize"), objc_flags);
347 AddOneLineSummary(objc_category_sp, ConstString("CGPoint"), objc_flags);
348 AddOneLineSummary(objc_category_sp, ConstString("CGRect"), objc_flags);
350 AddStringSummary(objc_category_sp,
351 "red=${var.red} green=${var.green} blue=${var.blue}",
352 ConstString("RGBColor"), objc_flags);
355 "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
356 ConstString("Rect"), objc_flags);
357 AddStringSummary(objc_category_sp, "{(v=${var.v}, h=${var.h})}",
358 ConstString("Point"), objc_flags);
359 AddStringSummary(objc_category_sp,
360 "${var.month}/${var.day}/${var.year} ${var.hour} "
361 ":${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
362 ConstString("DateTimeRect *"), objc_flags);
363 AddStringSummary(objc_category_sp, "${var.ld.month}/${var.ld.day}/"
364 "${var.ld.year} ${var.ld.hour} "
365 ":${var.ld.minute} :${var.ld.second} "
366 "dayOfWeek:${var.ld.dayOfWeek}",
367 ConstString("LongDateRect"), objc_flags);
368 AddStringSummary(objc_category_sp, "(x=${var.x}, y=${var.y})",
369 ConstString("HIPoint"), objc_flags);
370 AddStringSummary(objc_category_sp, "origin=${var.origin} size=${var.size}",
371 ConstString("HIRect"), objc_flags);
373 TypeSummaryImpl::Flags appkit_flags;
374 appkit_flags.SetCascades(true)
375 .SetSkipPointers(false)
376 .SetSkipReferences(false)
377 .SetDontShowChildren(true)
378 .SetDontShowValue(false)
379 .SetShowMembersOneLiner(false)
380 .SetHideItemNames(false);
382 appkit_flags.SetDontShowChildren(false);
385 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
386 "NSArray summary provider", ConstString("NSArray"), appkit_flags);
388 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
389 "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
391 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
392 "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
394 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
395 "NSArray summary provider", ConstString("__NSArray0"), appkit_flags);
396 AddCXXSummary(objc_category_sp,
397 lldb_private::formatters::NSArraySummaryProvider,
398 "NSArray summary provider",
399 ConstString("__NSSingleObjectArrayI"), appkit_flags);
401 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
402 "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
404 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
405 "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
407 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
408 "NSArray summary provider", ConstString("_NSCallStackArray"), appkit_flags);
410 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
411 "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
412 AddCXXSummary(objc_category_sp,
413 lldb_private::formatters::NSArraySummaryProvider,
414 "NSArray summary provider", ConstString("CFMutableArrayRef"),
417 AddCXXSummary(objc_category_sp,
418 lldb_private::formatters::NSDictionarySummaryProvider<false>,
419 "NSDictionary summary provider", ConstString("NSDictionary"),
421 AddCXXSummary(objc_category_sp,
422 lldb_private::formatters::NSDictionarySummaryProvider<false>,
423 "NSDictionary summary provider",
424 ConstString("NSMutableDictionary"), appkit_flags);
425 AddCXXSummary(objc_category_sp,
426 lldb_private::formatters::NSDictionarySummaryProvider<false>,
427 "NSDictionary summary provider",
428 ConstString("__NSCFDictionary"), appkit_flags);
429 AddCXXSummary(objc_category_sp,
430 lldb_private::formatters::NSDictionarySummaryProvider<false>,
431 "NSDictionary summary provider", ConstString("__NSDictionaryI"),
433 AddCXXSummary(objc_category_sp,
434 lldb_private::formatters::NSDictionarySummaryProvider<false>,
435 "NSDictionary summary provider",
436 ConstString("__NSSingleEntryDictionaryI"), appkit_flags);
437 AddCXXSummary(objc_category_sp,
438 lldb_private::formatters::NSDictionarySummaryProvider<false>,
439 "NSDictionary summary provider", ConstString("__NSDictionaryM"),
441 AddCXXSummary(objc_category_sp,
442 lldb_private::formatters::NSDictionarySummaryProvider<true>,
443 "NSDictionary summary provider", ConstString("CFDictionaryRef"),
445 AddCXXSummary(objc_category_sp,
446 lldb_private::formatters::NSDictionarySummaryProvider<true>,
447 "NSDictionary summary provider",
448 ConstString("CFMutableDictionaryRef"), appkit_flags);
450 AddCXXSummary(objc_category_sp,
451 lldb_private::formatters::NSSetSummaryProvider<false>,
452 "NSSet summary", ConstString("NSSet"), appkit_flags);
454 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
455 "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
456 AddCXXSummary(objc_category_sp,
457 lldb_private::formatters::NSSetSummaryProvider<true>,
458 "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
460 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>,
461 "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
462 AddCXXSummary(objc_category_sp,
463 lldb_private::formatters::NSSetSummaryProvider<false>,
464 "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
465 AddCXXSummary(objc_category_sp,
466 lldb_private::formatters::NSSetSummaryProvider<false>,
467 "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
468 AddCXXSummary(objc_category_sp,
469 lldb_private::formatters::NSSetSummaryProvider<false>,
470 "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
472 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
473 "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
475 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
476 "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
478 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
479 "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags);
481 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
482 "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags);
484 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>,
485 "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags);
488 objc_category_sp, lldb_private::formatters::NSError_SummaryProvider,
489 "NSError summary provider", ConstString("NSError"), appkit_flags);
491 objc_category_sp, lldb_private::formatters::NSException_SummaryProvider,
492 "NSException summary provider", ConstString("NSException"), appkit_flags);
494 // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}",
495 // ConstString("$_lldb_typegen_nspair"), appkit_flags);
497 appkit_flags.SetDontShowChildren(true);
499 AddCXXSynthetic(objc_category_sp,
500 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
501 "NSArray synthetic children", ConstString("__NSArrayM"),
502 ScriptedSyntheticChildren::Flags());
503 AddCXXSynthetic(objc_category_sp,
504 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
505 "NSArray synthetic children", ConstString("__NSArrayI"),
506 ScriptedSyntheticChildren::Flags());
507 AddCXXSynthetic(objc_category_sp,
508 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
509 "NSArray synthetic children", ConstString("__NSArray0"),
510 ScriptedSyntheticChildren::Flags());
511 AddCXXSynthetic(objc_category_sp,
512 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
513 "NSArray synthetic children",
514 ConstString("__NSSingleObjectArrayI"),
515 ScriptedSyntheticChildren::Flags());
516 AddCXXSynthetic(objc_category_sp,
517 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
518 "NSArray synthetic children", ConstString("NSArray"),
519 ScriptedSyntheticChildren::Flags());
520 AddCXXSynthetic(objc_category_sp,
521 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
522 "NSArray synthetic children", ConstString("NSMutableArray"),
523 ScriptedSyntheticChildren::Flags());
524 AddCXXSynthetic(objc_category_sp,
525 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
526 "NSArray synthetic children", ConstString("__NSCFArray"),
527 ScriptedSyntheticChildren::Flags());
528 AddCXXSynthetic(objc_category_sp,
529 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
530 "NSArray synthetic children", ConstString("_NSCallStackArray"),
531 ScriptedSyntheticChildren::Flags());
532 AddCXXSynthetic(objc_category_sp,
533 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
534 "NSArray synthetic children",
535 ConstString("CFMutableArrayRef"),
536 ScriptedSyntheticChildren::Flags());
537 AddCXXSynthetic(objc_category_sp,
538 lldb_private::formatters::NSArraySyntheticFrontEndCreator,
539 "NSArray synthetic children", ConstString("CFArrayRef"),
540 ScriptedSyntheticChildren::Flags());
544 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
545 "NSDictionary synthetic children", ConstString("__NSDictionaryM"),
546 ScriptedSyntheticChildren::Flags());
549 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
550 "NSDictionary synthetic children", ConstString("__NSDictionaryI"),
551 ScriptedSyntheticChildren::Flags());
554 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
555 "NSDictionary synthetic children",
556 ConstString("__NSSingleEntryDictionaryI"),
557 ScriptedSyntheticChildren::Flags());
560 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
561 "NSDictionary synthetic children", ConstString("__NSCFDictionary"),
562 ScriptedSyntheticChildren::Flags());
565 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
566 "NSDictionary synthetic children", ConstString("NSDictionary"),
567 ScriptedSyntheticChildren::Flags());
570 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
571 "NSDictionary synthetic children", ConstString("NSMutableDictionary"),
572 ScriptedSyntheticChildren::Flags());
575 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
576 "NSDictionary synthetic children", ConstString("CFDictionaryRef"),
577 ScriptedSyntheticChildren::Flags());
580 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,
581 "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"),
582 ScriptedSyntheticChildren::Flags());
584 AddCXXSynthetic(objc_category_sp,
585 lldb_private::formatters::NSErrorSyntheticFrontEndCreator,
586 "NSError synthetic children", ConstString("NSError"),
587 ScriptedSyntheticChildren::Flags());
588 AddCXXSynthetic(objc_category_sp,
589 lldb_private::formatters::NSExceptionSyntheticFrontEndCreator,
590 "NSException synthetic children", ConstString("NSException"),
591 ScriptedSyntheticChildren::Flags());
593 AddCXXSynthetic(objc_category_sp,
594 lldb_private::formatters::NSSetSyntheticFrontEndCreator,
595 "NSSet synthetic children", ConstString("NSSet"),
596 ScriptedSyntheticChildren::Flags());
597 AddCXXSynthetic(objc_category_sp,
598 lldb_private::formatters::NSSetSyntheticFrontEndCreator,
599 "__NSSetI synthetic children", ConstString("__NSSetI"),
600 ScriptedSyntheticChildren::Flags());
601 AddCXXSynthetic(objc_category_sp,
602 lldb_private::formatters::NSSetSyntheticFrontEndCreator,
603 "__NSSetM synthetic children", ConstString("__NSSetM"),
604 ScriptedSyntheticChildren::Flags());
606 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
607 "NSMutableSet synthetic children", ConstString("NSMutableSet"),
608 ScriptedSyntheticChildren::Flags());
610 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
611 "NSOrderedSet synthetic children", ConstString("NSOrderedSet"),
612 ScriptedSyntheticChildren::Flags());
614 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
615 "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"),
616 ScriptedSyntheticChildren::Flags());
618 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,
619 "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"),
620 ScriptedSyntheticChildren::Flags());
622 AddCXXSynthetic(objc_category_sp,
623 lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator,
624 "NSIndexPath synthetic children", ConstString("NSIndexPath"),
625 ScriptedSyntheticChildren::Flags());
628 objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
629 "CFBag summary provider", ConstString("CFBagRef"), appkit_flags);
630 AddCXXSummary(objc_category_sp,
631 lldb_private::formatters::CFBagSummaryProvider,
632 "CFBag summary provider", ConstString("__CFBag"), appkit_flags);
633 AddCXXSummary(objc_category_sp,
634 lldb_private::formatters::CFBagSummaryProvider,
635 "CFBag summary provider", ConstString("const struct __CFBag"),
638 objc_category_sp, lldb_private::formatters::CFBagSummaryProvider,
639 "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags);
641 AddCXXSummary(objc_category_sp,
642 lldb_private::formatters::CFBinaryHeapSummaryProvider,
643 "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"),
645 AddCXXSummary(objc_category_sp,
646 lldb_private::formatters::CFBinaryHeapSummaryProvider,
647 "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"),
651 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
652 "NSString summary provider", ConstString("NSString"), appkit_flags);
654 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
655 "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
657 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
658 "NSString summary provider", ConstString("__CFString"), appkit_flags);
659 AddCXXSummary(objc_category_sp,
660 lldb_private::formatters::NSStringSummaryProvider,
661 "NSString summary provider", ConstString("CFMutableStringRef"),
663 AddCXXSummary(objc_category_sp,
664 lldb_private::formatters::NSStringSummaryProvider,
665 "NSString summary provider", ConstString("NSMutableString"),
667 AddCXXSummary(objc_category_sp,
668 lldb_private::formatters::NSStringSummaryProvider,
669 "NSString summary provider",
670 ConstString("__NSCFConstantString"), appkit_flags);
672 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
673 "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
674 AddCXXSummary(objc_category_sp,
675 lldb_private::formatters::NSStringSummaryProvider,
676 "NSString summary provider", ConstString("NSCFConstantString"),
679 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
680 "NSString summary provider", ConstString("NSCFString"), appkit_flags);
682 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,
683 "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
684 AddCXXSummary(objc_category_sp,
685 lldb_private::formatters::NSStringSummaryProvider,
686 "NSString summary provider",
687 ConstString("NSTaggedPointerString"), appkit_flags);
689 AddCXXSummary(objc_category_sp,
690 lldb_private::formatters::NSAttributedStringSummaryProvider,
691 "NSAttributedString summary provider",
692 ConstString("NSAttributedString"), appkit_flags);
695 lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
696 "NSMutableAttributedString summary provider",
697 ConstString("NSMutableAttributedString"), appkit_flags);
700 lldb_private::formatters::NSMutableAttributedStringSummaryProvider,
701 "NSMutableAttributedString summary provider",
702 ConstString("NSConcreteMutableAttributedString"), appkit_flags);
705 objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider,
706 "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
708 AddCXXSummary(objc_category_sp,
709 lldb_private::formatters::NSDataSummaryProvider<false>,
710 "NSData summary provider", ConstString("NSData"), appkit_flags);
712 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
713 "NSData summary provider", ConstString("_NSInlineData"), appkit_flags);
715 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
716 "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
717 AddCXXSummary(objc_category_sp,
718 lldb_private::formatters::NSDataSummaryProvider<false>,
719 "NSData summary provider", ConstString("NSConcreteMutableData"),
722 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
723 "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
725 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,
726 "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
728 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
729 "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
731 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>,
732 "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
735 objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider,
736 "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags);
738 AddCXXSummary(objc_category_sp,
739 lldb_private::formatters::NSNotificationSummaryProvider,
740 "NSNotification summary provider",
741 ConstString("NSNotification"), appkit_flags);
742 AddCXXSummary(objc_category_sp,
743 lldb_private::formatters::NSNotificationSummaryProvider,
744 "NSNotification summary provider",
745 ConstString("NSConcreteNotification"), appkit_flags);
748 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
749 "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
751 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
752 "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
754 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
755 "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
757 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
758 "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
760 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
761 "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
763 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,
764 "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
765 AddCXXSummary(objc_category_sp,
766 lldb_private::formatters::NSNumberSummaryProvider,
767 "NSDecimalNumber summary provider",
768 ConstString("NSDecimalNumber"), appkit_flags);
770 AddCXXSummary(objc_category_sp,
771 lldb_private::formatters::NSURLSummaryProvider,
772 "NSURL summary provider", ConstString("NSURL"), appkit_flags);
774 objc_category_sp, lldb_private::formatters::NSURLSummaryProvider,
775 "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
777 AddCXXSummary(objc_category_sp,
778 lldb_private::formatters::NSDateSummaryProvider,
779 "NSDate summary provider", ConstString("NSDate"), appkit_flags);
781 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
782 "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
784 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
785 "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
787 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider,
788 "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
791 objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
792 "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags);
793 AddCXXSummary(objc_category_sp,
794 lldb_private::formatters::NSTimeZoneSummaryProvider,
795 "NSTimeZone summary provider", ConstString("CFTimeZoneRef"),
798 objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
799 "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
801 // CFAbsoluteTime is actually a double rather than a pointer to an object we
802 // do not care about the numeric value, since it is probably meaningless to
804 appkit_flags.SetDontShowValue(true);
805 AddCXXSummary(objc_category_sp,
806 lldb_private::formatters::CFAbsoluteTimeSummaryProvider,
807 "CFAbsoluteTime summary provider",
808 ConstString("CFAbsoluteTime"), appkit_flags);
809 appkit_flags.SetDontShowValue(false);
812 objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider,
813 "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags);
814 AddCXXSummary(objc_category_sp,
815 lldb_private::formatters::NSIndexSetSummaryProvider,
816 "NSIndexSet summary provider", ConstString("NSMutableIndexSet"),
819 AddStringSummary(objc_category_sp,
820 "@\"${var.month%d}/${var.day%d}/${var.year%d} "
821 "${var.hour%d}:${var.minute%d}:${var.second}\"",
822 ConstString("CFGregorianDate"), appkit_flags);
824 AddCXXSummary(objc_category_sp,
825 lldb_private::formatters::CFBitVectorSummaryProvider,
826 "CFBitVector summary provider", ConstString("CFBitVectorRef"),
828 AddCXXSummary(objc_category_sp,
829 lldb_private::formatters::CFBitVectorSummaryProvider,
830 "CFBitVector summary provider",
831 ConstString("CFMutableBitVectorRef"), appkit_flags);
832 AddCXXSummary(objc_category_sp,
833 lldb_private::formatters::CFBitVectorSummaryProvider,
834 "CFBitVector summary provider", ConstString("__CFBitVector"),
836 AddCXXSummary(objc_category_sp,
837 lldb_private::formatters::CFBitVectorSummaryProvider,
838 "CFBitVector summary provider",
839 ConstString("__CFMutableBitVector"), appkit_flags);
842 static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) {
843 if (!objc_category_sp)
846 TypeSummaryImpl::Flags cm_flags;
847 cm_flags.SetCascades(true)
848 .SetDontShowChildren(false)
849 .SetDontShowValue(false)
850 .SetHideItemNames(false)
851 .SetShowMembersOneLiner(false)
852 .SetSkipPointers(false)
853 .SetSkipReferences(false);
855 AddCXXSummary(objc_category_sp,
856 lldb_private::formatters::CMTimeSummaryProvider,
857 "CMTime summary provider", ConstString("CMTime"), cm_flags);
860 lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() {
861 static llvm::once_flag g_initialize;
862 static TypeCategoryImplSP g_category;
864 llvm::call_once(g_initialize, [this]() -> void {
865 DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
867 LoadCoreMediaFormatters(g_category);
868 LoadObjCFormatters(g_category);
874 std::vector<ConstString>
875 ObjCLanguage::GetPossibleFormattersMatches(ValueObject &valobj,
876 lldb::DynamicValueType use_dynamic) {
877 std::vector<ConstString> result;
879 if (use_dynamic == lldb::eNoDynamicValues)
882 CompilerType compiler_type(valobj.GetCompilerType());
884 const bool check_cpp = false;
885 const bool check_objc = true;
886 bool canBeObjCDynamic =
887 compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
889 if (canBeObjCDynamic) {
891 lldb::ProcessSP process_sp = valobj.GetProcessSP();
894 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
895 if (runtime == nullptr)
897 ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp(
898 runtime->GetClassDescriptor(valobj));
901 if (ConstString name = objc_class_sp->GetClassName())
902 result.push_back(name);
909 std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {
910 class ObjCScavengerResult : public Language::TypeScavenger::Result {
912 ObjCScavengerResult(CompilerType type)
913 : Language::TypeScavenger::Result(), m_compiler_type(type) {}
915 bool IsValid() override { return m_compiler_type.IsValid(); }
917 bool DumpToStream(Stream &stream, bool print_help_if_available) override {
919 m_compiler_type.DumpTypeDescription(&stream);
927 CompilerType m_compiler_type;
930 class ObjCRuntimeScavenger : public Language::TypeScavenger {
932 bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
933 ResultSet &results) override {
936 if (auto *process = exe_scope->CalculateProcess().get()) {
937 if (auto *objc_runtime = ObjCLanguageRuntime::Get(*process)) {
938 if (auto *decl_vendor = objc_runtime->GetDeclVendor()) {
939 ConstString name(key);
940 for (const CompilerType &type :
941 decl_vendor->FindTypes(name, /*max_matches*/ UINT32_MAX)) {
943 std::unique_ptr<Language::TypeScavenger::Result> result(
944 new ObjCScavengerResult(type));
945 results.insert(std::move(result));
954 friend class lldb_private::ObjCLanguage;
957 class ObjCModulesScavenger : public Language::TypeScavenger {
959 bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
960 ResultSet &results) override {
963 if (auto *target = exe_scope->CalculateTarget().get()) {
964 if (auto *clang_modules_decl_vendor =
965 target->GetClangModulesDeclVendor()) {
966 ConstString key_cs(key);
967 auto types = clang_modules_decl_vendor->FindTypes(
968 key_cs, /*max_matches*/ UINT32_MAX);
969 if (!types.empty()) {
971 std::unique_ptr<Language::TypeScavenger::Result> result(
972 new ObjCScavengerResult(types.front()));
973 results.insert(std::move(result));
981 friend class lldb_private::ObjCLanguage;
984 class ObjCDebugInfoScavenger : public Language::ImageListTypeScavenger {
986 CompilerType AdjustForInclusion(CompilerType &candidate) override {
987 LanguageType lang_type(candidate.GetMinimumLanguage());
988 if (!Language::LanguageIsObjC(lang_type))
989 return CompilerType();
990 if (candidate.IsTypedefType())
991 return candidate.GetTypedefedType();
996 return std::unique_ptr<TypeScavenger>(
997 new Language::EitherTypeScavenger<ObjCModulesScavenger,
998 ObjCRuntimeScavenger,
999 ObjCDebugInfoScavenger>());
1002 bool ObjCLanguage::GetFormatterPrefixSuffix(ValueObject &valobj,
1003 ConstString type_hint,
1004 std::string &prefix,
1005 std::string &suffix) {
1006 static ConstString g_CFBag("CFBag");
1007 static ConstString g_CFBinaryHeap("CFBinaryHeap");
1009 static ConstString g_NSNumberChar("NSNumber:char");
1010 static ConstString g_NSNumberShort("NSNumber:short");
1011 static ConstString g_NSNumberInt("NSNumber:int");
1012 static ConstString g_NSNumberLong("NSNumber:long");
1013 static ConstString g_NSNumberInt128("NSNumber:int128_t");
1014 static ConstString g_NSNumberFloat("NSNumber:float");
1015 static ConstString g_NSNumberDouble("NSNumber:double");
1017 static ConstString g_NSData("NSData");
1018 static ConstString g_NSArray("NSArray");
1019 static ConstString g_NSString("NSString");
1020 static ConstString g_NSStringStar("NSString*");
1022 if (type_hint.IsEmpty())
1028 if (type_hint == g_CFBag || type_hint == g_CFBinaryHeap) {
1033 if (type_hint == g_NSNumberChar) {
1037 if (type_hint == g_NSNumberShort) {
1041 if (type_hint == g_NSNumberInt) {
1045 if (type_hint == g_NSNumberLong) {
1049 if (type_hint == g_NSNumberInt128) {
1050 prefix = "(int128_t)";
1053 if (type_hint == g_NSNumberFloat) {
1057 if (type_hint == g_NSNumberDouble) {
1058 prefix = "(double)";
1062 if (type_hint == g_NSData || type_hint == g_NSArray) {
1068 if (type_hint == g_NSString || type_hint == g_NSStringStar) {
1076 bool ObjCLanguage::IsNilReference(ValueObject &valobj) {
1077 const uint32_t mask = eTypeIsObjC | eTypeIsPointer;
1078 bool isObjCpointer =
1079 (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);
1082 bool canReadValue = true;
1083 bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
1084 return canReadValue && isZero;
1087 bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const {
1088 const auto suffixes = {".h", ".m", ".M"};
1089 for (auto suffix : suffixes) {
1090 if (file_path.endswith_lower(suffix))