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