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