blob: 82143d288e887b4326d03308823d9f8783fcba02 [file] [log] [blame]
Eugene Zelenko8d15f332015-10-20 01:10:59 +00001//===-- ObjCLanguage.cpp ----------------------------------------*- C++ -*-===//
Enrico Granata5f9d3102015-08-27 21:33:50 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eugene Zelenko8d15f332015-10-20 01:10:59 +000010// C Includes
11// C++ Includes
Chaoren Lin3e130052015-09-14 22:39:34 +000012#include <mutex>
13
Eugene Zelenko8d15f332015-10-20 01:10:59 +000014// Other libraries and framework includes
15// Project includes
16#include "ObjCLanguage.h"
17
Enrico Granata5f9d3102015-08-27 21:33:50 +000018#include "lldb/Core/ConstString.h"
19#include "lldb/Core/PluginManager.h"
Jim Inghamaa816b82015-09-02 01:59:14 +000020#include "lldb/Core/StreamString.h"
Enrico Granatad3233c12015-09-09 01:10:46 +000021#include "lldb/Core/ValueObject.h"
Enrico Granata170c3952015-09-14 22:18:32 +000022#include "lldb/DataFormatters/DataVisualization.h"
23#include "lldb/DataFormatters/FormattersHelpers.h"
Enrico Granatad3233c12015-09-09 01:10:46 +000024#include "lldb/Symbol/CompilerType.h"
25#include "lldb/Target/ObjCLanguageRuntime.h"
Enrico Granata5f9d3102015-08-27 21:33:50 +000026
Enrico Granata170c3952015-09-14 22:18:32 +000027#include "CF.h"
28#include "Cocoa.h"
29#include "CoreMedia.h"
Enrico Granata7de855c2015-10-02 20:59:58 +000030#include "NSDictionary.h"
31#include "NSSet.h"
32#include "NSString.h"
Enrico Granata170c3952015-09-14 22:18:32 +000033
Enrico Granata5f9d3102015-08-27 21:33:50 +000034using namespace lldb;
35using namespace lldb_private;
Enrico Granata170c3952015-09-14 22:18:32 +000036using namespace lldb_private::formatters;
Enrico Granata5f9d3102015-08-27 21:33:50 +000037
38void
39ObjCLanguage::Initialize()
40{
41 PluginManager::RegisterPlugin (GetPluginNameStatic(),
42 "Objective-C Language",
43 CreateInstance);
44}
45
46void
47ObjCLanguage::Terminate()
48{
49 PluginManager::UnregisterPlugin (CreateInstance);
50}
51
52lldb_private::ConstString
53ObjCLanguage::GetPluginNameStatic()
54{
55 static ConstString g_name("objc");
56 return g_name;
57}
58
Enrico Granata5f9d3102015-08-27 21:33:50 +000059//------------------------------------------------------------------
60// PluginInterface protocol
61//------------------------------------------------------------------
62lldb_private::ConstString
63ObjCLanguage::GetPluginName()
64{
65 return GetPluginNameStatic();
66}
67
68uint32_t
69ObjCLanguage::GetPluginVersion()
70{
71 return 1;
72}
73
74//------------------------------------------------------------------
75// Static Functions
76//------------------------------------------------------------------
77Language *
78ObjCLanguage::CreateInstance (lldb::LanguageType language)
79{
80 switch (language)
81 {
82 case lldb::eLanguageTypeObjC:
83 return new ObjCLanguage();
84 default:
85 return nullptr;
86 }
87}
Jim Inghamaa816b82015-09-02 01:59:14 +000088
89void
90ObjCLanguage::MethodName::Clear()
91{
92 m_full.Clear();
93 m_class.Clear();
94 m_category.Clear();
95 m_selector.Clear();
96 m_type = eTypeUnspecified;
97 m_category_is_valid = false;
98}
99
100bool
101ObjCLanguage::MethodName::SetName (const char *name, bool strict)
102{
103 Clear();
104 if (name && name[0])
105 {
106 // If "strict" is true. then the method must be specified with a
107 // '+' or '-' at the beginning. If "strict" is false, then the '+'
108 // or '-' can be omitted
109 bool valid_prefix = false;
110
111 if (name[0] == '+' || name[0] == '-')
112 {
113 valid_prefix = name[1] == '[';
114 if (name[0] == '+')
115 m_type = eTypeClassMethod;
116 else
117 m_type = eTypeInstanceMethod;
118 }
119 else if (!strict)
120 {
121 // "strict" is false, the name just needs to start with '['
122 valid_prefix = name[0] == '[';
123 }
124
125 if (valid_prefix)
126 {
127 int name_len = strlen (name);
128 // Objective C methods must have at least:
129 // "-[" or "+[" prefix
130 // One character for a class name
131 // One character for the space between the class name
132 // One character for the method name
133 // "]" suffix
134 if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']')
135 {
136 m_full.SetCStringWithLength(name, name_len);
137 }
138 }
139 }
140 return IsValid(strict);
141}
142
143const ConstString &
144ObjCLanguage::MethodName::GetClassName ()
145{
146 if (!m_class)
147 {
148 if (IsValid(false))
149 {
150 const char *full = m_full.GetCString();
151 const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
152 const char *paren_pos = strchr (class_start, '(');
153 if (paren_pos)
154 {
155 m_class.SetCStringWithLength (class_start, paren_pos - class_start);
156 }
157 else
158 {
159 // No '(' was found in the full name, we can definitively say
160 // that our category was valid (and empty).
161 m_category_is_valid = true;
162 const char *space_pos = strchr (full, ' ');
163 if (space_pos)
164 {
165 m_class.SetCStringWithLength (class_start, space_pos - class_start);
166 if (!m_class_category)
167 {
168 // No category in name, so we can also fill in the m_class_category
169 m_class_category = m_class;
170 }
171 }
172 }
173 }
174 }
175 return m_class;
176}
177
178const ConstString &
179ObjCLanguage::MethodName::GetClassNameWithCategory ()
180{
181 if (!m_class_category)
182 {
183 if (IsValid(false))
184 {
185 const char *full = m_full.GetCString();
186 const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
187 const char *space_pos = strchr (full, ' ');
188 if (space_pos)
189 {
190 m_class_category.SetCStringWithLength (class_start, space_pos - class_start);
191 // If m_class hasn't been filled in and the class with category doesn't
192 // contain a '(', then we can also fill in the m_class
193 if (!m_class && strchr (m_class_category.GetCString(), '(') == NULL)
194 {
195 m_class = m_class_category;
196 // No '(' was found in the full name, we can definitively say
197 // that our category was valid (and empty).
198 m_category_is_valid = true;
199
200 }
201 }
202 }
203 }
204 return m_class_category;
205}
206
207const ConstString &
208ObjCLanguage::MethodName::GetSelector ()
209{
210 if (!m_selector)
211 {
212 if (IsValid(false))
213 {
214 const char *full = m_full.GetCString();
215 const char *space_pos = strchr (full, ' ');
216 if (space_pos)
217 {
218 ++space_pos; // skip the space
219 m_selector.SetCStringWithLength (space_pos, m_full.GetLength() - (space_pos - full) - 1);
220 }
221 }
222 }
223 return m_selector;
224}
225
226const ConstString &
227ObjCLanguage::MethodName::GetCategory ()
228{
229 if (!m_category_is_valid && !m_category)
230 {
231 if (IsValid(false))
232 {
233 m_category_is_valid = true;
234 const char *full = m_full.GetCString();
235 const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
236 const char *open_paren_pos = strchr (class_start, '(');
237 if (open_paren_pos)
238 {
239 ++open_paren_pos; // Skip the open paren
240 const char *close_paren_pos = strchr (open_paren_pos, ')');
241 if (close_paren_pos)
242 m_category.SetCStringWithLength (open_paren_pos, close_paren_pos - open_paren_pos);
243 }
244 }
245 }
246 return m_category;
247}
248
249ConstString
250ObjCLanguage::MethodName::GetFullNameWithoutCategory (bool empty_if_no_category)
251{
252 if (IsValid(false))
253 {
254 if (HasCategory())
255 {
256 StreamString strm;
257 if (m_type == eTypeClassMethod)
258 strm.PutChar('+');
259 else if (m_type == eTypeInstanceMethod)
260 strm.PutChar('-');
261 strm.Printf("[%s %s]", GetClassName().GetCString(), GetSelector().GetCString());
262 return ConstString(strm.GetString().c_str());
263 }
264
265 if (!empty_if_no_category)
266 {
267 // Just return the full name since it doesn't have a category
268 return GetFullName();
269 }
270 }
271 return ConstString();
272}
273
274size_t
275ObjCLanguage::MethodName::GetFullNames (std::vector<ConstString> &names, bool append)
276{
277 if (!append)
278 names.clear();
279 if (IsValid(false))
280 {
281 StreamString strm;
282 const bool is_class_method = m_type == eTypeClassMethod;
283 const bool is_instance_method = m_type == eTypeInstanceMethod;
284 const ConstString &category = GetCategory();
285 if (is_class_method || is_instance_method)
286 {
287 names.push_back (m_full);
288 if (category)
289 {
290 strm.Printf("%c[%s %s]",
291 is_class_method ? '+' : '-',
292 GetClassName().GetCString(),
293 GetSelector().GetCString());
294 names.push_back(ConstString(strm.GetString().c_str()));
295 }
296 }
297 else
298 {
299 const ConstString &class_name = GetClassName();
300 const ConstString &selector = GetSelector();
301 strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
302 names.push_back(ConstString(strm.GetString().c_str()));
303 strm.Clear();
304 strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
305 names.push_back(ConstString(strm.GetString().c_str()));
306 strm.Clear();
307 if (category)
308 {
309 strm.Printf("+[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
310 names.push_back(ConstString(strm.GetString().c_str()));
311 strm.Clear();
312 strm.Printf("-[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
313 names.push_back(ConstString(strm.GetString().c_str()));
314 }
315 }
316 }
317 return names.size();
318}
Enrico Granatad3233c12015-09-09 01:10:46 +0000319
Enrico Granata170c3952015-09-14 22:18:32 +0000320static void
321LoadObjCFormatters(TypeCategoryImplSP objc_category_sp)
322{
323 if (!objc_category_sp)
324 return;
325
326 TypeSummaryImpl::Flags objc_flags;
327 objc_flags.SetCascades(false)
328 .SetSkipPointers(true)
329 .SetSkipReferences(true)
330 .SetDontShowChildren(true)
331 .SetDontShowValue(true)
332 .SetShowMembersOneLiner(false)
333 .SetHideItemNames(false);
334
335 lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider,""));
336 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"),
337 ObjC_BOOL_summary);
338 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"),
339 ObjC_BOOL_summary);
340 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"),
341 ObjC_BOOL_summary);
342
343#ifndef LLDB_DISABLE_PYTHON
344 // we need to skip pointers here since we are special casing a SEL* when retrieving its value
345 objc_flags.SetSkipPointers(true);
346 AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("SEL"), objc_flags);
347 AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
348 AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("objc_selector"), objc_flags);
349 AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("objc_selector *"), objc_flags);
350 AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("SEL *"), objc_flags);
351
352 AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCClassSummaryProvider, "Class summary provider", ConstString("Class"), objc_flags);
353
354 SyntheticChildren::Flags class_synth_flags;
355 class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
356
357 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::ObjCClassSyntheticFrontEndCreator, "Class synthetic children", ConstString("Class"), class_synth_flags);
358#endif // LLDB_DISABLE_PYTHON
359
360 objc_flags.SetSkipPointers(false);
361 objc_flags.SetCascades(true);
362 objc_flags.SetSkipReferences(false);
363
364 AddStringSummary (objc_category_sp,
365 "${var.__FuncPtr%A}",
366 ConstString("__block_literal_generic"),
367 objc_flags);
368
369 AddStringSummary(objc_category_sp,
370 "${var.years} years, ${var.months} months, ${var.days} days, ${var.hours} hours, ${var.minutes} minutes ${var.seconds} seconds",
371 ConstString("CFGregorianUnits"),
372 objc_flags);
373 AddStringSummary(objc_category_sp,
374 "location=${var.location} length=${var.length}",
375 ConstString("CFRange"),
376 objc_flags);
377
378 AddStringSummary(objc_category_sp,
379 "location=${var.location}, length=${var.length}",
380 ConstString("NSRange"),
381 objc_flags);
382 AddStringSummary(objc_category_sp,
383 "(${var.origin}, ${var.size}), ...",
384 ConstString("NSRectArray"),
385 objc_flags);
386
387 AddOneLineSummary (objc_category_sp,
388 ConstString("NSPoint"),
389 objc_flags);
390 AddOneLineSummary (objc_category_sp,
391 ConstString("NSSize"),
392 objc_flags);
393 AddOneLineSummary (objc_category_sp,
394 ConstString("NSRect"),
395 objc_flags);
396
397 AddOneLineSummary (objc_category_sp,
398 ConstString("CGSize"),
399 objc_flags);
400 AddOneLineSummary (objc_category_sp,
401 ConstString("CGPoint"),
402 objc_flags);
403 AddOneLineSummary (objc_category_sp,
404 ConstString("CGRect"),
405 objc_flags);
406
407 AddStringSummary(objc_category_sp,
408 "red=${var.red} green=${var.green} blue=${var.blue}",
409 ConstString("RGBColor"),
410 objc_flags);
411 AddStringSummary(objc_category_sp,
412 "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
413 ConstString("Rect"),
414 objc_flags);
415 AddStringSummary(objc_category_sp,
416 "(v=${var.v}, h=${var.h})",
417 ConstString("Point"),
418 objc_flags);
419 AddStringSummary(objc_category_sp,
420 "${var.month}/${var.day}/${var.year} ${var.hour} :${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
421 ConstString("DateTimeRect *"),
422 objc_flags);
423 AddStringSummary(objc_category_sp,
424 "${var.ld.month}/${var.ld.day}/${var.ld.year} ${var.ld.hour} :${var.ld.minute} :${var.ld.second} dayOfWeek:${var.ld.dayOfWeek}",
425 ConstString("LongDateRect"),
426 objc_flags);
427 AddStringSummary(objc_category_sp,
428 "(x=${var.x}, y=${var.y})",
429 ConstString("HIPoint"),
430 objc_flags);
431 AddStringSummary(objc_category_sp,
432 "origin=${var.origin} size=${var.size}",
433 ConstString("HIRect"),
434 objc_flags);
435
436 TypeSummaryImpl::Flags appkit_flags;
437 appkit_flags.SetCascades(true)
438 .SetSkipPointers(false)
439 .SetSkipReferences(false)
440 .SetDontShowChildren(true)
441 .SetDontShowValue(false)
442 .SetShowMembersOneLiner(false)
443 .SetHideItemNames(false);
444
445 appkit_flags.SetDontShowChildren(false);
446
Enrico Granata170c3952015-09-14 22:18:32 +0000447#ifndef LLDB_DISABLE_PYTHON
448 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
449 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
450 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
Enrico Granatabbf1da32015-10-14 22:45:04 +0000451 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArray0"), appkit_flags);
Enrico Granata170c3952015-09-14 22:18:32 +0000452 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
453 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
454 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
455 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
456
457 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
458 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSMutableDictionary"), appkit_flags);
459 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
460 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
461 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
462 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
463 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
464
465 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSSet summary", ConstString("NSSet"), appkit_flags);
466 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
467 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
468 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
469 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
470 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
471 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
472 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
473 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags);
474 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags);
475 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags);
476 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags);
477
478 // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", ConstString("$_lldb_typegen_nspair"), appkit_flags);
479
480 appkit_flags.SetDontShowChildren(true);
481
482 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), ScriptedSyntheticChildren::Flags());
483 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayI"), ScriptedSyntheticChildren::Flags());
Enrico Granatabbf1da32015-10-14 22:45:04 +0000484 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArray0"), ScriptedSyntheticChildren::Flags());
Enrico Granata170c3952015-09-14 22:18:32 +0000485 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSArray"), ScriptedSyntheticChildren::Flags());
486 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), ScriptedSyntheticChildren::Flags());
487 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), ScriptedSyntheticChildren::Flags());
488 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("CFMutableArrayRef"), ScriptedSyntheticChildren::Flags());
489 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("CFArrayRef"), ScriptedSyntheticChildren::Flags());
490
491 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryM"), ScriptedSyntheticChildren::Flags());
492 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryI"), ScriptedSyntheticChildren::Flags());
493 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSCFDictionary"), ScriptedSyntheticChildren::Flags());
494 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSDictionary"), ScriptedSyntheticChildren::Flags());
495 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSMutableDictionary"), ScriptedSyntheticChildren::Flags());
496 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFDictionaryRef"), ScriptedSyntheticChildren::Flags());
497 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), ScriptedSyntheticChildren::Flags());
498
499 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("NSSet"), ScriptedSyntheticChildren::Flags());
500 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSSetI synthetic children", ConstString("__NSSetI"), ScriptedSyntheticChildren::Flags());
501 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSSetM synthetic children", ConstString("__NSSetM"), ScriptedSyntheticChildren::Flags());
502 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSMutableSet synthetic children", ConstString("NSMutableSet"), ScriptedSyntheticChildren::Flags());
503 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSOrderedSet synthetic children", ConstString("NSOrderedSet"), ScriptedSyntheticChildren::Flags());
504 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"), ScriptedSyntheticChildren::Flags());
505 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), ScriptedSyntheticChildren::Flags());
506
507 AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, "NSIndexPath synthetic children", ConstString("NSIndexPath"), ScriptedSyntheticChildren::Flags());
508
509 AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFBagRef"), appkit_flags);
510 AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("__CFBag"), appkit_flags);
511 AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("const struct __CFBag"), appkit_flags);
512 AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags);
513
514 AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"), appkit_flags);
515 AddCXXSummary(objc_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"), appkit_flags);
516
517 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
518 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
519 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__CFString"), appkit_flags);
520 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);
521 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSMutableString"), appkit_flags);
522 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
523 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
524 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
525 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
526 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
527
528 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSAttributedStringSummaryProvider, "NSAttributedString summary provider", ConstString("NSAttributedString"), appkit_flags);
529 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSMutableAttributedString"), appkit_flags);
530 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSConcreteMutableAttributedString"), appkit_flags);
531
532 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider, "NSBundle summary provider", ConstString("NSBundle"), appkit_flags);
533
534 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
535 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
536 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
537 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSMutableData"), appkit_flags);
538 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
539 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
540 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
541
542 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider, "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags);
543
544 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSNotification"), appkit_flags);
545 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSConcreteNotification"), appkit_flags);
546
547 AddStringSummary(objc_category_sp, "domain: ${var._domain} - code: ${var._code}", ConstString("NSError"), appkit_flags);
548 AddStringSummary(objc_category_sp,"name:${var.name%S} reason:${var.reason%S}",ConstString("NSException"),appkit_flags);
549
550 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
551 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags);
552 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
553 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
554 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
555 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
556
557 AddCXXSummary(objc_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSDecimalNumber summary provider", ConstString("NSDecimalNumber"), appkit_flags);
558 AddCXXSummary(objc_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSHost summary provider", ConstString("NSHost"), appkit_flags);
559 AddCXXSummary(objc_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSTask summary provider", ConstString("NSTask"), appkit_flags);
560 AddCXXSummary(objc_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSValue summary provider", ConstString("NSValue"), appkit_flags);
561
562 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("NSURL"), appkit_flags);
563 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
564
565 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("NSDate"), appkit_flags);
566 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
567 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
568 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
569
570 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags);
571 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("CFTimeZoneRef"), appkit_flags);
572 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags);
573
574 // CFAbsoluteTime is actually a double rather than a pointer to an object
575 // we do not care about the numeric value, since it is probably meaningless to users
576 appkit_flags.SetDontShowValue(true);
577 AddCXXSummary(objc_category_sp, lldb_private::formatters::CFAbsoluteTimeSummaryProvider, "CFAbsoluteTime summary provider", ConstString("CFAbsoluteTime"), appkit_flags);
578 appkit_flags.SetDontShowValue(false);
579
580 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags);
581 AddCXXSummary(objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, "NSIndexSet summary provider", ConstString("NSMutableIndexSet"), appkit_flags);
582
583 AddStringSummary(objc_category_sp,
584 "@\"${var.month%d}/${var.day%d}/${var.year%d} ${var.hour%d}:${var.minute%d}:${var.second}\"",
585 ConstString("CFGregorianDate"),
586 appkit_flags);
587
588 AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("CFBitVectorRef"), appkit_flags);
589 AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("CFMutableBitVectorRef"), appkit_flags);
590 AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("__CFBitVector"), appkit_flags);
591 AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, "CFBitVector summary provider", ConstString("__CFMutableBitVector"), appkit_flags);
592#endif // LLDB_DISABLE_PYTHON
593}
594
595static void
596LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp)
597{
598 if (!objc_category_sp)
599 return;
600
601 TypeSummaryImpl::Flags cm_flags;
602 cm_flags.SetCascades(true)
603 .SetDontShowChildren(false)
604 .SetDontShowValue(false)
605 .SetHideItemNames(false)
606 .SetShowMembersOneLiner(false)
607 .SetSkipPointers(false)
608 .SetSkipReferences(false);
609
610#ifndef LLDB_DISABLE_PYTHON
611 AddCXXSummary(objc_category_sp, lldb_private::formatters::CMTimeSummaryProvider, "CMTime summary provider", ConstString("CMTime"), cm_flags);
612#endif // LLDB_DISABLE_PYTHON
613}
614
Enrico Granata170c3952015-09-14 22:18:32 +0000615lldb::TypeCategoryImplSP
616ObjCLanguage::GetFormatters ()
617{
618 static std::once_flag g_initialize;
619 static TypeCategoryImplSP g_category;
620
621 std::call_once(g_initialize, [this] () -> void {
622 DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
623 if (g_category)
624 {
625 LoadCoreMediaFormatters(g_category);
626 LoadObjCFormatters(g_category);
627 }
628 });
629 return g_category;
630}
631
Enrico Granatad3233c12015-09-09 01:10:46 +0000632std::vector<ConstString>
633ObjCLanguage::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
634{
635 std::vector<ConstString> result;
636
637 if (use_dynamic == lldb::eNoDynamicValues)
638 return result;
639
640 CompilerType compiler_type(valobj.GetCompilerType());
641
642 const bool check_cpp = false;
643 const bool check_objc = true;
644 bool canBeObjCDynamic = compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);
645
646 if (canBeObjCDynamic)
647 {
648 do {
649 lldb::ProcessSP process_sp = valobj.GetProcessSP();
650 if (!process_sp)
651 break;
652 ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
653 if (runtime == nullptr)
654 break;
655 ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj));
656 if (!objc_class_sp)
657 break;
658 if (ConstString name = objc_class_sp->GetClassName())
659 result.push_back(name);
660 } while (false);
661 }
662
663 return result;
664}
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000665
666std::unique_ptr<Language::TypeScavenger>
667ObjCLanguage::GetTypeScavenger ()
668{
669 class ObjCTypeScavenger : public Language::TypeScavenger
670 {
671 private:
672 class ObjCScavengerResult : public Language::TypeScavenger::Result
673 {
674 public:
675 ObjCScavengerResult (CompilerType type) :
676 Language::TypeScavenger::Result(),
677 m_compiler_type(type)
678 {
679 }
680
681 bool
682 IsValid () override
683 {
684 return m_compiler_type.IsValid();
685 }
686
687 bool
688 DumpToStream (Stream& stream,
689 bool print_help_if_available) override
690 {
691 if (IsValid())
692 {
693 m_compiler_type.DumpTypeDescription(&stream);
694 stream.EOL();
695 return true;
696 }
697 return false;
698 }
699
Eugene Zelenko8d15f332015-10-20 01:10:59 +0000700 ~ObjCScavengerResult() override = default;
701
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000702 private:
703 CompilerType m_compiler_type;
704 };
705
706 protected:
707 ObjCTypeScavenger() = default;
708
Eugene Zelenko8d15f332015-10-20 01:10:59 +0000709 ~ObjCTypeScavenger() override = default;
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000710
711 bool
712 Find_Impl (ExecutionContextScope *exe_scope,
713 const char *key,
714 ResultSet &results) override
715 {
716 bool result = false;
717
Enrico Granata72d8a722015-10-02 01:23:11 +0000718 Target* target = exe_scope->CalculateTarget().get();
719 if (target)
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000720 {
Enrico Granata72d8a722015-10-02 01:23:11 +0000721 if (auto clang_modules_decl_vendor = target->GetClangModulesDeclVendor())
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000722 {
Enrico Granata72d8a722015-10-02 01:23:11 +0000723 std::vector <clang::NamedDecl*> decls;
724 ConstString key_cs(key);
725
726 if (clang_modules_decl_vendor->FindDecls(key_cs, false, UINT32_MAX, decls) > 0 &&
727 decls.size() > 0)
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000728 {
Enrico Granata72d8a722015-10-02 01:23:11 +0000729 CompilerType module_type = ClangASTContext::GetTypeForDecl(decls.front());
730 result = true;
731 std::unique_ptr<Language::TypeScavenger::Result> result(new ObjCScavengerResult(module_type));
732 results.insert(std::move(result));
733 }
734 }
735 }
736
737 if (!result)
738 {
739 Process* process = exe_scope->CalculateProcess().get();
740 if (process)
741 {
742 const bool create_on_demand = false;
743 auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
744 if (objc_runtime)
745 {
746 auto decl_vendor = objc_runtime->GetDeclVendor();
747 if (decl_vendor)
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000748 {
Enrico Granata72d8a722015-10-02 01:23:11 +0000749 std::vector<clang::NamedDecl *> decls;
750 ConstString name(key);
751 decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
752 for (auto decl : decls)
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000753 {
Enrico Granata72d8a722015-10-02 01:23:11 +0000754 if (decl)
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000755 {
Enrico Granata72d8a722015-10-02 01:23:11 +0000756 if (CompilerType candidate = ClangASTContext::GetTypeForDecl(decl))
757 {
758 result = true;
759 std::unique_ptr<Language::TypeScavenger::Result> result(new ObjCScavengerResult(candidate));
760 results.insert(std::move(result));
761 }
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000762 }
763 }
764 }
765 }
766 }
767 }
Enrico Granata72d8a722015-10-02 01:23:11 +0000768
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000769 return result;
770 }
771
Oleksiy Vyalovaf877132015-10-01 19:08:00 +0000772 friend class lldb_private::ObjCLanguage;
Enrico Granata9b0af1b2015-10-01 18:16:18 +0000773 };
774
775 return std::unique_ptr<TypeScavenger>(new ObjCTypeScavenger());
776}
Enrico Granata675f49b2015-10-07 18:36:53 +0000777
778bool
779ObjCLanguage::GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint,
780 std::string& prefix, std::string& suffix)
781{
782 static ConstString g_CFBag("CFBag");
783 static ConstString g_CFBinaryHeap("CFBinaryHeap");
784
785 static ConstString g_NSNumberChar("NSNumber:char");
786 static ConstString g_NSNumberShort("NSNumber:short");
787 static ConstString g_NSNumberInt("NSNumber:int");
788 static ConstString g_NSNumberLong("NSNumber:long");
789 static ConstString g_NSNumberFloat("NSNumber:float");
790 static ConstString g_NSNumberDouble("NSNumber:double");
791
792 static ConstString g_NSData("NSData");
793 static ConstString g_NSArray("NSArray");
794 static ConstString g_NSString("NSString");
795 static ConstString g_NSStringStar("NSString*");
796
797 if (type_hint.IsEmpty())
798 return false;
799
800 prefix.clear();
801 suffix.clear();
802
803 if (type_hint == g_CFBag ||
804 type_hint == g_CFBinaryHeap)
805 {
806 prefix = "@";
807 return true;
808 }
809
810 if (type_hint == g_NSNumberChar)
811 {
812 prefix = "(char)";
813 return true;
814 }
815 if (type_hint == g_NSNumberShort)
816 {
817 prefix = "(short)";
818 return true;
819 }
820 if (type_hint == g_NSNumberInt)
821 {
822 prefix = "(int)";
823 return true;
824 }
825 if (type_hint == g_NSNumberLong)
826 {
827 prefix = "(long)";
828 return true;
829 }
830 if (type_hint == g_NSNumberFloat)
831 {
832 prefix = "(float)";
833 return true;
834 }
835 if (type_hint == g_NSNumberDouble)
836 {
837 prefix = "(double)";
838 return true;
839 }
840
841 if (type_hint == g_NSData ||
842 type_hint == g_NSArray)
843 {
844 prefix = "@\"";
845 suffix = "\"";
846 return true;
847 }
848
849 if (type_hint == g_NSString ||
850 type_hint == g_NSStringStar)
851 {
852 prefix = "@";
853 return true;
854 }
855
856 return false;
857}