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