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