1 //===-- ObjCLanguage.cpp --------------------------------------------------===//
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 "Plugins/ExpressionParser/Clang/ClangUtil.h"
14 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/ValueObject.h"
18 #include "lldb/DataFormatters/DataVisualization.h"
19 #include "lldb/DataFormatters/FormattersHelpers.h"
20 #include "lldb/Symbol/CompilerType.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"
27 #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
28 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
32 #include "CoreMedia.h"
33 #include "NSDictionary.h"
38 using namespace lldb_private
;
39 using namespace lldb_private::formatters
;
41 LLDB_PLUGIN_DEFINE(ObjCLanguage
)
43 void ObjCLanguage::Initialize() {
44 PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language",
48 void ObjCLanguage::Terminate() {
49 PluginManager::UnregisterPlugin(CreateInstance
);
54 Language
*ObjCLanguage::CreateInstance(lldb::LanguageType language
) {
56 case lldb::eLanguageTypeObjC
:
57 return new ObjCLanguage();
63 std::optional
<const ObjCLanguage::MethodName
>
64 ObjCLanguage::MethodName::Create(llvm::StringRef name
, bool strict
) {
68 // Objective-C method minimum requirements:
69 // - If `strict` is true, must start with '-' or '+' (1 char)
70 // - Must be followed by '[' (1 char)
71 // - Must have at least one character for class name (1 char)
72 // - Must have a space between class name and method name (1 char)
73 // - Must have at least one character for method name (1 char)
74 // - Must be end with ']' (1 char)
75 // This means that the minimum size is 5 characters (6 if `strict`)
76 // e.g. [a a] (-[a a] or +[a a] if `strict`)
78 // We can check length and ending invariants first
79 if (name
.size() < (5 + (strict
? 1 : 0)) || name
.back() != ']')
83 Type type
= eTypeUnspecified
;
84 if (name
.startswith("+["))
85 type
= eTypeClassMethod
;
86 else if (name
.startswith("-["))
87 type
= eTypeInstanceMethod
;
89 // If there's no type and it's strict, this is invalid
90 if (strict
&& type
== eTypeUnspecified
)
93 // If not strict and type unspecified, make sure we start with '['
94 if (type
== eTypeUnspecified
&& name
.front() != '[')
97 // If we've gotten here, we're confident that this looks enough like an
98 // Objective-C method to treat it like one.
99 ObjCLanguage::MethodName
method_name(name
, type
);
103 llvm::StringRef
ObjCLanguage::MethodName::GetClassName() const {
104 llvm::StringRef full
= m_full
;
105 const size_t class_start_pos
= (full
.front() == '[' ? 1 : 2);
106 const size_t paren_pos
= full
.find('(', class_start_pos
);
107 // If there's a category we want to stop there
108 if (paren_pos
!= llvm::StringRef::npos
)
109 return full
.substr(class_start_pos
, paren_pos
- class_start_pos
);
111 // Otherwise we find the space separating the class and method
112 const size_t space_pos
= full
.find(' ', class_start_pos
);
113 return full
.substr(class_start_pos
, space_pos
- class_start_pos
);
116 llvm::StringRef
ObjCLanguage::MethodName::GetClassNameWithCategory() const {
117 llvm::StringRef full
= m_full
;
118 const size_t class_start_pos
= (full
.front() == '[' ? 1 : 2);
119 const size_t space_pos
= full
.find(' ', class_start_pos
);
120 return full
.substr(class_start_pos
, space_pos
- class_start_pos
);
123 llvm::StringRef
ObjCLanguage::MethodName::GetSelector() const {
124 llvm::StringRef full
= m_full
;
125 const size_t space_pos
= full
.find(' ');
126 if (space_pos
== llvm::StringRef::npos
)
127 return llvm::StringRef();
128 const size_t closing_bracket
= full
.find(']', space_pos
);
129 return full
.substr(space_pos
+ 1, closing_bracket
- space_pos
- 1);
132 llvm::StringRef
ObjCLanguage::MethodName::GetCategory() const {
133 llvm::StringRef full
= m_full
;
134 const size_t open_paren_pos
= full
.find('(');
135 const size_t close_paren_pos
= full
.find(')');
137 if (open_paren_pos
== llvm::StringRef::npos
||
138 close_paren_pos
== llvm::StringRef::npos
)
139 return llvm::StringRef();
141 return full
.substr(open_paren_pos
+ 1,
142 close_paren_pos
- (open_paren_pos
+ 1));
145 std::string
ObjCLanguage::MethodName::GetFullNameWithoutCategory() const {
146 llvm::StringRef full
= m_full
;
147 const size_t open_paren_pos
= full
.find('(');
148 const size_t close_paren_pos
= full
.find(')');
149 if (open_paren_pos
== llvm::StringRef::npos
||
150 close_paren_pos
== llvm::StringRef::npos
)
151 return std::string();
153 llvm::StringRef class_name
= GetClassName();
154 llvm::StringRef selector_name
= GetSelector();
156 // Compute the total size to avoid reallocations
157 // class name + selector name + '[' + ' ' + ']'
158 size_t total_size
= class_name
.size() + selector_name
.size() + 3;
159 if (m_type
!= eTypeUnspecified
)
160 total_size
++; // For + or -
162 std::string name_sans_category
;
163 name_sans_category
.reserve(total_size
);
165 if (m_type
== eTypeClassMethod
)
166 name_sans_category
+= '+';
167 else if (m_type
== eTypeInstanceMethod
)
168 name_sans_category
+= '-';
170 name_sans_category
+= '[';
171 name_sans_category
.append(class_name
.data(), class_name
.size());
172 name_sans_category
+= ' ';
173 name_sans_category
.append(selector_name
.data(), selector_name
.size());
174 name_sans_category
+= ']';
176 return name_sans_category
;
179 std::vector
<Language::MethodNameVariant
>
180 ObjCLanguage::GetMethodNameVariants(ConstString method_name
) const {
181 std::vector
<Language::MethodNameVariant
> variant_names
;
182 std::optional
<const ObjCLanguage::MethodName
> objc_method
=
183 ObjCLanguage::MethodName::Create(method_name
.GetStringRef(), false);
185 return variant_names
;
187 variant_names
.emplace_back(ConstString(objc_method
->GetSelector()),
188 lldb::eFunctionNameTypeSelector
);
190 const std::string name_sans_category
=
191 objc_method
->GetFullNameWithoutCategory();
193 if (objc_method
->IsClassMethod() || objc_method
->IsInstanceMethod()) {
194 if (!name_sans_category
.empty())
195 variant_names
.emplace_back(ConstString(name_sans_category
.c_str()),
196 lldb::eFunctionNameTypeFull
);
200 strm
.Printf("+%s", objc_method
->GetFullName().c_str());
201 variant_names
.emplace_back(ConstString(strm
.GetString()),
202 lldb::eFunctionNameTypeFull
);
205 strm
.Printf("-%s", objc_method
->GetFullName().c_str());
206 variant_names
.emplace_back(ConstString(strm
.GetString()),
207 lldb::eFunctionNameTypeFull
);
210 if (!name_sans_category
.empty()) {
211 strm
.Printf("+%s", name_sans_category
.c_str());
212 variant_names
.emplace_back(ConstString(strm
.GetString()),
213 lldb::eFunctionNameTypeFull
);
216 strm
.Printf("-%s", name_sans_category
.c_str());
217 variant_names
.emplace_back(ConstString(strm
.GetString()),
218 lldb::eFunctionNameTypeFull
);
222 return variant_names
;
225 bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled
) const {
226 ConstString demangled_name
= mangled
.GetDemangledName();
229 return ObjCLanguage::IsPossibleObjCMethodName(demangled_name
.GetCString());
232 static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp
) {
233 if (!objc_category_sp
)
236 TypeSummaryImpl::Flags objc_flags
;
237 objc_flags
.SetCascades(false)
238 .SetSkipPointers(true)
239 .SetSkipReferences(true)
240 .SetDontShowChildren(true)
241 .SetDontShowValue(true)
242 .SetShowMembersOneLiner(false)
243 .SetHideItemNames(false);
245 lldb::TypeSummaryImplSP
ObjC_BOOL_summary(new CXXFunctionSummaryFormat(
246 objc_flags
, lldb_private::formatters::ObjCBOOLSummaryProvider
, ""));
247 objc_category_sp
->AddTypeSummary("BOOL", eFormatterMatchExact
,
249 objc_category_sp
->AddTypeSummary("BOOL &", eFormatterMatchExact
,
251 objc_category_sp
->AddTypeSummary("BOOL *", eFormatterMatchExact
,
254 // we need to skip pointers here since we are special casing a SEL* when
255 // retrieving its value
256 objc_flags
.SetSkipPointers(true);
257 AddCXXSummary(objc_category_sp
,
258 lldb_private::formatters::ObjCSELSummaryProvider
<false>,
259 "SEL summary provider", "SEL", objc_flags
);
260 AddCXXSummary(objc_category_sp
,
261 lldb_private::formatters::ObjCSELSummaryProvider
<false>,
262 "SEL summary provider", "struct objc_selector", objc_flags
);
263 AddCXXSummary(objc_category_sp
,
264 lldb_private::formatters::ObjCSELSummaryProvider
<false>,
265 "SEL summary provider", "objc_selector", objc_flags
);
266 AddCXXSummary(objc_category_sp
,
267 lldb_private::formatters::ObjCSELSummaryProvider
<true>,
268 "SEL summary provider", "objc_selector *", objc_flags
);
269 AddCXXSummary(objc_category_sp
,
270 lldb_private::formatters::ObjCSELSummaryProvider
<true>,
271 "SEL summary provider", "SEL *", objc_flags
);
273 AddCXXSummary(objc_category_sp
,
274 lldb_private::formatters::ObjCClassSummaryProvider
,
275 "Class summary provider", "Class", objc_flags
);
277 SyntheticChildren::Flags class_synth_flags
;
278 class_synth_flags
.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
281 AddCXXSynthetic(objc_category_sp
,
282 lldb_private::formatters::ObjCClassSyntheticFrontEndCreator
,
283 "Class synthetic children", "Class", class_synth_flags
);
285 objc_flags
.SetSkipPointers(false);
286 objc_flags
.SetCascades(true);
287 objc_flags
.SetSkipReferences(false);
289 AddStringSummary(objc_category_sp
, "${var.__FuncPtr%A}",
290 "__block_literal_generic", objc_flags
);
292 AddStringSummary(objc_category_sp
,
293 "${var.years} years, ${var.months} "
294 "months, ${var.days} days, ${var.hours} "
295 "hours, ${var.minutes} minutes "
296 "${var.seconds} seconds",
297 "CFGregorianUnits", objc_flags
);
298 AddStringSummary(objc_category_sp
,
299 "location=${var.location} length=${var.length}", "CFRange",
302 AddStringSummary(objc_category_sp
,
303 "location=${var.location}, length=${var.length}", "NSRange",
305 AddStringSummary(objc_category_sp
, "(${var.origin}, ${var.size}), ...",
306 "NSRectArray", objc_flags
);
308 AddOneLineSummary(objc_category_sp
, "NSPoint", objc_flags
);
309 AddOneLineSummary(objc_category_sp
, "NSSize", objc_flags
);
310 AddOneLineSummary(objc_category_sp
, "NSRect", objc_flags
);
312 AddOneLineSummary(objc_category_sp
, "CGSize", objc_flags
);
313 AddOneLineSummary(objc_category_sp
, "CGPoint", objc_flags
);
314 AddOneLineSummary(objc_category_sp
, "CGRect", objc_flags
);
316 AddStringSummary(objc_category_sp
,
317 "red=${var.red} green=${var.green} blue=${var.blue}",
318 "RGBColor", objc_flags
);
321 "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})", "Rect",
323 AddStringSummary(objc_category_sp
, "{(v=${var.v}, h=${var.h})}", "Point",
325 AddStringSummary(objc_category_sp
,
326 "${var.month}/${var.day}/${var.year} ${var.hour} "
327 ":${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
328 "DateTimeRect *", objc_flags
);
329 AddStringSummary(objc_category_sp
,
330 "${var.ld.month}/${var.ld.day}/"
331 "${var.ld.year} ${var.ld.hour} "
332 ":${var.ld.minute} :${var.ld.second} "
333 "dayOfWeek:${var.ld.dayOfWeek}",
334 "LongDateRect", objc_flags
);
335 AddStringSummary(objc_category_sp
, "(x=${var.x}, y=${var.y})", "HIPoint",
337 AddStringSummary(objc_category_sp
, "origin=${var.origin} size=${var.size}",
338 "HIRect", objc_flags
);
340 TypeSummaryImpl::Flags appkit_flags
;
341 appkit_flags
.SetCascades(true)
342 .SetSkipPointers(false)
343 .SetSkipReferences(false)
344 .SetDontShowChildren(true)
345 .SetDontShowValue(false)
346 .SetShowMembersOneLiner(false)
347 .SetHideItemNames(false);
349 appkit_flags
.SetDontShowChildren(false);
351 AddCXXSummary(objc_category_sp
,
352 lldb_private::formatters::NSArraySummaryProvider
,
353 "NSArray summary provider", "NSArray", appkit_flags
);
354 AddCXXSummary(objc_category_sp
,
355 lldb_private::formatters::NSArraySummaryProvider
,
356 "NSArray summary provider", "NSConstantArray", appkit_flags
);
357 AddCXXSummary(objc_category_sp
,
358 lldb_private::formatters::NSArraySummaryProvider
,
359 "NSArray summary provider", "NSMutableArray", appkit_flags
);
360 AddCXXSummary(objc_category_sp
,
361 lldb_private::formatters::NSArraySummaryProvider
,
362 "NSArray summary provider", "__NSArrayI", appkit_flags
);
363 AddCXXSummary(objc_category_sp
,
364 lldb_private::formatters::NSArraySummaryProvider
,
365 "NSArray summary provider", "__NSArray0", appkit_flags
);
367 objc_category_sp
, lldb_private::formatters::NSArraySummaryProvider
,
368 "NSArray summary provider", "__NSSingleObjectArrayI", appkit_flags
);
369 AddCXXSummary(objc_category_sp
,
370 lldb_private::formatters::NSArraySummaryProvider
,
371 "NSArray summary provider", "__NSArrayM", appkit_flags
);
372 AddCXXSummary(objc_category_sp
,
373 lldb_private::formatters::NSArraySummaryProvider
,
374 "NSArray summary provider", "__NSCFArray", appkit_flags
);
375 AddCXXSummary(objc_category_sp
,
376 lldb_private::formatters::NSArraySummaryProvider
,
377 "NSArray summary provider", "_NSCallStackArray", appkit_flags
);
378 AddCXXSummary(objc_category_sp
,
379 lldb_private::formatters::NSArraySummaryProvider
,
380 "NSArray summary provider", "CFArrayRef", appkit_flags
);
381 AddCXXSummary(objc_category_sp
,
382 lldb_private::formatters::NSArraySummaryProvider
,
383 "NSArray summary provider", "CFMutableArrayRef", appkit_flags
);
385 AddCXXSummary(objc_category_sp
,
386 lldb_private::formatters::NSDictionarySummaryProvider
<false>,
387 "NSDictionary summary provider", "NSDictionary", appkit_flags
);
388 AddCXXSummary(objc_category_sp
,
389 lldb_private::formatters::NSDictionarySummaryProvider
<false>,
390 "NSDictionary summary provider", "NSConstantDictionary",
392 AddCXXSummary(objc_category_sp
,
393 lldb_private::formatters::NSDictionarySummaryProvider
<false>,
394 "NSDictionary summary provider", "NSMutableDictionary",
396 AddCXXSummary(objc_category_sp
,
397 lldb_private::formatters::NSDictionarySummaryProvider
<false>,
398 "NSDictionary summary provider", "__NSCFDictionary",
400 AddCXXSummary(objc_category_sp
,
401 lldb_private::formatters::NSDictionarySummaryProvider
<false>,
402 "NSDictionary summary provider", "__NSDictionaryI",
404 AddCXXSummary(objc_category_sp
,
405 lldb_private::formatters::NSDictionarySummaryProvider
<false>,
406 "NSDictionary summary provider", "__NSSingleEntryDictionaryI",
408 AddCXXSummary(objc_category_sp
,
409 lldb_private::formatters::NSDictionarySummaryProvider
<false>,
410 "NSDictionary summary provider", "__NSDictionaryM",
412 AddCXXSummary(objc_category_sp
,
413 lldb_private::formatters::NSDictionarySummaryProvider
<true>,
414 "NSDictionary summary provider", "CFDictionaryRef",
416 AddCXXSummary(objc_category_sp
,
417 lldb_private::formatters::NSDictionarySummaryProvider
<true>,
418 "NSDictionary summary provider", "__CFDictionary",
420 AddCXXSummary(objc_category_sp
,
421 lldb_private::formatters::NSDictionarySummaryProvider
<true>,
422 "NSDictionary summary provider", "CFMutableDictionaryRef",
425 AddCXXSummary(objc_category_sp
,
426 lldb_private::formatters::NSSetSummaryProvider
<false>,
427 "NSSet summary", "NSSet", appkit_flags
);
428 AddCXXSummary(objc_category_sp
,
429 lldb_private::formatters::NSSetSummaryProvider
<false>,
430 "NSMutableSet summary", "NSMutableSet", appkit_flags
);
431 AddCXXSummary(objc_category_sp
,
432 lldb_private::formatters::NSSetSummaryProvider
<true>,
433 "CFSetRef summary", "CFSetRef", appkit_flags
);
434 AddCXXSummary(objc_category_sp
,
435 lldb_private::formatters::NSSetSummaryProvider
<true>,
436 "CFMutableSetRef summary", "CFMutableSetRef", appkit_flags
);
437 AddCXXSummary(objc_category_sp
,
438 lldb_private::formatters::NSSetSummaryProvider
<false>,
439 "__NSCFSet summary", "__NSCFSet", appkit_flags
);
440 AddCXXSummary(objc_category_sp
,
441 lldb_private::formatters::NSSetSummaryProvider
<false>,
442 "__CFSet summary", "__CFSet", appkit_flags
);
443 AddCXXSummary(objc_category_sp
,
444 lldb_private::formatters::NSSetSummaryProvider
<false>,
445 "__NSSetI summary", "__NSSetI", appkit_flags
);
446 AddCXXSummary(objc_category_sp
,
447 lldb_private::formatters::NSSetSummaryProvider
<false>,
448 "__NSSetM summary", "__NSSetM", appkit_flags
);
449 AddCXXSummary(objc_category_sp
,
450 lldb_private::formatters::NSSetSummaryProvider
<false>,
451 "NSCountedSet summary", "NSCountedSet", appkit_flags
);
452 AddCXXSummary(objc_category_sp
,
453 lldb_private::formatters::NSSetSummaryProvider
<false>,
454 "NSMutableSet summary", "NSMutableSet", appkit_flags
);
455 AddCXXSummary(objc_category_sp
,
456 lldb_private::formatters::NSSetSummaryProvider
<false>,
457 "NSOrderedSet summary", "NSOrderedSet", appkit_flags
);
458 AddCXXSummary(objc_category_sp
,
459 lldb_private::formatters::NSSetSummaryProvider
<false>,
460 "__NSOrderedSetI summary", "__NSOrderedSetI", appkit_flags
);
461 AddCXXSummary(objc_category_sp
,
462 lldb_private::formatters::NSSetSummaryProvider
<false>,
463 "__NSOrderedSetM summary", "__NSOrderedSetM", appkit_flags
);
465 AddCXXSummary(objc_category_sp
,
466 lldb_private::formatters::NSError_SummaryProvider
,
467 "NSError summary provider", "NSError", appkit_flags
);
468 AddCXXSummary(objc_category_sp
,
469 lldb_private::formatters::NSException_SummaryProvider
,
470 "NSException summary provider", "NSException", appkit_flags
);
472 // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}",
473 // ConstString("$_lldb_typegen_nspair"), appkit_flags);
475 appkit_flags
.SetDontShowChildren(true);
477 AddCXXSynthetic(objc_category_sp
,
478 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
479 "NSArray synthetic children", "__NSArrayM",
480 ScriptedSyntheticChildren::Flags());
481 AddCXXSynthetic(objc_category_sp
,
482 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
483 "NSArray synthetic children", "__NSArrayI",
484 ScriptedSyntheticChildren::Flags());
485 AddCXXSynthetic(objc_category_sp
,
486 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
487 "NSArray synthetic children", "__NSArray0",
488 ScriptedSyntheticChildren::Flags());
489 AddCXXSynthetic(objc_category_sp
,
490 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
491 "NSArray synthetic children", "__NSSingleObjectArrayI",
492 ScriptedSyntheticChildren::Flags());
493 AddCXXSynthetic(objc_category_sp
,
494 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
495 "NSArray synthetic children", "NSArray",
496 ScriptedSyntheticChildren::Flags());
497 AddCXXSynthetic(objc_category_sp
,
498 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
499 "NSArray synthetic children", "NSConstantArray",
500 ScriptedSyntheticChildren::Flags());
501 AddCXXSynthetic(objc_category_sp
,
502 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
503 "NSArray synthetic children", "NSMutableArray",
504 ScriptedSyntheticChildren::Flags());
505 AddCXXSynthetic(objc_category_sp
,
506 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
507 "NSArray synthetic children", "__NSCFArray",
508 ScriptedSyntheticChildren::Flags());
509 AddCXXSynthetic(objc_category_sp
,
510 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
511 "NSArray synthetic children", "_NSCallStackArray",
512 ScriptedSyntheticChildren::Flags());
513 AddCXXSynthetic(objc_category_sp
,
514 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
515 "NSArray synthetic children", "CFMutableArrayRef",
516 ScriptedSyntheticChildren::Flags());
517 AddCXXSynthetic(objc_category_sp
,
518 lldb_private::formatters::NSArraySyntheticFrontEndCreator
,
519 "NSArray synthetic children", "CFArrayRef",
520 ScriptedSyntheticChildren::Flags());
524 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
525 "NSDictionary synthetic children", "__NSDictionaryM",
526 ScriptedSyntheticChildren::Flags());
529 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
530 "NSDictionary synthetic children", "NSConstantDictionary",
531 ScriptedSyntheticChildren::Flags());
534 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
535 "NSDictionary synthetic children", "__NSDictionaryI",
536 ScriptedSyntheticChildren::Flags());
539 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
540 "NSDictionary synthetic children", "__NSSingleEntryDictionaryI",
541 ScriptedSyntheticChildren::Flags());
544 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
545 "NSDictionary synthetic children", "__NSCFDictionary",
546 ScriptedSyntheticChildren::Flags());
549 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
550 "NSDictionary synthetic children", "NSDictionary",
551 ScriptedSyntheticChildren::Flags());
554 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
555 "NSDictionary synthetic children", "NSMutableDictionary",
556 ScriptedSyntheticChildren::Flags());
559 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
560 "NSDictionary synthetic children", "CFDictionaryRef",
561 ScriptedSyntheticChildren::Flags());
564 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
565 "NSDictionary synthetic children", "CFMutableDictionaryRef",
566 ScriptedSyntheticChildren::Flags());
569 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator
,
570 "NSDictionary synthetic children", "__CFDictionary",
571 ScriptedSyntheticChildren::Flags());
573 AddCXXSynthetic(objc_category_sp
,
574 lldb_private::formatters::NSErrorSyntheticFrontEndCreator
,
575 "NSError synthetic children", "NSError",
576 ScriptedSyntheticChildren::Flags());
577 AddCXXSynthetic(objc_category_sp
,
578 lldb_private::formatters::NSExceptionSyntheticFrontEndCreator
,
579 "NSException synthetic children", "NSException",
580 ScriptedSyntheticChildren::Flags());
583 objc_category_sp
, lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
584 "NSSet synthetic children", "NSSet", ScriptedSyntheticChildren::Flags());
585 AddCXXSynthetic(objc_category_sp
,
586 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
587 "__NSSetI synthetic children", "__NSSetI",
588 ScriptedSyntheticChildren::Flags());
589 AddCXXSynthetic(objc_category_sp
,
590 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
591 "__NSSetM synthetic children", "__NSSetM",
592 ScriptedSyntheticChildren::Flags());
593 AddCXXSynthetic(objc_category_sp
,
594 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
595 "__NSCFSet synthetic children", "__NSCFSet",
596 ScriptedSyntheticChildren::Flags());
597 AddCXXSynthetic(objc_category_sp
,
598 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
599 "CFSetRef synthetic children", "CFSetRef",
600 ScriptedSyntheticChildren::Flags());
602 AddCXXSynthetic(objc_category_sp
,
603 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
604 "NSMutableSet synthetic children", "NSMutableSet",
605 ScriptedSyntheticChildren::Flags());
606 AddCXXSynthetic(objc_category_sp
,
607 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
608 "NSOrderedSet synthetic children", "NSOrderedSet",
609 ScriptedSyntheticChildren::Flags());
610 AddCXXSynthetic(objc_category_sp
,
611 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
612 "__NSOrderedSetI synthetic children", "__NSOrderedSetI",
613 ScriptedSyntheticChildren::Flags());
614 AddCXXSynthetic(objc_category_sp
,
615 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
616 "__NSOrderedSetM synthetic children", "__NSOrderedSetM",
617 ScriptedSyntheticChildren::Flags());
618 AddCXXSynthetic(objc_category_sp
,
619 lldb_private::formatters::NSSetSyntheticFrontEndCreator
,
620 "__CFSet synthetic children", "__CFSet",
621 ScriptedSyntheticChildren::Flags());
623 AddCXXSynthetic(objc_category_sp
,
624 lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator
,
625 "NSIndexPath synthetic children", "NSIndexPath",
626 ScriptedSyntheticChildren::Flags());
628 AddCXXSummary(objc_category_sp
,
629 lldb_private::formatters::CFBagSummaryProvider
,
630 "CFBag summary provider", "CFBagRef", appkit_flags
);
631 AddCXXSummary(objc_category_sp
,
632 lldb_private::formatters::CFBagSummaryProvider
,
633 "CFBag summary provider", "__CFBag", appkit_flags
);
634 AddCXXSummary(objc_category_sp
,
635 lldb_private::formatters::CFBagSummaryProvider
,
636 "CFBag summary provider", "const struct __CFBag", appkit_flags
);
637 AddCXXSummary(objc_category_sp
,
638 lldb_private::formatters::CFBagSummaryProvider
,
639 "CFBag summary provider", "CFMutableBagRef", appkit_flags
);
642 objc_category_sp
, lldb_private::formatters::CFBinaryHeapSummaryProvider
,
643 "CFBinaryHeap summary provider", "CFBinaryHeapRef", appkit_flags
);
645 objc_category_sp
, lldb_private::formatters::CFBinaryHeapSummaryProvider
,
646 "CFBinaryHeap summary provider", "__CFBinaryHeap", appkit_flags
);
648 AddCXXSummary(objc_category_sp
,
649 lldb_private::formatters::NSStringSummaryProvider
,
650 "NSString summary provider", "NSString", appkit_flags
);
651 AddCXXSummary(objc_category_sp
,
652 lldb_private::formatters::NSStringSummaryProvider
,
653 "NSString summary provider", "CFStringRef", appkit_flags
);
654 AddCXXSummary(objc_category_sp
,
655 lldb_private::formatters::NSStringSummaryProvider
,
656 "NSString summary provider", "__CFString", appkit_flags
);
658 objc_category_sp
, lldb_private::formatters::NSStringSummaryProvider
,
659 "NSString summary provider", "CFMutableStringRef", appkit_flags
);
660 AddCXXSummary(objc_category_sp
,
661 lldb_private::formatters::NSStringSummaryProvider
,
662 "NSString summary provider", "NSMutableString", appkit_flags
);
664 objc_category_sp
, lldb_private::formatters::NSStringSummaryProvider
,
665 "NSString summary provider", "__NSCFConstantString", appkit_flags
);
666 AddCXXSummary(objc_category_sp
,
667 lldb_private::formatters::NSStringSummaryProvider
,
668 "NSString summary provider", "__NSCFString", appkit_flags
);
670 objc_category_sp
, lldb_private::formatters::NSStringSummaryProvider
,
671 "NSString summary provider", "NSCFConstantString", appkit_flags
);
672 AddCXXSummary(objc_category_sp
,
673 lldb_private::formatters::NSStringSummaryProvider
,
674 "NSString summary provider", "NSCFString", appkit_flags
);
675 AddCXXSummary(objc_category_sp
,
676 lldb_private::formatters::NSStringSummaryProvider
,
677 "NSString summary provider", "NSPathStore2", appkit_flags
);
679 objc_category_sp
, lldb_private::formatters::NSStringSummaryProvider
,
680 "NSString summary provider", "NSTaggedPointerString", appkit_flags
);
682 AddCXXSummary(objc_category_sp
,
683 lldb_private::formatters::NSAttributedStringSummaryProvider
,
684 "NSAttributedString summary provider", "NSAttributedString",
688 lldb_private::formatters::NSMutableAttributedStringSummaryProvider
,
689 "NSMutableAttributedString summary provider", "NSMutableAttributedString",
693 lldb_private::formatters::NSMutableAttributedStringSummaryProvider
,
694 "NSMutableAttributedString summary provider",
695 "NSConcreteMutableAttributedString", appkit_flags
);
697 AddCXXSummary(objc_category_sp
,
698 lldb_private::formatters::NSBundleSummaryProvider
,
699 "NSBundle summary provider", "NSBundle", appkit_flags
);
701 AddCXXSummary(objc_category_sp
,
702 lldb_private::formatters::NSDataSummaryProvider
<false>,
703 "NSData summary provider", "NSData", appkit_flags
);
704 AddCXXSummary(objc_category_sp
,
705 lldb_private::formatters::NSDataSummaryProvider
<false>,
706 "NSData summary provider", "_NSInlineData", appkit_flags
);
707 AddCXXSummary(objc_category_sp
,
708 lldb_private::formatters::NSDataSummaryProvider
<false>,
709 "NSData summary provider", "NSConcreteData", appkit_flags
);
711 objc_category_sp
, lldb_private::formatters::NSDataSummaryProvider
<false>,
712 "NSData summary provider", "NSConcreteMutableData", appkit_flags
);
713 AddCXXSummary(objc_category_sp
,
714 lldb_private::formatters::NSDataSummaryProvider
<false>,
715 "NSData summary provider", "NSMutableData", appkit_flags
);
716 AddCXXSummary(objc_category_sp
,
717 lldb_private::formatters::NSDataSummaryProvider
<false>,
718 "NSData summary provider", "__NSCFData", appkit_flags
);
719 AddCXXSummary(objc_category_sp
,
720 lldb_private::formatters::NSDataSummaryProvider
<true>,
721 "NSData summary provider", "CFDataRef", appkit_flags
);
722 AddCXXSummary(objc_category_sp
,
723 lldb_private::formatters::NSDataSummaryProvider
<true>,
724 "NSData summary provider", "CFMutableDataRef", appkit_flags
);
726 AddCXXSummary(objc_category_sp
,
727 lldb_private::formatters::NSMachPortSummaryProvider
,
728 "NSMachPort summary provider", "NSMachPort", appkit_flags
);
731 objc_category_sp
, lldb_private::formatters::NSNotificationSummaryProvider
,
732 "NSNotification summary provider", "NSNotification", appkit_flags
);
733 AddCXXSummary(objc_category_sp
,
734 lldb_private::formatters::NSNotificationSummaryProvider
,
735 "NSNotification summary provider", "NSConcreteNotification",
738 AddCXXSummary(objc_category_sp
,
739 lldb_private::formatters::NSNumberSummaryProvider
,
740 "NSNumber summary provider", "NSNumber", appkit_flags
);
742 objc_category_sp
, lldb_private::formatters::NSNumberSummaryProvider
,
743 "NSNumber summary provider", "NSConstantIntegerNumber", appkit_flags
);
745 objc_category_sp
, lldb_private::formatters::NSNumberSummaryProvider
,
746 "NSNumber summary provider", "NSConstantDoubleNumber", appkit_flags
);
748 objc_category_sp
, lldb_private::formatters::NSNumberSummaryProvider
,
749 "NSNumber summary provider", "NSConstantFloatNumber", appkit_flags
);
750 AddCXXSummary(objc_category_sp
,
751 lldb_private::formatters::NSNumberSummaryProvider
,
752 "CFNumberRef summary provider", "CFNumberRef", appkit_flags
);
753 AddCXXSummary(objc_category_sp
,
754 lldb_private::formatters::NSNumberSummaryProvider
,
755 "NSNumber summary provider", "__NSCFBoolean", appkit_flags
);
756 AddCXXSummary(objc_category_sp
,
757 lldb_private::formatters::NSNumberSummaryProvider
,
758 "NSNumber summary provider", "__NSCFNumber", appkit_flags
);
759 AddCXXSummary(objc_category_sp
,
760 lldb_private::formatters::NSNumberSummaryProvider
,
761 "NSNumber summary provider", "NSCFBoolean", appkit_flags
);
762 AddCXXSummary(objc_category_sp
,
763 lldb_private::formatters::NSNumberSummaryProvider
,
764 "NSNumber summary provider", "NSCFNumber", appkit_flags
);
766 objc_category_sp
, lldb_private::formatters::NSNumberSummaryProvider
,
767 "NSDecimalNumber summary provider", "NSDecimalNumber", appkit_flags
);
769 AddCXXSummary(objc_category_sp
,
770 lldb_private::formatters::NSURLSummaryProvider
,
771 "NSURL summary provider", "NSURL", appkit_flags
);
772 AddCXXSummary(objc_category_sp
,
773 lldb_private::formatters::NSURLSummaryProvider
,
774 "NSURL summary provider", "CFURLRef", appkit_flags
);
776 AddCXXSummary(objc_category_sp
,
777 lldb_private::formatters::NSDateSummaryProvider
,
778 "NSDate summary provider", "NSDate", appkit_flags
);
779 AddCXXSummary(objc_category_sp
,
780 lldb_private::formatters::NSDateSummaryProvider
,
781 "NSDate summary provider", "__NSDate", appkit_flags
);
782 AddCXXSummary(objc_category_sp
,
783 lldb_private::formatters::NSDateSummaryProvider
,
784 "NSDate summary provider", "__NSTaggedDate", appkit_flags
);
785 AddCXXSummary(objc_category_sp
,
786 lldb_private::formatters::NSDateSummaryProvider
,
787 "NSDate summary provider", "NSCalendarDate", appkit_flags
);
789 AddCXXSummary(objc_category_sp
,
790 lldb_private::formatters::NSTimeZoneSummaryProvider
,
791 "NSTimeZone summary provider", "NSTimeZone", appkit_flags
);
792 AddCXXSummary(objc_category_sp
,
793 lldb_private::formatters::NSTimeZoneSummaryProvider
,
794 "NSTimeZone summary provider", "CFTimeZoneRef", appkit_flags
);
795 AddCXXSummary(objc_category_sp
,
796 lldb_private::formatters::NSTimeZoneSummaryProvider
,
797 "NSTimeZone summary provider", "__NSTimeZone", appkit_flags
);
799 // CFAbsoluteTime is actually a double rather than a pointer to an object we
800 // do not care about the numeric value, since it is probably meaningless to
802 appkit_flags
.SetDontShowValue(true);
804 objc_category_sp
, lldb_private::formatters::CFAbsoluteTimeSummaryProvider
,
805 "CFAbsoluteTime summary provider", "CFAbsoluteTime", appkit_flags
);
806 appkit_flags
.SetDontShowValue(false);
808 AddCXXSummary(objc_category_sp
,
809 lldb_private::formatters::NSIndexSetSummaryProvider
,
810 "NSIndexSet summary provider", "NSIndexSet", appkit_flags
);
812 objc_category_sp
, lldb_private::formatters::NSIndexSetSummaryProvider
,
813 "NSIndexSet summary provider", "NSMutableIndexSet", appkit_flags
);
815 AddStringSummary(objc_category_sp
,
816 "@\"${var.month%d}/${var.day%d}/${var.year%d} "
817 "${var.hour%d}:${var.minute%d}:${var.second}\"",
818 "CFGregorianDate", appkit_flags
);
820 AddCXXSummary(objc_category_sp
,
821 lldb_private::formatters::CFBitVectorSummaryProvider
,
822 "CFBitVector summary provider", "CFBitVectorRef", appkit_flags
);
824 objc_category_sp
, lldb_private::formatters::CFBitVectorSummaryProvider
,
825 "CFBitVector summary provider", "CFMutableBitVectorRef", appkit_flags
);
826 AddCXXSummary(objc_category_sp
,
827 lldb_private::formatters::CFBitVectorSummaryProvider
,
828 "CFBitVector summary provider", "__CFBitVector", appkit_flags
);
830 objc_category_sp
, lldb_private::formatters::CFBitVectorSummaryProvider
,
831 "CFBitVector summary provider", "__CFMutableBitVector", appkit_flags
);
834 static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp
) {
835 if (!objc_category_sp
)
838 TypeSummaryImpl::Flags cm_flags
;
839 cm_flags
.SetCascades(true)
840 .SetDontShowChildren(false)
841 .SetDontShowValue(false)
842 .SetHideItemNames(false)
843 .SetShowMembersOneLiner(false)
844 .SetSkipPointers(false)
845 .SetSkipReferences(false);
847 AddCXXSummary(objc_category_sp
,
848 lldb_private::formatters::CMTimeSummaryProvider
,
849 "CMTime summary provider", "CMTime", cm_flags
);
852 lldb::TypeCategoryImplSP
ObjCLanguage::GetFormatters() {
853 static llvm::once_flag g_initialize
;
854 static TypeCategoryImplSP g_category
;
856 llvm::call_once(g_initialize
, [this]() -> void {
857 DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),
860 LoadCoreMediaFormatters(g_category
);
861 LoadObjCFormatters(g_category
);
867 std::vector
<FormattersMatchCandidate
>
868 ObjCLanguage::GetPossibleFormattersMatches(ValueObject
&valobj
,
869 lldb::DynamicValueType use_dynamic
) {
870 std::vector
<FormattersMatchCandidate
> result
;
872 if (use_dynamic
== lldb::eNoDynamicValues
)
875 CompilerType
compiler_type(valobj
.GetCompilerType());
877 const bool check_cpp
= false;
878 const bool check_objc
= true;
879 bool canBeObjCDynamic
=
880 compiler_type
.IsPossibleDynamicType(nullptr, check_cpp
, check_objc
);
882 if (canBeObjCDynamic
&& ClangUtil::IsClangType(compiler_type
)) {
884 lldb::ProcessSP process_sp
= valobj
.GetProcessSP();
887 ObjCLanguageRuntime
*runtime
= ObjCLanguageRuntime::Get(*process_sp
);
888 if (runtime
== nullptr)
890 ObjCLanguageRuntime::ClassDescriptorSP
objc_class_sp(
891 runtime
->GetClassDescriptor(valobj
));
894 if (ConstString name
= objc_class_sp
->GetClassName())
896 {name
, valobj
.GetTargetSP()->GetDebugger().GetScriptInterpreter(),
897 TypeImpl(objc_class_sp
->GetType()),
898 FormattersMatchCandidate::Flags
{}});
905 std::unique_ptr
<Language::TypeScavenger
> ObjCLanguage::GetTypeScavenger() {
906 class ObjCScavengerResult
: public Language::TypeScavenger::Result
{
908 ObjCScavengerResult(CompilerType type
)
909 : Language::TypeScavenger::Result(), m_compiler_type(type
) {}
911 bool IsValid() override
{ return m_compiler_type
.IsValid(); }
913 bool DumpToStream(Stream
&stream
, bool print_help_if_available
) override
{
915 m_compiler_type
.DumpTypeDescription(&stream
);
923 CompilerType m_compiler_type
;
926 class ObjCRuntimeScavenger
: public Language::TypeScavenger
{
928 bool Find_Impl(ExecutionContextScope
*exe_scope
, const char *key
,
929 ResultSet
&results
) override
{
932 if (auto *process
= exe_scope
->CalculateProcess().get()) {
933 if (auto *objc_runtime
= ObjCLanguageRuntime::Get(*process
)) {
934 if (auto *decl_vendor
= objc_runtime
->GetDeclVendor()) {
935 ConstString
name(key
);
936 for (const CompilerType
&type
:
937 decl_vendor
->FindTypes(name
, /*max_matches*/ UINT32_MAX
)) {
939 std::unique_ptr
<Language::TypeScavenger::Result
> result(
940 new ObjCScavengerResult(type
));
941 results
.insert(std::move(result
));
950 friend class lldb_private::ObjCLanguage
;
953 class ObjCModulesScavenger
: public Language::TypeScavenger
{
955 bool Find_Impl(ExecutionContextScope
*exe_scope
, const char *key
,
956 ResultSet
&results
) override
{
959 if (auto *target
= exe_scope
->CalculateTarget().get()) {
960 auto *persistent_vars
= llvm::cast
<ClangPersistentVariables
>(
961 target
->GetPersistentExpressionStateForLanguage(
962 lldb::eLanguageTypeC
));
963 if (std::shared_ptr
<ClangModulesDeclVendor
> clang_modules_decl_vendor
=
964 persistent_vars
->GetClangModulesDeclVendor()) {
965 ConstString
key_cs(key
);
966 auto types
= clang_modules_decl_vendor
->FindTypes(
967 key_cs
, /*max_matches*/ UINT32_MAX
);
968 if (!types
.empty()) {
970 std::unique_ptr
<Language::TypeScavenger::Result
> result(
971 new ObjCScavengerResult(types
.front()));
972 results
.insert(std::move(result
));
980 friend class lldb_private::ObjCLanguage
;
983 class ObjCDebugInfoScavenger
: public Language::ImageListTypeScavenger
{
985 CompilerType
AdjustForInclusion(CompilerType
&candidate
) override
{
986 LanguageType
lang_type(candidate
.GetMinimumLanguage());
987 if (!Language::LanguageIsObjC(lang_type
))
988 return CompilerType();
989 if (candidate
.IsTypedefType())
990 return candidate
.GetTypedefedType();
995 return std::unique_ptr
<TypeScavenger
>(
996 new Language::EitherTypeScavenger
<ObjCModulesScavenger
,
997 ObjCRuntimeScavenger
,
998 ObjCDebugInfoScavenger
>());
1001 std::pair
<llvm::StringRef
, llvm::StringRef
>
1002 ObjCLanguage::GetFormatterPrefixSuffix(llvm::StringRef type_hint
) {
1003 static constexpr llvm::StringRef empty
;
1004 static const llvm::StringMap
<
1005 std::pair
<const llvm::StringRef
, const llvm::StringRef
>>
1007 {"CFBag", {"@", empty
}},
1008 {"CFBinaryHeap", {"@", empty
}},
1009 {"NSString", {"@", empty
}},
1010 {"NSString*", {"@", empty
}},
1011 {"NSNumber:char", {"(char)", empty
}},
1012 {"NSNumber:short", {"(short)", empty
}},
1013 {"NSNumber:int", {"(int)", empty
}},
1014 {"NSNumber:long", {"(long)", empty
}},
1015 {"NSNumber:int128_t", {"(int128_t)", empty
}},
1016 {"NSNumber:float", {"(float)", empty
}},
1017 {"NSNumber:double", {"(double)", empty
}},
1018 {"NSData", {"@\"", "\""}},
1019 {"NSArray", {"@\"", "\""}},
1021 return g_affix_map
.lookup(type_hint
);
1024 bool ObjCLanguage::IsNilReference(ValueObject
&valobj
) {
1025 const uint32_t mask
= eTypeIsObjC
| eTypeIsPointer
;
1026 bool isObjCpointer
=
1027 (((valobj
.GetCompilerType().GetTypeInfo(nullptr)) & mask
) == mask
);
1030 bool canReadValue
= true;
1031 bool isZero
= valobj
.GetValueAsUnsigned(0, &canReadValue
) == 0;
1032 return canReadValue
&& isZero
;
1035 bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path
) const {
1036 const auto suffixes
= {".h", ".m", ".M"};
1037 for (auto suffix
: suffixes
) {
1038 if (file_path
.ends_with_insensitive(suffix
))