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