brintos

brintos / llvm-project-archived public Read only

0
0
Text · 45.6 KiB · c0dcb95 Raw
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