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