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