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