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 bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { 271 ConstString demangled_name = mangled.GetDemangledName(); 272 if (!demangled_name) 273 return false; 274 return ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString()); 275 } 276 277 static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { 278 if (!objc_category_sp) 279 return; 280 281 TypeSummaryImpl::Flags objc_flags; 282 objc_flags.SetCascades(false) 283 .SetSkipPointers(true) 284 .SetSkipReferences(true) 285 .SetDontShowChildren(true) 286 .SetDontShowValue(true) 287 .SetShowMembersOneLiner(false) 288 .SetHideItemNames(false); 289 290 lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat( 291 objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider, "")); 292 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL"), 293 ObjC_BOOL_summary); 294 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL &"), 295 ObjC_BOOL_summary); 296 objc_category_sp->GetTypeSummariesContainer()->Add(ConstString("BOOL *"), 297 ObjC_BOOL_summary); 298 299 // we need to skip pointers here since we are special casing a SEL* when 300 // retrieving its value 301 objc_flags.SetSkipPointers(true); 302 AddCXXSummary(objc_category_sp, 303 lldb_private::formatters::ObjCSELSummaryProvider<false>, 304 "SEL summary provider", ConstString("SEL"), objc_flags); 305 AddCXXSummary( 306 objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, 307 "SEL summary provider", ConstString("struct objc_selector"), objc_flags); 308 AddCXXSummary( 309 objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, 310 "SEL summary provider", ConstString("objc_selector"), objc_flags); 311 AddCXXSummary( 312 objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, 313 "SEL summary provider", ConstString("objc_selector *"), objc_flags); 314 AddCXXSummary(objc_category_sp, 315 lldb_private::formatters::ObjCSELSummaryProvider<true>, 316 "SEL summary provider", ConstString("SEL *"), objc_flags); 317 318 AddCXXSummary(objc_category_sp, 319 lldb_private::formatters::ObjCClassSummaryProvider, 320 "Class summary provider", ConstString("Class"), objc_flags); 321 322 SyntheticChildren::Flags class_synth_flags; 323 class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences( 324 false); 325 326 AddCXXSynthetic(objc_category_sp, 327 lldb_private::formatters::ObjCClassSyntheticFrontEndCreator, 328 "Class synthetic children", ConstString("Class"), 329 class_synth_flags); 330 331 objc_flags.SetSkipPointers(false); 332 objc_flags.SetCascades(true); 333 objc_flags.SetSkipReferences(false); 334 335 AddStringSummary(objc_category_sp, "${var.__FuncPtr%A}", 336 ConstString("__block_literal_generic"), objc_flags); 337 338 AddStringSummary(objc_category_sp, "${var.years} years, ${var.months} " 339 "months, ${var.days} days, ${var.hours} " 340 "hours, ${var.minutes} minutes " 341 "${var.seconds} seconds", 342 ConstString("CFGregorianUnits"), objc_flags); 343 AddStringSummary(objc_category_sp, 344 "location=${var.location} length=${var.length}", 345 ConstString("CFRange"), objc_flags); 346 347 AddStringSummary(objc_category_sp, 348 "location=${var.location}, length=${var.length}", 349 ConstString("NSRange"), objc_flags); 350 AddStringSummary(objc_category_sp, "(${var.origin}, ${var.size}), ...", 351 ConstString("NSRectArray"), objc_flags); 352 353 AddOneLineSummary(objc_category_sp, ConstString("NSPoint"), objc_flags); 354 AddOneLineSummary(objc_category_sp, ConstString("NSSize"), objc_flags); 355 AddOneLineSummary(objc_category_sp, ConstString("NSRect"), objc_flags); 356 357 AddOneLineSummary(objc_category_sp, ConstString("CGSize"), objc_flags); 358 AddOneLineSummary(objc_category_sp, ConstString("CGPoint"), objc_flags); 359 AddOneLineSummary(objc_category_sp, ConstString("CGRect"), objc_flags); 360 361 AddStringSummary(objc_category_sp, 362 "red=${var.red} green=${var.green} blue=${var.blue}", 363 ConstString("RGBColor"), objc_flags); 364 AddStringSummary( 365 objc_category_sp, 366 "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})", 367 ConstString("Rect"), objc_flags); 368 AddStringSummary(objc_category_sp, "{(v=${var.v}, h=${var.h})}", 369 ConstString("Point"), objc_flags); 370 AddStringSummary(objc_category_sp, 371 "${var.month}/${var.day}/${var.year} ${var.hour} " 372 ":${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}", 373 ConstString("DateTimeRect *"), objc_flags); 374 AddStringSummary(objc_category_sp, "${var.ld.month}/${var.ld.day}/" 375 "${var.ld.year} ${var.ld.hour} " 376 ":${var.ld.minute} :${var.ld.second} " 377 "dayOfWeek:${var.ld.dayOfWeek}", 378 ConstString("LongDateRect"), objc_flags); 379 AddStringSummary(objc_category_sp, "(x=${var.x}, y=${var.y})", 380 ConstString("HIPoint"), objc_flags); 381 AddStringSummary(objc_category_sp, "origin=${var.origin} size=${var.size}", 382 ConstString("HIRect"), objc_flags); 383 384 TypeSummaryImpl::Flags appkit_flags; 385 appkit_flags.SetCascades(true) 386 .SetSkipPointers(false) 387 .SetSkipReferences(false) 388 .SetDontShowChildren(true) 389 .SetDontShowValue(false) 390 .SetShowMembersOneLiner(false) 391 .SetHideItemNames(false); 392 393 appkit_flags.SetDontShowChildren(false); 394 395 AddCXXSummary( 396 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, 397 "NSArray summary provider", ConstString("NSArray"), appkit_flags); 398 AddCXXSummary( 399 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, 400 "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags); 401 AddCXXSummary( 402 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, 403 "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags); 404 AddCXXSummary( 405 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, 406 "NSArray summary provider", ConstString("__NSArray0"), appkit_flags); 407 AddCXXSummary(objc_category_sp, 408 lldb_private::formatters::NSArraySummaryProvider, 409 "NSArray summary provider", 410 ConstString("__NSSingleObjectArrayI"), appkit_flags); 411 AddCXXSummary( 412 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, 413 "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags); 414 AddCXXSummary( 415 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, 416 "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags); 417 AddCXXSummary( 418 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, 419 "NSArray summary provider", ConstString("_NSCallStackArray"), appkit_flags); 420 AddCXXSummary( 421 objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, 422 "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags); 423 AddCXXSummary(objc_category_sp, 424 lldb_private::formatters::NSArraySummaryProvider, 425 "NSArray summary provider", ConstString("CFMutableArrayRef"), 426 appkit_flags); 427 428 AddCXXSummary(objc_category_sp, 429 lldb_private::formatters::NSDictionarySummaryProvider<false>, 430 "NSDictionary summary provider", ConstString("NSDictionary"), 431 appkit_flags); 432 AddCXXSummary(objc_category_sp, 433 lldb_private::formatters::NSDictionarySummaryProvider<false>, 434 "NSDictionary summary provider", 435 ConstString("NSMutableDictionary"), appkit_flags); 436 AddCXXSummary(objc_category_sp, 437 lldb_private::formatters::NSDictionarySummaryProvider<false>, 438 "NSDictionary summary provider", 439 ConstString("__NSCFDictionary"), appkit_flags); 440 AddCXXSummary(objc_category_sp, 441 lldb_private::formatters::NSDictionarySummaryProvider<false>, 442 "NSDictionary summary provider", ConstString("__NSDictionaryI"), 443 appkit_flags); 444 AddCXXSummary(objc_category_sp, 445 lldb_private::formatters::NSDictionarySummaryProvider<false>, 446 "NSDictionary summary provider", 447 ConstString("__NSSingleEntryDictionaryI"), appkit_flags); 448 AddCXXSummary(objc_category_sp, 449 lldb_private::formatters::NSDictionarySummaryProvider<false>, 450 "NSDictionary summary provider", ConstString("__NSDictionaryM"), 451 appkit_flags); 452 AddCXXSummary(objc_category_sp, 453 lldb_private::formatters::NSDictionarySummaryProvider<true>, 454 "NSDictionary summary provider", ConstString("CFDictionaryRef"), 455 appkit_flags); 456 AddCXXSummary(objc_category_sp, 457 lldb_private::formatters::NSDictionarySummaryProvider<true>, 458 "NSDictionary summary provider", ConstString("__CFDictionary"), 459 appkit_flags); 460 AddCXXSummary(objc_category_sp, 461 lldb_private::formatters::NSDictionarySummaryProvider<true>, 462 "NSDictionary summary provider", 463 ConstString("CFMutableDictionaryRef"), appkit_flags); 464 465 AddCXXSummary(objc_category_sp, 466 lldb_private::formatters::NSSetSummaryProvider<false>, 467 "NSSet summary", ConstString("NSSet"), appkit_flags); 468 AddCXXSummary( 469 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, 470 "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags); 471 AddCXXSummary(objc_category_sp, 472 lldb_private::formatters::NSSetSummaryProvider<true>, 473 "CFSetRef summary", ConstString("CFSetRef"), appkit_flags); 474 AddCXXSummary( 475 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, 476 "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags); 477 AddCXXSummary(objc_category_sp, 478 lldb_private::formatters::NSSetSummaryProvider<false>, 479 "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags); 480 AddCXXSummary(objc_category_sp, 481 lldb_private::formatters::NSSetSummaryProvider<false>, 482 "__CFSet summary", ConstString("__CFSet"), appkit_flags); 483 AddCXXSummary(objc_category_sp, 484 lldb_private::formatters::NSSetSummaryProvider<false>, 485 "__NSSetI summary", ConstString("__NSSetI"), appkit_flags); 486 AddCXXSummary(objc_category_sp, 487 lldb_private::formatters::NSSetSummaryProvider<false>, 488 "__NSSetM summary", ConstString("__NSSetM"), appkit_flags); 489 AddCXXSummary( 490 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, 491 "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags); 492 AddCXXSummary( 493 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, 494 "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags); 495 AddCXXSummary( 496 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, 497 "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags); 498 AddCXXSummary( 499 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, 500 "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags); 501 AddCXXSummary( 502 objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, 503 "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags); 504 505 AddCXXSummary( 506 objc_category_sp, lldb_private::formatters::NSError_SummaryProvider, 507 "NSError summary provider", ConstString("NSError"), appkit_flags); 508 AddCXXSummary( 509 objc_category_sp, lldb_private::formatters::NSException_SummaryProvider, 510 "NSException summary provider", ConstString("NSException"), appkit_flags); 511 512 // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", 513 // ConstString("$_lldb_typegen_nspair"), appkit_flags); 514 515 appkit_flags.SetDontShowChildren(true); 516 517 AddCXXSynthetic(objc_category_sp, 518 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 519 "NSArray synthetic children", ConstString("__NSArrayM"), 520 ScriptedSyntheticChildren::Flags()); 521 AddCXXSynthetic(objc_category_sp, 522 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 523 "NSArray synthetic children", ConstString("__NSArrayI"), 524 ScriptedSyntheticChildren::Flags()); 525 AddCXXSynthetic(objc_category_sp, 526 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 527 "NSArray synthetic children", ConstString("__NSArray0"), 528 ScriptedSyntheticChildren::Flags()); 529 AddCXXSynthetic(objc_category_sp, 530 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 531 "NSArray synthetic children", 532 ConstString("__NSSingleObjectArrayI"), 533 ScriptedSyntheticChildren::Flags()); 534 AddCXXSynthetic(objc_category_sp, 535 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 536 "NSArray synthetic children", ConstString("NSArray"), 537 ScriptedSyntheticChildren::Flags()); 538 AddCXXSynthetic(objc_category_sp, 539 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 540 "NSArray synthetic children", ConstString("NSMutableArray"), 541 ScriptedSyntheticChildren::Flags()); 542 AddCXXSynthetic(objc_category_sp, 543 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 544 "NSArray synthetic children", ConstString("__NSCFArray"), 545 ScriptedSyntheticChildren::Flags()); 546 AddCXXSynthetic(objc_category_sp, 547 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 548 "NSArray synthetic children", ConstString("_NSCallStackArray"), 549 ScriptedSyntheticChildren::Flags()); 550 AddCXXSynthetic(objc_category_sp, 551 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 552 "NSArray synthetic children", 553 ConstString("CFMutableArrayRef"), 554 ScriptedSyntheticChildren::Flags()); 555 AddCXXSynthetic(objc_category_sp, 556 lldb_private::formatters::NSArraySyntheticFrontEndCreator, 557 "NSArray synthetic children", ConstString("CFArrayRef"), 558 ScriptedSyntheticChildren::Flags()); 559 560 AddCXXSynthetic( 561 objc_category_sp, 562 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 563 "NSDictionary synthetic children", ConstString("__NSDictionaryM"), 564 ScriptedSyntheticChildren::Flags()); 565 AddCXXSynthetic( 566 objc_category_sp, 567 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 568 "NSDictionary synthetic children", ConstString("__NSDictionaryI"), 569 ScriptedSyntheticChildren::Flags()); 570 AddCXXSynthetic( 571 objc_category_sp, 572 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 573 "NSDictionary synthetic children", 574 ConstString("__NSSingleEntryDictionaryI"), 575 ScriptedSyntheticChildren::Flags()); 576 AddCXXSynthetic( 577 objc_category_sp, 578 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 579 "NSDictionary synthetic children", ConstString("__NSCFDictionary"), 580 ScriptedSyntheticChildren::Flags()); 581 AddCXXSynthetic( 582 objc_category_sp, 583 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 584 "NSDictionary synthetic children", ConstString("NSDictionary"), 585 ScriptedSyntheticChildren::Flags()); 586 AddCXXSynthetic( 587 objc_category_sp, 588 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 589 "NSDictionary synthetic children", ConstString("NSMutableDictionary"), 590 ScriptedSyntheticChildren::Flags()); 591 AddCXXSynthetic( 592 objc_category_sp, 593 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 594 "NSDictionary synthetic children", ConstString("CFDictionaryRef"), 595 ScriptedSyntheticChildren::Flags()); 596 AddCXXSynthetic( 597 objc_category_sp, 598 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 599 "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), 600 ScriptedSyntheticChildren::Flags()); 601 AddCXXSynthetic( 602 objc_category_sp, 603 lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, 604 "NSDictionary synthetic children", ConstString("__CFDictionary"), 605 ScriptedSyntheticChildren::Flags()); 606 607 AddCXXSynthetic(objc_category_sp, 608 lldb_private::formatters::NSErrorSyntheticFrontEndCreator, 609 "NSError synthetic children", ConstString("NSError"), 610 ScriptedSyntheticChildren::Flags()); 611 AddCXXSynthetic(objc_category_sp, 612 lldb_private::formatters::NSExceptionSyntheticFrontEndCreator, 613 "NSException synthetic children", ConstString("NSException"), 614 ScriptedSyntheticChildren::Flags()); 615 616 AddCXXSynthetic(objc_category_sp, 617 lldb_private::formatters::NSSetSyntheticFrontEndCreator, 618 "NSSet synthetic children", ConstString("NSSet"), 619 ScriptedSyntheticChildren::Flags()); 620 AddCXXSynthetic(objc_category_sp, 621 lldb_private::formatters::NSSetSyntheticFrontEndCreator, 622 "__NSSetI synthetic children", ConstString("__NSSetI"), 623 ScriptedSyntheticChildren::Flags()); 624 AddCXXSynthetic(objc_category_sp, 625 lldb_private::formatters::NSSetSyntheticFrontEndCreator, 626 "__NSSetM synthetic children", ConstString("__NSSetM"), 627 ScriptedSyntheticChildren::Flags()); 628 AddCXXSynthetic(objc_category_sp, 629 lldb_private::formatters::NSSetSyntheticFrontEndCreator, 630 "__NSCFSet synthetic children", ConstString("__NSCFSet"), 631 ScriptedSyntheticChildren::Flags()); 632 AddCXXSynthetic(objc_category_sp, 633 lldb_private::formatters::NSSetSyntheticFrontEndCreator, 634 "CFSetRef synthetic children", ConstString("CFSetRef"), 635 ScriptedSyntheticChildren::Flags()); 636 637 AddCXXSynthetic( 638 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, 639 "NSMutableSet synthetic children", ConstString("NSMutableSet"), 640 ScriptedSyntheticChildren::Flags()); 641 AddCXXSynthetic( 642 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, 643 "NSOrderedSet synthetic children", ConstString("NSOrderedSet"), 644 ScriptedSyntheticChildren::Flags()); 645 AddCXXSynthetic( 646 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, 647 "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"), 648 ScriptedSyntheticChildren::Flags()); 649 AddCXXSynthetic( 650 objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, 651 "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), 652 ScriptedSyntheticChildren::Flags()); 653 AddCXXSynthetic(objc_category_sp, 654 lldb_private::formatters::NSSetSyntheticFrontEndCreator, 655 "__CFSet synthetic children", ConstString("__CFSet"), 656 ScriptedSyntheticChildren::Flags()); 657 658 AddCXXSynthetic(objc_category_sp, 659 lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, 660 "NSIndexPath synthetic children", ConstString("NSIndexPath"), 661 ScriptedSyntheticChildren::Flags()); 662 663 AddCXXSummary( 664 objc_category_sp, lldb_private::formatters::CFBagSummaryProvider, 665 "CFBag summary provider", ConstString("CFBagRef"), appkit_flags); 666 AddCXXSummary(objc_category_sp, 667 lldb_private::formatters::CFBagSummaryProvider, 668 "CFBag summary provider", ConstString("__CFBag"), appkit_flags); 669 AddCXXSummary(objc_category_sp, 670 lldb_private::formatters::CFBagSummaryProvider, 671 "CFBag summary provider", ConstString("const struct __CFBag"), 672 appkit_flags); 673 AddCXXSummary( 674 objc_category_sp, lldb_private::formatters::CFBagSummaryProvider, 675 "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags); 676 677 AddCXXSummary(objc_category_sp, 678 lldb_private::formatters::CFBinaryHeapSummaryProvider, 679 "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"), 680 appkit_flags); 681 AddCXXSummary(objc_category_sp, 682 lldb_private::formatters::CFBinaryHeapSummaryProvider, 683 "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"), 684 appkit_flags); 685 686 AddCXXSummary( 687 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, 688 "NSString summary provider", ConstString("NSString"), appkit_flags); 689 AddCXXSummary( 690 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, 691 "NSString summary provider", ConstString("CFStringRef"), appkit_flags); 692 AddCXXSummary( 693 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, 694 "NSString summary provider", ConstString("__CFString"), appkit_flags); 695 AddCXXSummary(objc_category_sp, 696 lldb_private::formatters::NSStringSummaryProvider, 697 "NSString summary provider", ConstString("CFMutableStringRef"), 698 appkit_flags); 699 AddCXXSummary(objc_category_sp, 700 lldb_private::formatters::NSStringSummaryProvider, 701 "NSString summary provider", ConstString("NSMutableString"), 702 appkit_flags); 703 AddCXXSummary(objc_category_sp, 704 lldb_private::formatters::NSStringSummaryProvider, 705 "NSString summary provider", 706 ConstString("__NSCFConstantString"), appkit_flags); 707 AddCXXSummary( 708 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, 709 "NSString summary provider", ConstString("__NSCFString"), appkit_flags); 710 AddCXXSummary(objc_category_sp, 711 lldb_private::formatters::NSStringSummaryProvider, 712 "NSString summary provider", ConstString("NSCFConstantString"), 713 appkit_flags); 714 AddCXXSummary( 715 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, 716 "NSString summary provider", ConstString("NSCFString"), appkit_flags); 717 AddCXXSummary( 718 objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, 719 "NSString summary provider", ConstString("NSPathStore2"), appkit_flags); 720 AddCXXSummary(objc_category_sp, 721 lldb_private::formatters::NSStringSummaryProvider, 722 "NSString summary provider", 723 ConstString("NSTaggedPointerString"), appkit_flags); 724 725 AddCXXSummary(objc_category_sp, 726 lldb_private::formatters::NSAttributedStringSummaryProvider, 727 "NSAttributedString summary provider", 728 ConstString("NSAttributedString"), appkit_flags); 729 AddCXXSummary( 730 objc_category_sp, 731 lldb_private::formatters::NSMutableAttributedStringSummaryProvider, 732 "NSMutableAttributedString summary provider", 733 ConstString("NSMutableAttributedString"), appkit_flags); 734 AddCXXSummary( 735 objc_category_sp, 736 lldb_private::formatters::NSMutableAttributedStringSummaryProvider, 737 "NSMutableAttributedString summary provider", 738 ConstString("NSConcreteMutableAttributedString"), appkit_flags); 739 740 AddCXXSummary( 741 objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider, 742 "NSBundle summary provider", ConstString("NSBundle"), appkit_flags); 743 744 AddCXXSummary(objc_category_sp, 745 lldb_private::formatters::NSDataSummaryProvider<false>, 746 "NSData summary provider", ConstString("NSData"), appkit_flags); 747 AddCXXSummary( 748 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, 749 "NSData summary provider", ConstString("_NSInlineData"), appkit_flags); 750 AddCXXSummary( 751 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, 752 "NSData summary provider", ConstString("NSConcreteData"), appkit_flags); 753 AddCXXSummary(objc_category_sp, 754 lldb_private::formatters::NSDataSummaryProvider<false>, 755 "NSData summary provider", ConstString("NSConcreteMutableData"), 756 appkit_flags); 757 AddCXXSummary( 758 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, 759 "NSData summary provider", ConstString("NSMutableData"), appkit_flags); 760 AddCXXSummary( 761 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, 762 "NSData summary provider", ConstString("__NSCFData"), appkit_flags); 763 AddCXXSummary( 764 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, 765 "NSData summary provider", ConstString("CFDataRef"), appkit_flags); 766 AddCXXSummary( 767 objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, 768 "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags); 769 770 AddCXXSummary( 771 objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider, 772 "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags); 773 774 AddCXXSummary(objc_category_sp, 775 lldb_private::formatters::NSNotificationSummaryProvider, 776 "NSNotification summary provider", 777 ConstString("NSNotification"), appkit_flags); 778 AddCXXSummary(objc_category_sp, 779 lldb_private::formatters::NSNotificationSummaryProvider, 780 "NSNotification summary provider", 781 ConstString("NSConcreteNotification"), appkit_flags); 782 783 AddCXXSummary( 784 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, 785 "NSNumber summary provider", ConstString("NSNumber"), appkit_flags); 786 AddCXXSummary( 787 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, 788 "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags); 789 AddCXXSummary( 790 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, 791 "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags); 792 AddCXXSummary( 793 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, 794 "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags); 795 AddCXXSummary( 796 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, 797 "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags); 798 AddCXXSummary( 799 objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, 800 "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags); 801 AddCXXSummary(objc_category_sp, 802 lldb_private::formatters::NSNumberSummaryProvider, 803 "NSDecimalNumber summary provider", 804 ConstString("NSDecimalNumber"), appkit_flags); 805 806 AddCXXSummary(objc_category_sp, 807 lldb_private::formatters::NSURLSummaryProvider, 808 "NSURL summary provider", ConstString("NSURL"), appkit_flags); 809 AddCXXSummary( 810 objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, 811 "NSURL summary provider", ConstString("CFURLRef"), appkit_flags); 812 813 AddCXXSummary(objc_category_sp, 814 lldb_private::formatters::NSDateSummaryProvider, 815 "NSDate summary provider", ConstString("NSDate"), appkit_flags); 816 AddCXXSummary( 817 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, 818 "NSDate summary provider", ConstString("__NSDate"), appkit_flags); 819 AddCXXSummary( 820 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, 821 "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags); 822 AddCXXSummary( 823 objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, 824 "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags); 825 826 AddCXXSummary( 827 objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, 828 "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags); 829 AddCXXSummary(objc_category_sp, 830 lldb_private::formatters::NSTimeZoneSummaryProvider, 831 "NSTimeZone summary provider", ConstString("CFTimeZoneRef"), 832 appkit_flags); 833 AddCXXSummary( 834 objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, 835 "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags); 836 837 // CFAbsoluteTime is actually a double rather than a pointer to an object we 838 // do not care about the numeric value, since it is probably meaningless to 839 // users 840 appkit_flags.SetDontShowValue(true); 841 AddCXXSummary(objc_category_sp, 842 lldb_private::formatters::CFAbsoluteTimeSummaryProvider, 843 "CFAbsoluteTime summary provider", 844 ConstString("CFAbsoluteTime"), appkit_flags); 845 appkit_flags.SetDontShowValue(false); 846 847 AddCXXSummary( 848 objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, 849 "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags); 850 AddCXXSummary(objc_category_sp, 851 lldb_private::formatters::NSIndexSetSummaryProvider, 852 "NSIndexSet summary provider", ConstString("NSMutableIndexSet"), 853 appkit_flags); 854 855 AddStringSummary(objc_category_sp, 856 "@\"${var.month%d}/${var.day%d}/${var.year%d} " 857 "${var.hour%d}:${var.minute%d}:${var.second}\"", 858 ConstString("CFGregorianDate"), appkit_flags); 859 860 AddCXXSummary(objc_category_sp, 861 lldb_private::formatters::CFBitVectorSummaryProvider, 862 "CFBitVector summary provider", ConstString("CFBitVectorRef"), 863 appkit_flags); 864 AddCXXSummary(objc_category_sp, 865 lldb_private::formatters::CFBitVectorSummaryProvider, 866 "CFBitVector summary provider", 867 ConstString("CFMutableBitVectorRef"), appkit_flags); 868 AddCXXSummary(objc_category_sp, 869 lldb_private::formatters::CFBitVectorSummaryProvider, 870 "CFBitVector summary provider", ConstString("__CFBitVector"), 871 appkit_flags); 872 AddCXXSummary(objc_category_sp, 873 lldb_private::formatters::CFBitVectorSummaryProvider, 874 "CFBitVector summary provider", 875 ConstString("__CFMutableBitVector"), appkit_flags); 876 } 877 878 static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) { 879 if (!objc_category_sp) 880 return; 881 882 TypeSummaryImpl::Flags cm_flags; 883 cm_flags.SetCascades(true) 884 .SetDontShowChildren(false) 885 .SetDontShowValue(false) 886 .SetHideItemNames(false) 887 .SetShowMembersOneLiner(false) 888 .SetSkipPointers(false) 889 .SetSkipReferences(false); 890 891 AddCXXSummary(objc_category_sp, 892 lldb_private::formatters::CMTimeSummaryProvider, 893 "CMTime summary provider", ConstString("CMTime"), cm_flags); 894 } 895 896 lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() { 897 static llvm::once_flag g_initialize; 898 static TypeCategoryImplSP g_category; 899 900 llvm::call_once(g_initialize, [this]() -> void { 901 DataVisualization::Categories::GetCategory(GetPluginName(), g_category); 902 if (g_category) { 903 LoadCoreMediaFormatters(g_category); 904 LoadObjCFormatters(g_category); 905 } 906 }); 907 return g_category; 908 } 909 910 std::vector<ConstString> 911 ObjCLanguage::GetPossibleFormattersMatches(ValueObject &valobj, 912 lldb::DynamicValueType use_dynamic) { 913 std::vector<ConstString> result; 914 915 if (use_dynamic == lldb::eNoDynamicValues) 916 return result; 917 918 CompilerType compiler_type(valobj.GetCompilerType()); 919 920 const bool check_cpp = false; 921 const bool check_objc = true; 922 bool canBeObjCDynamic = 923 compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc); 924 925 if (canBeObjCDynamic && ClangUtil::IsClangType(compiler_type)) { 926 do { 927 lldb::ProcessSP process_sp = valobj.GetProcessSP(); 928 if (!process_sp) 929 break; 930 ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp); 931 if (runtime == nullptr) 932 break; 933 ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp( 934 runtime->GetClassDescriptor(valobj)); 935 if (!objc_class_sp) 936 break; 937 if (ConstString name = objc_class_sp->GetClassName()) 938 result.push_back(name); 939 } while (false); 940 } 941 942 return result; 943 } 944 945 std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() { 946 class ObjCScavengerResult : public Language::TypeScavenger::Result { 947 public: 948 ObjCScavengerResult(CompilerType type) 949 : Language::TypeScavenger::Result(), m_compiler_type(type) {} 950 951 bool IsValid() override { return m_compiler_type.IsValid(); } 952 953 bool DumpToStream(Stream &stream, bool print_help_if_available) override { 954 if (IsValid()) { 955 m_compiler_type.DumpTypeDescription(&stream); 956 stream.EOL(); 957 return true; 958 } 959 return false; 960 } 961 962 private: 963 CompilerType m_compiler_type; 964 }; 965 966 class ObjCRuntimeScavenger : public Language::TypeScavenger { 967 protected: 968 bool Find_Impl(ExecutionContextScope *exe_scope, const char *key, 969 ResultSet &results) override { 970 bool result = false; 971 972 if (auto *process = exe_scope->CalculateProcess().get()) { 973 if (auto *objc_runtime = ObjCLanguageRuntime::Get(*process)) { 974 if (auto *decl_vendor = objc_runtime->GetDeclVendor()) { 975 ConstString name(key); 976 for (const CompilerType &type : 977 decl_vendor->FindTypes(name, /*max_matches*/ UINT32_MAX)) { 978 result = true; 979 std::unique_ptr<Language::TypeScavenger::Result> result( 980 new ObjCScavengerResult(type)); 981 results.insert(std::move(result)); 982 } 983 } 984 } 985 } 986 987 return result; 988 } 989 990 friend class lldb_private::ObjCLanguage; 991 }; 992 993 class ObjCModulesScavenger : public Language::TypeScavenger { 994 protected: 995 bool Find_Impl(ExecutionContextScope *exe_scope, const char *key, 996 ResultSet &results) override { 997 bool result = false; 998 999 if (auto *target = exe_scope->CalculateTarget().get()) { 1000 auto *persistent_vars = llvm::cast<ClangPersistentVariables>( 1001 target->GetPersistentExpressionStateForLanguage( 1002 lldb::eLanguageTypeC)); 1003 if (std::shared_ptr<ClangModulesDeclVendor> clang_modules_decl_vendor = 1004 persistent_vars->GetClangModulesDeclVendor()) { 1005 ConstString key_cs(key); 1006 auto types = clang_modules_decl_vendor->FindTypes( 1007 key_cs, /*max_matches*/ UINT32_MAX); 1008 if (!types.empty()) { 1009 result = true; 1010 std::unique_ptr<Language::TypeScavenger::Result> result( 1011 new ObjCScavengerResult(types.front())); 1012 results.insert(std::move(result)); 1013 } 1014 } 1015 } 1016 1017 return result; 1018 } 1019 1020 friend class lldb_private::ObjCLanguage; 1021 }; 1022 1023 class ObjCDebugInfoScavenger : public Language::ImageListTypeScavenger { 1024 public: 1025 CompilerType AdjustForInclusion(CompilerType &candidate) override { 1026 LanguageType lang_type(candidate.GetMinimumLanguage()); 1027 if (!Language::LanguageIsObjC(lang_type)) 1028 return CompilerType(); 1029 if (candidate.IsTypedefType()) 1030 return candidate.GetTypedefedType(); 1031 return candidate; 1032 } 1033 }; 1034 1035 return std::unique_ptr<TypeScavenger>( 1036 new Language::EitherTypeScavenger<ObjCModulesScavenger, 1037 ObjCRuntimeScavenger, 1038 ObjCDebugInfoScavenger>()); 1039 } 1040 1041 bool ObjCLanguage::GetFormatterPrefixSuffix(ValueObject &valobj, 1042 ConstString type_hint, 1043 std::string &prefix, 1044 std::string &suffix) { 1045 static ConstString g_CFBag("CFBag"); 1046 static ConstString g_CFBinaryHeap("CFBinaryHeap"); 1047 1048 static ConstString g_NSNumberChar("NSNumber:char"); 1049 static ConstString g_NSNumberShort("NSNumber:short"); 1050 static ConstString g_NSNumberInt("NSNumber:int"); 1051 static ConstString g_NSNumberLong("NSNumber:long"); 1052 static ConstString g_NSNumberInt128("NSNumber:int128_t"); 1053 static ConstString g_NSNumberFloat("NSNumber:float"); 1054 static ConstString g_NSNumberDouble("NSNumber:double"); 1055 1056 static ConstString g_NSData("NSData"); 1057 static ConstString g_NSArray("NSArray"); 1058 static ConstString g_NSString("NSString"); 1059 static ConstString g_NSStringStar("NSString*"); 1060 1061 if (type_hint.IsEmpty()) 1062 return false; 1063 1064 prefix.clear(); 1065 suffix.clear(); 1066 1067 if (type_hint == g_CFBag || type_hint == g_CFBinaryHeap) { 1068 prefix = "@"; 1069 return true; 1070 } 1071 1072 if (type_hint == g_NSNumberChar) { 1073 prefix = "(char)"; 1074 return true; 1075 } 1076 if (type_hint == g_NSNumberShort) { 1077 prefix = "(short)"; 1078 return true; 1079 } 1080 if (type_hint == g_NSNumberInt) { 1081 prefix = "(int)"; 1082 return true; 1083 } 1084 if (type_hint == g_NSNumberLong) { 1085 prefix = "(long)"; 1086 return true; 1087 } 1088 if (type_hint == g_NSNumberInt128) { 1089 prefix = "(int128_t)"; 1090 return true; 1091 } 1092 if (type_hint == g_NSNumberFloat) { 1093 prefix = "(float)"; 1094 return true; 1095 } 1096 if (type_hint == g_NSNumberDouble) { 1097 prefix = "(double)"; 1098 return true; 1099 } 1100 1101 if (type_hint == g_NSData || type_hint == g_NSArray) { 1102 prefix = "@\""; 1103 suffix = "\""; 1104 return true; 1105 } 1106 1107 if (type_hint == g_NSString || type_hint == g_NSStringStar) { 1108 prefix = "@"; 1109 return true; 1110 } 1111 1112 return false; 1113 } 1114 1115 bool ObjCLanguage::IsNilReference(ValueObject &valobj) { 1116 const uint32_t mask = eTypeIsObjC | eTypeIsPointer; 1117 bool isObjCpointer = 1118 (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask); 1119 if (!isObjCpointer) 1120 return false; 1121 bool canReadValue = true; 1122 bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0; 1123 return canReadValue && isZero; 1124 } 1125 1126 bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const { 1127 const auto suffixes = {".h", ".m", ".M"}; 1128 for (auto suffix : suffixes) { 1129 if (file_path.endswith_lower(suffix)) 1130 return true; 1131 } 1132 return false; 1133 } 1134