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