Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
39644 views
//===-- ObjCLanguage.cpp --------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <mutex>910#include "ObjCLanguage.h"1112#include "Plugins/ExpressionParser/Clang/ClangUtil.h"13#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"14#include "lldb/Core/Debugger.h"15#include "lldb/Core/PluginManager.h"16#include "lldb/Core/ValueObject.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"2324#include "llvm/Support/Threading.h"2526#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"27#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"2829#include "CF.h"30#include "Cocoa.h"31#include "CoreMedia.h"32#include "NSDictionary.h"33#include "NSSet.h"34#include "NSString.h"3536using namespace lldb;37using namespace lldb_private;38using namespace lldb_private::formatters;3940LLDB_PLUGIN_DEFINE(ObjCLanguage)4142void ObjCLanguage::Initialize() {43PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language",44CreateInstance);45}4647void ObjCLanguage::Terminate() {48PluginManager::UnregisterPlugin(CreateInstance);49}5051// Static Functions5253Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) {54switch (language) {55case lldb::eLanguageTypeObjC:56return new ObjCLanguage();57default:58return nullptr;59}60}6162std::optional<const ObjCLanguage::MethodName>63ObjCLanguage::MethodName::Create(llvm::StringRef name, bool strict) {64if (name.empty())65return std::nullopt;6667// Objective-C method minimum requirements:68// - If `strict` is true, must start with '-' or '+' (1 char)69// - Must be followed by '[' (1 char)70// - Must have at least one character for class name (1 char)71// - Must have a space between class name and method name (1 char)72// - Must have at least one character for method name (1 char)73// - Must be end with ']' (1 char)74// This means that the minimum size is 5 characters (6 if `strict`)75// e.g. [a a] (-[a a] or +[a a] if `strict`)7677// We can check length and ending invariants first78if (name.size() < (5 + (strict ? 1 : 0)) || name.back() != ']')79return std::nullopt;8081// Figure out type82Type type = eTypeUnspecified;83if (name.starts_with("+["))84type = eTypeClassMethod;85else if (name.starts_with("-["))86type = eTypeInstanceMethod;8788// If there's no type and it's strict, this is invalid89if (strict && type == eTypeUnspecified)90return std::nullopt;9192// If not strict and type unspecified, make sure we start with '['93if (type == eTypeUnspecified && name.front() != '[')94return std::nullopt;9596// If we've gotten here, we're confident that this looks enough like an97// Objective-C method to treat it like one.98ObjCLanguage::MethodName method_name(name, type);99return method_name;100}101102llvm::StringRef ObjCLanguage::MethodName::GetClassName() const {103llvm::StringRef full = m_full;104const size_t class_start_pos = (full.front() == '[' ? 1 : 2);105const size_t paren_pos = full.find('(', class_start_pos);106// If there's a category we want to stop there107if (paren_pos != llvm::StringRef::npos)108return full.substr(class_start_pos, paren_pos - class_start_pos);109110// Otherwise we find the space separating the class and method111const size_t space_pos = full.find(' ', class_start_pos);112return full.substr(class_start_pos, space_pos - class_start_pos);113}114115llvm::StringRef ObjCLanguage::MethodName::GetClassNameWithCategory() const {116llvm::StringRef full = m_full;117const size_t class_start_pos = (full.front() == '[' ? 1 : 2);118const size_t space_pos = full.find(' ', class_start_pos);119return full.substr(class_start_pos, space_pos - class_start_pos);120}121122llvm::StringRef ObjCLanguage::MethodName::GetSelector() const {123llvm::StringRef full = m_full;124const size_t space_pos = full.find(' ');125if (space_pos == llvm::StringRef::npos)126return llvm::StringRef();127const size_t closing_bracket = full.find(']', space_pos);128return full.substr(space_pos + 1, closing_bracket - space_pos - 1);129}130131llvm::StringRef ObjCLanguage::MethodName::GetCategory() const {132llvm::StringRef full = m_full;133const size_t open_paren_pos = full.find('(');134const size_t close_paren_pos = full.find(')');135136if (open_paren_pos == llvm::StringRef::npos ||137close_paren_pos == llvm::StringRef::npos)138return llvm::StringRef();139140return full.substr(open_paren_pos + 1,141close_paren_pos - (open_paren_pos + 1));142}143144std::string ObjCLanguage::MethodName::GetFullNameWithoutCategory() const {145llvm::StringRef full = m_full;146const size_t open_paren_pos = full.find('(');147const size_t close_paren_pos = full.find(')');148if (open_paren_pos == llvm::StringRef::npos ||149close_paren_pos == llvm::StringRef::npos)150return std::string();151152llvm::StringRef class_name = GetClassName();153llvm::StringRef selector_name = GetSelector();154155// Compute the total size to avoid reallocations156// class name + selector name + '[' + ' ' + ']'157size_t total_size = class_name.size() + selector_name.size() + 3;158if (m_type != eTypeUnspecified)159total_size++; // For + or -160161std::string name_sans_category;162name_sans_category.reserve(total_size);163164if (m_type == eTypeClassMethod)165name_sans_category += '+';166else if (m_type == eTypeInstanceMethod)167name_sans_category += '-';168169name_sans_category += '[';170name_sans_category.append(class_name.data(), class_name.size());171name_sans_category += ' ';172name_sans_category.append(selector_name.data(), selector_name.size());173name_sans_category += ']';174175return name_sans_category;176}177178std::vector<Language::MethodNameVariant>179ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {180std::vector<Language::MethodNameVariant> variant_names;181std::optional<const ObjCLanguage::MethodName> objc_method =182ObjCLanguage::MethodName::Create(method_name.GetStringRef(), false);183if (!objc_method)184return variant_names;185186variant_names.emplace_back(ConstString(objc_method->GetSelector()),187lldb::eFunctionNameTypeSelector);188189const std::string name_sans_category =190objc_method->GetFullNameWithoutCategory();191192if (objc_method->IsClassMethod() || objc_method->IsInstanceMethod()) {193if (!name_sans_category.empty())194variant_names.emplace_back(ConstString(name_sans_category.c_str()),195lldb::eFunctionNameTypeFull);196} else {197StreamString strm;198199strm.Printf("+%s", objc_method->GetFullName().c_str());200variant_names.emplace_back(ConstString(strm.GetString()),201lldb::eFunctionNameTypeFull);202strm.Clear();203204strm.Printf("-%s", objc_method->GetFullName().c_str());205variant_names.emplace_back(ConstString(strm.GetString()),206lldb::eFunctionNameTypeFull);207strm.Clear();208209if (!name_sans_category.empty()) {210strm.Printf("+%s", name_sans_category.c_str());211variant_names.emplace_back(ConstString(strm.GetString()),212lldb::eFunctionNameTypeFull);213strm.Clear();214215strm.Printf("-%s", name_sans_category.c_str());216variant_names.emplace_back(ConstString(strm.GetString()),217lldb::eFunctionNameTypeFull);218}219}220221return variant_names;222}223224bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {225ConstString demangled_name = mangled.GetDemangledName();226if (!demangled_name)227return false;228return ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString());229}230231static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {232if (!objc_category_sp)233return;234235TypeSummaryImpl::Flags objc_flags;236objc_flags.SetCascades(false)237.SetSkipPointers(true)238.SetSkipReferences(true)239.SetDontShowChildren(true)240.SetDontShowValue(true)241.SetShowMembersOneLiner(false)242.SetHideItemNames(false);243244lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(245objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider, ""));246objc_category_sp->AddTypeSummary("BOOL", eFormatterMatchExact,247ObjC_BOOL_summary);248objc_category_sp->AddTypeSummary("BOOL &", eFormatterMatchExact,249ObjC_BOOL_summary);250objc_category_sp->AddTypeSummary("BOOL *", eFormatterMatchExact,251ObjC_BOOL_summary);252253// we need to skip pointers here since we are special casing a SEL* when254// retrieving its value255objc_flags.SetSkipPointers(true);256AddCXXSummary(objc_category_sp,257lldb_private::formatters::ObjCSELSummaryProvider<false>,258"SEL summary provider", "SEL", objc_flags);259AddCXXSummary(objc_category_sp,260lldb_private::formatters::ObjCSELSummaryProvider<false>,261"SEL summary provider", "struct objc_selector", objc_flags);262AddCXXSummary(objc_category_sp,263lldb_private::formatters::ObjCSELSummaryProvider<false>,264"SEL summary provider", "objc_selector", objc_flags);265AddCXXSummary(objc_category_sp,266lldb_private::formatters::ObjCSELSummaryProvider<true>,267"SEL summary provider", "objc_selector *", objc_flags);268AddCXXSummary(objc_category_sp,269lldb_private::formatters::ObjCSELSummaryProvider<true>,270"SEL summary provider", "SEL *", objc_flags);271272AddCXXSummary(objc_category_sp,273lldb_private::formatters::ObjCClassSummaryProvider,274"Class summary provider", "Class", objc_flags);275276SyntheticChildren::Flags class_synth_flags;277class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(278false);279280AddCXXSynthetic(objc_category_sp,281lldb_private::formatters::ObjCClassSyntheticFrontEndCreator,282"Class synthetic children", "Class", class_synth_flags);283284objc_flags.SetSkipPointers(false);285objc_flags.SetCascades(true);286objc_flags.SetSkipReferences(false);287288AddStringSummary(objc_category_sp, "${var.__FuncPtr%A}",289"__block_literal_generic", objc_flags);290291AddStringSummary(objc_category_sp,292"${var.years} years, ${var.months} "293"months, ${var.days} days, ${var.hours} "294"hours, ${var.minutes} minutes "295"${var.seconds} seconds",296"CFGregorianUnits", objc_flags);297AddStringSummary(objc_category_sp,298"location=${var.location} length=${var.length}", "CFRange",299objc_flags);300301AddStringSummary(objc_category_sp,302"location=${var.location}, length=${var.length}", "NSRange",303objc_flags);304AddStringSummary(objc_category_sp, "(${var.origin}, ${var.size}), ...",305"NSRectArray", objc_flags);306307AddOneLineSummary(objc_category_sp, "NSPoint", objc_flags);308AddOneLineSummary(objc_category_sp, "NSSize", objc_flags);309AddOneLineSummary(objc_category_sp, "NSRect", objc_flags);310311AddOneLineSummary(objc_category_sp, "CGSize", objc_flags);312AddOneLineSummary(objc_category_sp, "CGPoint", objc_flags);313AddOneLineSummary(objc_category_sp, "CGRect", objc_flags);314315AddStringSummary(objc_category_sp,316"red=${var.red} green=${var.green} blue=${var.blue}",317"RGBColor", objc_flags);318AddStringSummary(319objc_category_sp,320"(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})", "Rect",321objc_flags);322AddStringSummary(objc_category_sp, "{(v=${var.v}, h=${var.h})}", "Point",323objc_flags);324AddStringSummary(objc_category_sp,325"${var.month}/${var.day}/${var.year} ${var.hour} "326":${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",327"DateTimeRect *", objc_flags);328AddStringSummary(objc_category_sp,329"${var.ld.month}/${var.ld.day}/"330"${var.ld.year} ${var.ld.hour} "331":${var.ld.minute} :${var.ld.second} "332"dayOfWeek:${var.ld.dayOfWeek}",333"LongDateRect", objc_flags);334AddStringSummary(objc_category_sp, "(x=${var.x}, y=${var.y})", "HIPoint",335objc_flags);336AddStringSummary(objc_category_sp, "origin=${var.origin} size=${var.size}",337"HIRect", objc_flags);338339TypeSummaryImpl::Flags appkit_flags;340appkit_flags.SetCascades(true)341.SetSkipPointers(false)342.SetSkipReferences(false)343.SetDontShowChildren(true)344.SetDontShowValue(false)345.SetShowMembersOneLiner(false)346.SetHideItemNames(false);347348appkit_flags.SetDontShowChildren(false);349350AddCXXSummary(objc_category_sp,351lldb_private::formatters::NSArraySummaryProvider,352"NSArray summary provider", "NSArray", appkit_flags);353AddCXXSummary(objc_category_sp,354lldb_private::formatters::NSArraySummaryProvider,355"NSArray summary provider", "NSConstantArray", appkit_flags);356AddCXXSummary(objc_category_sp,357lldb_private::formatters::NSArraySummaryProvider,358"NSArray summary provider", "NSMutableArray", appkit_flags);359AddCXXSummary(objc_category_sp,360lldb_private::formatters::NSArraySummaryProvider,361"NSArray summary provider", "__NSArrayI", appkit_flags);362AddCXXSummary(objc_category_sp,363lldb_private::formatters::NSArraySummaryProvider,364"NSArray summary provider", "__NSArray0", appkit_flags);365AddCXXSummary(366objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,367"NSArray summary provider", "__NSSingleObjectArrayI", appkit_flags);368AddCXXSummary(objc_category_sp,369lldb_private::formatters::NSArraySummaryProvider,370"NSArray summary provider", "__NSArrayM", appkit_flags);371AddCXXSummary(objc_category_sp,372lldb_private::formatters::NSArraySummaryProvider,373"NSArray summary provider", "__NSCFArray", appkit_flags);374AddCXXSummary(objc_category_sp,375lldb_private::formatters::NSArraySummaryProvider,376"NSArray summary provider", "_NSCallStackArray", appkit_flags);377AddCXXSummary(objc_category_sp,378lldb_private::formatters::NSArraySummaryProvider,379"NSArray summary provider", "CFArrayRef", appkit_flags);380AddCXXSummary(objc_category_sp,381lldb_private::formatters::NSArraySummaryProvider,382"NSArray summary provider", "CFMutableArrayRef", appkit_flags);383384AddCXXSummary(objc_category_sp,385lldb_private::formatters::NSDictionarySummaryProvider<false>,386"NSDictionary summary provider", "NSDictionary", appkit_flags);387AddCXXSummary(objc_category_sp,388lldb_private::formatters::NSDictionarySummaryProvider<false>,389"NSDictionary summary provider", "NSConstantDictionary",390appkit_flags);391AddCXXSummary(objc_category_sp,392lldb_private::formatters::NSDictionarySummaryProvider<false>,393"NSDictionary summary provider", "NSMutableDictionary",394appkit_flags);395AddCXXSummary(objc_category_sp,396lldb_private::formatters::NSDictionarySummaryProvider<false>,397"NSDictionary summary provider", "__NSCFDictionary",398appkit_flags);399AddCXXSummary(objc_category_sp,400lldb_private::formatters::NSDictionarySummaryProvider<false>,401"NSDictionary summary provider", "__NSDictionaryI",402appkit_flags);403AddCXXSummary(objc_category_sp,404lldb_private::formatters::NSDictionarySummaryProvider<false>,405"NSDictionary summary provider", "__NSSingleEntryDictionaryI",406appkit_flags);407AddCXXSummary(objc_category_sp,408lldb_private::formatters::NSDictionarySummaryProvider<false>,409"NSDictionary summary provider", "__NSDictionaryM",410appkit_flags);411AddCXXSummary(objc_category_sp,412lldb_private::formatters::NSDictionarySummaryProvider<true>,413"NSDictionary summary provider", "CFDictionaryRef",414appkit_flags);415AddCXXSummary(objc_category_sp,416lldb_private::formatters::NSDictionarySummaryProvider<true>,417"NSDictionary summary provider", "__CFDictionary",418appkit_flags);419AddCXXSummary(objc_category_sp,420lldb_private::formatters::NSDictionarySummaryProvider<true>,421"NSDictionary summary provider", "CFMutableDictionaryRef",422appkit_flags);423424AddCXXSummary(objc_category_sp,425lldb_private::formatters::NSSetSummaryProvider<false>,426"NSSet summary", "NSSet", appkit_flags);427AddCXXSummary(objc_category_sp,428lldb_private::formatters::NSSetSummaryProvider<false>,429"NSMutableSet summary", "NSMutableSet", appkit_flags);430AddCXXSummary(objc_category_sp,431lldb_private::formatters::NSSetSummaryProvider<true>,432"CFSetRef summary", "CFSetRef", appkit_flags);433AddCXXSummary(objc_category_sp,434lldb_private::formatters::NSSetSummaryProvider<true>,435"CFMutableSetRef summary", "CFMutableSetRef", appkit_flags);436AddCXXSummary(objc_category_sp,437lldb_private::formatters::NSSetSummaryProvider<false>,438"__NSCFSet summary", "__NSCFSet", appkit_flags);439AddCXXSummary(objc_category_sp,440lldb_private::formatters::NSSetSummaryProvider<false>,441"__CFSet summary", "__CFSet", appkit_flags);442AddCXXSummary(objc_category_sp,443lldb_private::formatters::NSSetSummaryProvider<false>,444"__NSSetI summary", "__NSSetI", appkit_flags);445AddCXXSummary(objc_category_sp,446lldb_private::formatters::NSSetSummaryProvider<false>,447"__NSSetM summary", "__NSSetM", appkit_flags);448AddCXXSummary(objc_category_sp,449lldb_private::formatters::NSSetSummaryProvider<false>,450"NSCountedSet summary", "NSCountedSet", appkit_flags);451AddCXXSummary(objc_category_sp,452lldb_private::formatters::NSSetSummaryProvider<false>,453"NSMutableSet summary", "NSMutableSet", appkit_flags);454AddCXXSummary(objc_category_sp,455lldb_private::formatters::NSSetSummaryProvider<false>,456"NSOrderedSet summary", "NSOrderedSet", appkit_flags);457AddCXXSummary(objc_category_sp,458lldb_private::formatters::NSSetSummaryProvider<false>,459"__NSOrderedSetI summary", "__NSOrderedSetI", appkit_flags);460AddCXXSummary(objc_category_sp,461lldb_private::formatters::NSSetSummaryProvider<false>,462"__NSOrderedSetM summary", "__NSOrderedSetM", appkit_flags);463464AddCXXSummary(objc_category_sp,465lldb_private::formatters::NSError_SummaryProvider,466"NSError summary provider", "NSError", appkit_flags);467AddCXXSummary(objc_category_sp,468lldb_private::formatters::NSException_SummaryProvider,469"NSException summary provider", "NSException", appkit_flags);470471// AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}",472// ConstString("$_lldb_typegen_nspair"), appkit_flags);473474appkit_flags.SetDontShowChildren(true);475476AddCXXSynthetic(objc_category_sp,477lldb_private::formatters::NSArraySyntheticFrontEndCreator,478"NSArray synthetic children", "__NSArrayM",479ScriptedSyntheticChildren::Flags());480AddCXXSynthetic(objc_category_sp,481lldb_private::formatters::NSArraySyntheticFrontEndCreator,482"NSArray synthetic children", "__NSArrayI",483ScriptedSyntheticChildren::Flags());484AddCXXSynthetic(objc_category_sp,485lldb_private::formatters::NSArraySyntheticFrontEndCreator,486"NSArray synthetic children", "__NSArray0",487ScriptedSyntheticChildren::Flags());488AddCXXSynthetic(objc_category_sp,489lldb_private::formatters::NSArraySyntheticFrontEndCreator,490"NSArray synthetic children", "__NSSingleObjectArrayI",491ScriptedSyntheticChildren::Flags());492AddCXXSynthetic(objc_category_sp,493lldb_private::formatters::NSArraySyntheticFrontEndCreator,494"NSArray synthetic children", "NSArray",495ScriptedSyntheticChildren::Flags());496AddCXXSynthetic(objc_category_sp,497lldb_private::formatters::NSArraySyntheticFrontEndCreator,498"NSArray synthetic children", "NSConstantArray",499ScriptedSyntheticChildren::Flags());500AddCXXSynthetic(objc_category_sp,501lldb_private::formatters::NSArraySyntheticFrontEndCreator,502"NSArray synthetic children", "NSMutableArray",503ScriptedSyntheticChildren::Flags());504AddCXXSynthetic(objc_category_sp,505lldb_private::formatters::NSArraySyntheticFrontEndCreator,506"NSArray synthetic children", "__NSCFArray",507ScriptedSyntheticChildren::Flags());508AddCXXSynthetic(objc_category_sp,509lldb_private::formatters::NSArraySyntheticFrontEndCreator,510"NSArray synthetic children", "_NSCallStackArray",511ScriptedSyntheticChildren::Flags());512AddCXXSynthetic(objc_category_sp,513lldb_private::formatters::NSArraySyntheticFrontEndCreator,514"NSArray synthetic children", "CFMutableArrayRef",515ScriptedSyntheticChildren::Flags());516AddCXXSynthetic(objc_category_sp,517lldb_private::formatters::NSArraySyntheticFrontEndCreator,518"NSArray synthetic children", "CFArrayRef",519ScriptedSyntheticChildren::Flags());520521AddCXXSynthetic(522objc_category_sp,523lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,524"NSDictionary synthetic children", "__NSDictionaryM",525ScriptedSyntheticChildren::Flags());526AddCXXSynthetic(527objc_category_sp,528lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,529"NSDictionary synthetic children", "NSConstantDictionary",530ScriptedSyntheticChildren::Flags());531AddCXXSynthetic(532objc_category_sp,533lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,534"NSDictionary synthetic children", "__NSDictionaryI",535ScriptedSyntheticChildren::Flags());536AddCXXSynthetic(537objc_category_sp,538lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,539"NSDictionary synthetic children", "__NSSingleEntryDictionaryI",540ScriptedSyntheticChildren::Flags());541AddCXXSynthetic(542objc_category_sp,543lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,544"NSDictionary synthetic children", "__NSCFDictionary",545ScriptedSyntheticChildren::Flags());546AddCXXSynthetic(547objc_category_sp,548lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,549"NSDictionary synthetic children", "NSDictionary",550ScriptedSyntheticChildren::Flags());551AddCXXSynthetic(552objc_category_sp,553lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,554"NSDictionary synthetic children", "NSMutableDictionary",555ScriptedSyntheticChildren::Flags());556AddCXXSynthetic(557objc_category_sp,558lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,559"NSDictionary synthetic children", "CFDictionaryRef",560ScriptedSyntheticChildren::Flags());561AddCXXSynthetic(562objc_category_sp,563lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,564"NSDictionary synthetic children", "CFMutableDictionaryRef",565ScriptedSyntheticChildren::Flags());566AddCXXSynthetic(567objc_category_sp,568lldb_private::formatters::NSDictionarySyntheticFrontEndCreator,569"NSDictionary synthetic children", "__CFDictionary",570ScriptedSyntheticChildren::Flags());571572AddCXXSynthetic(objc_category_sp,573lldb_private::formatters::NSErrorSyntheticFrontEndCreator,574"NSError synthetic children", "NSError",575ScriptedSyntheticChildren::Flags());576AddCXXSynthetic(objc_category_sp,577lldb_private::formatters::NSExceptionSyntheticFrontEndCreator,578"NSException synthetic children", "NSException",579ScriptedSyntheticChildren::Flags());580581AddCXXSynthetic(582objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator,583"NSSet synthetic children", "NSSet", ScriptedSyntheticChildren::Flags());584AddCXXSynthetic(objc_category_sp,585lldb_private::formatters::NSSetSyntheticFrontEndCreator,586"__NSSetI synthetic children", "__NSSetI",587ScriptedSyntheticChildren::Flags());588AddCXXSynthetic(objc_category_sp,589lldb_private::formatters::NSSetSyntheticFrontEndCreator,590"__NSSetM synthetic children", "__NSSetM",591ScriptedSyntheticChildren::Flags());592AddCXXSynthetic(objc_category_sp,593lldb_private::formatters::NSSetSyntheticFrontEndCreator,594"__NSCFSet synthetic children", "__NSCFSet",595ScriptedSyntheticChildren::Flags());596AddCXXSynthetic(objc_category_sp,597lldb_private::formatters::NSSetSyntheticFrontEndCreator,598"CFSetRef synthetic children", "CFSetRef",599ScriptedSyntheticChildren::Flags());600601AddCXXSynthetic(objc_category_sp,602lldb_private::formatters::NSSetSyntheticFrontEndCreator,603"NSMutableSet synthetic children", "NSMutableSet",604ScriptedSyntheticChildren::Flags());605AddCXXSynthetic(objc_category_sp,606lldb_private::formatters::NSSetSyntheticFrontEndCreator,607"NSOrderedSet synthetic children", "NSOrderedSet",608ScriptedSyntheticChildren::Flags());609AddCXXSynthetic(objc_category_sp,610lldb_private::formatters::NSSetSyntheticFrontEndCreator,611"__NSOrderedSetI synthetic children", "__NSOrderedSetI",612ScriptedSyntheticChildren::Flags());613AddCXXSynthetic(objc_category_sp,614lldb_private::formatters::NSSetSyntheticFrontEndCreator,615"__NSOrderedSetM synthetic children", "__NSOrderedSetM",616ScriptedSyntheticChildren::Flags());617AddCXXSynthetic(objc_category_sp,618lldb_private::formatters::NSSetSyntheticFrontEndCreator,619"__CFSet synthetic children", "__CFSet",620ScriptedSyntheticChildren::Flags());621622AddCXXSynthetic(objc_category_sp,623lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator,624"NSIndexPath synthetic children", "NSIndexPath",625ScriptedSyntheticChildren::Flags());626627AddCXXSummary(objc_category_sp,628lldb_private::formatters::CFBagSummaryProvider,629"CFBag summary provider", "CFBagRef", appkit_flags);630AddCXXSummary(objc_category_sp,631lldb_private::formatters::CFBagSummaryProvider,632"CFBag summary provider", "__CFBag", appkit_flags);633AddCXXSummary(objc_category_sp,634lldb_private::formatters::CFBagSummaryProvider,635"CFBag summary provider", "const struct __CFBag", appkit_flags);636AddCXXSummary(objc_category_sp,637lldb_private::formatters::CFBagSummaryProvider,638"CFBag summary provider", "CFMutableBagRef", appkit_flags);639640AddCXXSummary(641objc_category_sp, lldb_private::formatters::CFBinaryHeapSummaryProvider,642"CFBinaryHeap summary provider", "CFBinaryHeapRef", appkit_flags);643AddCXXSummary(644objc_category_sp, lldb_private::formatters::CFBinaryHeapSummaryProvider,645"CFBinaryHeap summary provider", "__CFBinaryHeap", appkit_flags);646647AddCXXSummary(objc_category_sp,648lldb_private::formatters::NSStringSummaryProvider,649"NSString summary provider", "NSString", appkit_flags);650AddCXXSummary(objc_category_sp,651lldb_private::formatters::NSStringSummaryProvider,652"NSString summary provider", "CFStringRef", appkit_flags);653AddCXXSummary(objc_category_sp,654lldb_private::formatters::NSStringSummaryProvider,655"NSString summary provider", "__CFString", appkit_flags);656AddCXXSummary(657objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,658"NSString summary provider", "CFMutableStringRef", appkit_flags);659AddCXXSummary(objc_category_sp,660lldb_private::formatters::NSStringSummaryProvider,661"NSString summary provider", "NSMutableString", appkit_flags);662AddCXXSummary(663objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,664"NSString summary provider", "__NSCFConstantString", appkit_flags);665AddCXXSummary(objc_category_sp,666lldb_private::formatters::NSStringSummaryProvider,667"NSString summary provider", "__NSCFString", appkit_flags);668AddCXXSummary(669objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,670"NSString summary provider", "NSCFConstantString", appkit_flags);671AddCXXSummary(objc_category_sp,672lldb_private::formatters::NSStringSummaryProvider,673"NSString summary provider", "NSCFString", appkit_flags);674AddCXXSummary(objc_category_sp,675lldb_private::formatters::NSStringSummaryProvider,676"NSString summary provider", "NSPathStore2", appkit_flags);677AddCXXSummary(678objc_category_sp, lldb_private::formatters::NSStringSummaryProvider,679"NSString summary provider", "NSTaggedPointerString", appkit_flags);680681AddCXXSummary(objc_category_sp,682lldb_private::formatters::NSAttributedStringSummaryProvider,683"NSAttributedString summary provider", "NSAttributedString",684appkit_flags);685AddCXXSummary(686objc_category_sp,687lldb_private::formatters::NSMutableAttributedStringSummaryProvider,688"NSMutableAttributedString summary provider", "NSMutableAttributedString",689appkit_flags);690AddCXXSummary(691objc_category_sp,692lldb_private::formatters::NSMutableAttributedStringSummaryProvider,693"NSMutableAttributedString summary provider",694"NSConcreteMutableAttributedString", appkit_flags);695696AddCXXSummary(objc_category_sp,697lldb_private::formatters::NSBundleSummaryProvider,698"NSBundle summary provider", "NSBundle", appkit_flags);699700AddCXXSummary(objc_category_sp,701lldb_private::formatters::NSDataSummaryProvider<false>,702"NSData summary provider", "NSData", appkit_flags);703AddCXXSummary(objc_category_sp,704lldb_private::formatters::NSDataSummaryProvider<false>,705"NSData summary provider", "_NSInlineData", appkit_flags);706AddCXXSummary(objc_category_sp,707lldb_private::formatters::NSDataSummaryProvider<false>,708"NSData summary provider", "NSConcreteData", appkit_flags);709AddCXXSummary(710objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>,711"NSData summary provider", "NSConcreteMutableData", appkit_flags);712AddCXXSummary(objc_category_sp,713lldb_private::formatters::NSDataSummaryProvider<false>,714"NSData summary provider", "NSMutableData", appkit_flags);715AddCXXSummary(objc_category_sp,716lldb_private::formatters::NSDataSummaryProvider<false>,717"NSData summary provider", "__NSCFData", appkit_flags);718AddCXXSummary(objc_category_sp,719lldb_private::formatters::NSDataSummaryProvider<true>,720"NSData summary provider", "CFDataRef", appkit_flags);721AddCXXSummary(objc_category_sp,722lldb_private::formatters::NSDataSummaryProvider<true>,723"NSData summary provider", "CFMutableDataRef", appkit_flags);724725AddCXXSummary(objc_category_sp,726lldb_private::formatters::NSMachPortSummaryProvider,727"NSMachPort summary provider", "NSMachPort", appkit_flags);728729AddCXXSummary(730objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider,731"NSNotification summary provider", "NSNotification", appkit_flags);732AddCXXSummary(objc_category_sp,733lldb_private::formatters::NSNotificationSummaryProvider,734"NSNotification summary provider", "NSConcreteNotification",735appkit_flags);736737AddCXXSummary(objc_category_sp,738lldb_private::formatters::NSNumberSummaryProvider,739"NSNumber summary provider", "NSNumber", appkit_flags);740AddCXXSummary(741objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,742"NSNumber summary provider", "NSConstantIntegerNumber", appkit_flags);743AddCXXSummary(744objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,745"NSNumber summary provider", "NSConstantDoubleNumber", appkit_flags);746AddCXXSummary(747objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,748"NSNumber summary provider", "NSConstantFloatNumber", appkit_flags);749AddCXXSummary(objc_category_sp,750lldb_private::formatters::NSNumberSummaryProvider,751"CFNumberRef summary provider", "CFNumberRef", appkit_flags);752AddCXXSummary(objc_category_sp,753lldb_private::formatters::NSNumberSummaryProvider,754"NSNumber summary provider", "__NSCFBoolean", appkit_flags);755AddCXXSummary(objc_category_sp,756lldb_private::formatters::NSNumberSummaryProvider,757"NSNumber summary provider", "__NSCFNumber", appkit_flags);758AddCXXSummary(objc_category_sp,759lldb_private::formatters::NSNumberSummaryProvider,760"NSNumber summary provider", "NSCFBoolean", appkit_flags);761AddCXXSummary(objc_category_sp,762lldb_private::formatters::NSNumberSummaryProvider,763"NSNumber summary provider", "NSCFNumber", appkit_flags);764AddCXXSummary(765objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider,766"NSDecimalNumber summary provider", "NSDecimalNumber", appkit_flags);767768AddCXXSummary(objc_category_sp,769lldb_private::formatters::NSURLSummaryProvider,770"NSURL summary provider", "NSURL", appkit_flags);771AddCXXSummary(objc_category_sp,772lldb_private::formatters::NSURLSummaryProvider,773"NSURL summary provider", "CFURLRef", appkit_flags);774775AddCXXSummary(objc_category_sp,776lldb_private::formatters::NSDateSummaryProvider,777"NSDate summary provider", "NSDate", appkit_flags);778AddCXXSummary(objc_category_sp,779lldb_private::formatters::NSDateSummaryProvider,780"NSDate summary provider", "__NSDate", appkit_flags);781AddCXXSummary(objc_category_sp,782lldb_private::formatters::NSDateSummaryProvider,783"NSDate summary provider", "__NSTaggedDate", appkit_flags);784AddCXXSummary(objc_category_sp,785lldb_private::formatters::NSDateSummaryProvider,786"NSDate summary provider", "NSCalendarDate", appkit_flags);787788AddCXXSummary(objc_category_sp,789lldb_private::formatters::NSTimeZoneSummaryProvider,790"NSTimeZone summary provider", "NSTimeZone", appkit_flags);791AddCXXSummary(objc_category_sp,792lldb_private::formatters::NSTimeZoneSummaryProvider,793"NSTimeZone summary provider", "CFTimeZoneRef", appkit_flags);794AddCXXSummary(objc_category_sp,795lldb_private::formatters::NSTimeZoneSummaryProvider,796"NSTimeZone summary provider", "__NSTimeZone", appkit_flags);797798// CFAbsoluteTime is actually a double rather than a pointer to an object we799// do not care about the numeric value, since it is probably meaningless to800// users801appkit_flags.SetDontShowValue(true);802AddCXXSummary(803objc_category_sp, lldb_private::formatters::CFAbsoluteTimeSummaryProvider,804"CFAbsoluteTime summary provider", "CFAbsoluteTime", appkit_flags);805appkit_flags.SetDontShowValue(false);806807AddCXXSummary(objc_category_sp,808lldb_private::formatters::NSIndexSetSummaryProvider,809"NSIndexSet summary provider", "NSIndexSet", appkit_flags);810AddCXXSummary(811objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider,812"NSIndexSet summary provider", "NSMutableIndexSet", appkit_flags);813814AddStringSummary(objc_category_sp,815"@\"${var.month%d}/${var.day%d}/${var.year%d} "816"${var.hour%d}:${var.minute%d}:${var.second}\"",817"CFGregorianDate", appkit_flags);818819AddCXXSummary(objc_category_sp,820lldb_private::formatters::CFBitVectorSummaryProvider,821"CFBitVector summary provider", "CFBitVectorRef", appkit_flags);822AddCXXSummary(823objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider,824"CFBitVector summary provider", "CFMutableBitVectorRef", appkit_flags);825AddCXXSummary(objc_category_sp,826lldb_private::formatters::CFBitVectorSummaryProvider,827"CFBitVector summary provider", "__CFBitVector", appkit_flags);828AddCXXSummary(829objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider,830"CFBitVector summary provider", "__CFMutableBitVector", appkit_flags);831}832833static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) {834if (!objc_category_sp)835return;836837TypeSummaryImpl::Flags cm_flags;838cm_flags.SetCascades(true)839.SetDontShowChildren(false)840.SetDontShowValue(false)841.SetHideItemNames(false)842.SetShowMembersOneLiner(false)843.SetSkipPointers(false)844.SetSkipReferences(false);845846AddCXXSummary(objc_category_sp,847lldb_private::formatters::CMTimeSummaryProvider,848"CMTime summary provider", "CMTime", cm_flags);849}850851lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() {852static llvm::once_flag g_initialize;853static TypeCategoryImplSP g_category;854855llvm::call_once(g_initialize, [this]() -> void {856DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),857g_category);858if (g_category) {859LoadCoreMediaFormatters(g_category);860LoadObjCFormatters(g_category);861}862});863return g_category;864}865866std::vector<FormattersMatchCandidate>867ObjCLanguage::GetPossibleFormattersMatches(ValueObject &valobj,868lldb::DynamicValueType use_dynamic) {869std::vector<FormattersMatchCandidate> result;870871if (use_dynamic == lldb::eNoDynamicValues)872return result;873874CompilerType compiler_type(valobj.GetCompilerType());875876const bool check_cpp = false;877const bool check_objc = true;878bool canBeObjCDynamic =879compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc);880881if (canBeObjCDynamic && ClangUtil::IsClangType(compiler_type)) {882do {883lldb::ProcessSP process_sp = valobj.GetProcessSP();884if (!process_sp)885break;886ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);887if (runtime == nullptr)888break;889ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp(890runtime->GetClassDescriptor(valobj));891if (!objc_class_sp)892break;893if (ConstString name = objc_class_sp->GetClassName())894result.push_back(895{name, valobj.GetTargetSP()->GetDebugger().GetScriptInterpreter(),896TypeImpl(objc_class_sp->GetType()),897FormattersMatchCandidate::Flags{}});898} while (false);899}900901return result;902}903904std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {905class ObjCScavengerResult : public Language::TypeScavenger::Result {906public:907ObjCScavengerResult(CompilerType type)908: Language::TypeScavenger::Result(), m_compiler_type(type) {}909910bool IsValid() override { return m_compiler_type.IsValid(); }911912bool DumpToStream(Stream &stream, bool print_help_if_available) override {913if (IsValid()) {914m_compiler_type.DumpTypeDescription(&stream);915stream.EOL();916return true;917}918return false;919}920921private:922CompilerType m_compiler_type;923};924925class ObjCRuntimeScavenger : public Language::TypeScavenger {926protected:927bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,928ResultSet &results) override {929bool result = false;930931if (auto *process = exe_scope->CalculateProcess().get()) {932if (auto *objc_runtime = ObjCLanguageRuntime::Get(*process)) {933if (auto *decl_vendor = objc_runtime->GetDeclVendor()) {934ConstString name(key);935for (const CompilerType &type :936decl_vendor->FindTypes(name, /*max_matches*/ UINT32_MAX)) {937result = true;938std::unique_ptr<Language::TypeScavenger::Result> result(939new ObjCScavengerResult(type));940results.insert(std::move(result));941}942}943}944}945946return result;947}948949friend class lldb_private::ObjCLanguage;950};951952class ObjCModulesScavenger : public Language::TypeScavenger {953protected:954bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,955ResultSet &results) override {956bool result = false;957958if (auto *target = exe_scope->CalculateTarget().get()) {959auto *persistent_vars = llvm::cast<ClangPersistentVariables>(960target->GetPersistentExpressionStateForLanguage(961lldb::eLanguageTypeC));962if (std::shared_ptr<ClangModulesDeclVendor> clang_modules_decl_vendor =963persistent_vars->GetClangModulesDeclVendor()) {964ConstString key_cs(key);965auto types = clang_modules_decl_vendor->FindTypes(966key_cs, /*max_matches*/ UINT32_MAX);967if (!types.empty()) {968result = true;969std::unique_ptr<Language::TypeScavenger::Result> result(970new ObjCScavengerResult(types.front()));971results.insert(std::move(result));972}973}974}975976return result;977}978979friend class lldb_private::ObjCLanguage;980};981982class ObjCDebugInfoScavenger : public Language::ImageListTypeScavenger {983public:984CompilerType AdjustForInclusion(CompilerType &candidate) override {985LanguageType lang_type(candidate.GetMinimumLanguage());986if (!Language::LanguageIsObjC(lang_type))987return CompilerType();988if (candidate.IsTypedefType())989return candidate.GetTypedefedType();990return candidate;991}992};993994return std::unique_ptr<TypeScavenger>(995new Language::EitherTypeScavenger<ObjCModulesScavenger,996ObjCRuntimeScavenger,997ObjCDebugInfoScavenger>());998}9991000std::pair<llvm::StringRef, llvm::StringRef>1001ObjCLanguage::GetFormatterPrefixSuffix(llvm::StringRef type_hint) {1002static constexpr llvm::StringRef empty;1003static const llvm::StringMap<1004std::pair<const llvm::StringRef, const llvm::StringRef>>1005g_affix_map = {1006{"CFBag", {"@", empty}},1007{"CFBinaryHeap", {"@", empty}},1008{"NSString", {"@", empty}},1009{"NSString*", {"@", empty}},1010{"NSNumber:char", {"(char)", empty}},1011{"NSNumber:short", {"(short)", empty}},1012{"NSNumber:int", {"(int)", empty}},1013{"NSNumber:long", {"(long)", empty}},1014{"NSNumber:int128_t", {"(int128_t)", empty}},1015{"NSNumber:float", {"(float)", empty}},1016{"NSNumber:double", {"(double)", empty}},1017{"NSData", {"@\"", "\""}},1018{"NSArray", {"@\"", "\""}},1019};1020return g_affix_map.lookup(type_hint);1021}10221023bool ObjCLanguage::IsNilReference(ValueObject &valobj) {1024const uint32_t mask = eTypeIsObjC | eTypeIsPointer;1025bool isObjCpointer =1026(((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask);1027if (!isObjCpointer)1028return false;1029bool canReadValue = true;1030bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;1031return canReadValue && isZero;1032}10331034bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const {1035const auto suffixes = {".h", ".m", ".M"};1036for (auto suffix : suffixes) {1037if (file_path.ends_with_insensitive(suffix))1038return true;1039}1040return false;1041}104210431044