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

source code of lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp