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