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