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