brintos

brintos / llvm-project-archived public Read only

0
0
Text · 101.3 KiB · a3624ac Raw
2548 lines · cpp
1//===-- CPlusPlusLanguage.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 "CPlusPlusLanguage.h"10 11#include <cctype>12#include <cstring>13 14#include <functional>15#include <memory>16#include <mutex>17#include <set>18 19#include "llvm/ADT/StringRef.h"20#include "llvm/Demangle/ItaniumDemangle.h"21 22#include "lldb/Core/DemangledNameInfo.h"23#include "lldb/Core/Mangled.h"24#include "lldb/Core/Module.h"25#include "lldb/Core/PluginManager.h"26#include "lldb/Core/UniqueCStringMap.h"27#include "lldb/DataFormatters/CXXFunctionPointer.h"28#include "lldb/DataFormatters/DataVisualization.h"29#include "lldb/DataFormatters/FormattersHelpers.h"30#include "lldb/DataFormatters/VectorType.h"31#include "lldb/Interpreter/OptionValueProperties.h"32#include "lldb/Symbol/SymbolFile.h"33#include "lldb/Symbol/VariableList.h"34#include "lldb/Utility/ConstString.h"35#include "lldb/Utility/LLDBLog.h"36#include "lldb/Utility/Log.h"37#include "lldb/Utility/RegularExpression.h"38#include "lldb/ValueObject/ValueObjectVariable.h"39 40#include "BlockPointer.h"41#include "CPlusPlusNameParser.h"42#include "Coroutines.h"43#include "CxxStringTypes.h"44#include "Generic.h"45#include "LibCxx.h"46#include "LibCxxAtomic.h"47#include "LibCxxVariant.h"48#include "LibStdcpp.h"49#include "MSVCUndecoratedNameParser.h"50#include "MsvcStl.h"51#include "lldb/lldb-enumerations.h"52 53using namespace lldb;54using namespace lldb_private;55using namespace lldb_private::formatters;56 57LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)58 59void CPlusPlusLanguage::Initialize() {60  PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",61                                CreateInstance, &DebuggerInitialize);62}63 64void CPlusPlusLanguage::Terminate() {65  PluginManager::UnregisterPlugin(CreateInstance);66}67 68std::unique_ptr<Language::MethodName>69CPlusPlusLanguage::GetMethodName(ConstString full_name) const {70  std::unique_ptr<CxxMethodName> cpp_method =71      std::make_unique<CxxMethodName>(full_name);72  cpp_method->IsValid();73  return cpp_method;74}75 76std::pair<FunctionNameType, std::optional<ConstString>>77CPlusPlusLanguage::GetFunctionNameInfo(ConstString name) const {78  if (Mangled::IsMangledName(name.GetCString()))79    return {eFunctionNameTypeFull, std::nullopt};80 81  FunctionNameType func_name_type = eFunctionNameTypeNone;82  CxxMethodName method(name);83  llvm::StringRef basename = method.GetBasename();84  if (basename.empty()) {85    llvm::StringRef context;86    func_name_type |=87        (ExtractContextAndIdentifier(name.GetStringRef(), context, basename)88             ? (eFunctionNameTypeMethod | eFunctionNameTypeBase)89             : eFunctionNameTypeFull);90  } else {91    func_name_type |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);92  }93 94  if (!method.GetQualifiers().empty()) {95    // There is a 'const' or other qualifier following the end of the function96    // parens, this can't be a eFunctionNameTypeBase.97    func_name_type &= ~(eFunctionNameTypeBase);98  }99 100  if (basename.empty())101    return {func_name_type, std::nullopt};102  else103    return {func_name_type, ConstString(basename)};104}105 106bool CPlusPlusLanguage::SymbolNameFitsToLanguage(const Mangled &mangled) const {107  auto mangling_scheme =108      Mangled::GetManglingScheme(mangled.GetMangledName().GetStringRef());109  return mangling_scheme == Mangled::eManglingSchemeItanium ||110         mangling_scheme == Mangled::eManglingSchemeMSVC;111}112 113ConstString CPlusPlusLanguage::GetDemangledFunctionNameWithoutArguments(114    Mangled mangled) const {115  const char *mangled_name_cstr = mangled.GetMangledName().GetCString();116  ConstString demangled_name = mangled.GetDemangledName();117  if (demangled_name && mangled_name_cstr && mangled_name_cstr[0]) {118    if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&119        (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,120                                        // typeinfo structure, and typeinfo121                                        // mangled_name122         mangled_name_cstr[2] != 'G' && // avoid guard variables123         mangled_name_cstr[2] != 'Z'))  // named local entities (if we124                                        // eventually handle eSymbolTypeData,125                                        // we will want this back)126    {127      CxxMethodName cxx_method(demangled_name);128      if (!cxx_method.GetBasename().empty()) {129        std::string shortname;130        if (!cxx_method.GetContext().empty())131          shortname = cxx_method.GetContext().str() + "::";132        shortname += cxx_method.GetBasename().str();133        return ConstString(shortname);134      }135    }136  }137  if (demangled_name)138    return demangled_name;139  return mangled.GetMangledName();140}141 142// Static Functions143 144Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {145  // Use plugin for C++ but not for Objective-C++ (which has its own plugin).146  if (Language::LanguageIsCPlusPlus(language) &&147      language != eLanguageTypeObjC_plus_plus)148    return new CPlusPlusLanguage();149  return nullptr;150}151 152static bool ReverseFindMatchingChars(const llvm::StringRef &s,153                                     const llvm::StringRef &left_right_chars,154                                     size_t &left_pos, size_t &right_pos,155                                     size_t pos = llvm::StringRef::npos) {156  assert(left_right_chars.size() == 2);157  left_pos = llvm::StringRef::npos;158  const char left_char = left_right_chars[0];159  const char right_char = left_right_chars[1];160  pos = s.find_last_of(left_right_chars, pos);161  if (pos == llvm::StringRef::npos || s[pos] == left_char)162    return false;163  right_pos = pos;164  uint32_t depth = 1;165  while (pos > 0 && depth > 0) {166    pos = s.find_last_of(left_right_chars, pos);167    if (pos == llvm::StringRef::npos)168      return false;169    if (s[pos] == left_char) {170      if (--depth == 0) {171        left_pos = pos;172        return left_pos < right_pos;173      }174    } else if (s[pos] == right_char) {175      ++depth;176    }177  }178  return false;179}180 181static bool IsTrivialBasename(const llvm::StringRef &basename) {182  // Check that the basename matches with the following regular expression183  // "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation184  // because it is significantly more efficient then using the general purpose185  // regular expression library.186  size_t idx = 0;187  if (basename.starts_with('~'))188    idx = 1;189 190  if (basename.size() <= idx)191    return false; // Empty string or "~"192 193  if (!std::isalpha(static_cast<unsigned char>(basename[idx])) &&194      basename[idx] != '_')195    return false; // First character (after removing the possible '~'') isn't in196                  // [A-Za-z_]197 198  // Read all characters matching [A-Za-z_0-9]199  ++idx;200  while (idx < basename.size()) {201    if (!std::isalnum(static_cast<unsigned char>(basename[idx])) &&202        basename[idx] != '_')203      break;204    ++idx;205  }206 207  // We processed all characters. It is a vaild basename.208  return idx == basename.size();209}210 211/// A context is trivial if an only if it matches this pattern.212/// "^\s*([A-Za-z_:]*)\s*$". for example function `foo::bar::func()`213/// has a trivial context but. but `foo<int>::bar::func()` doesn't.214static bool IsTrivialContext(llvm::StringRef context) {215  // remove trailing or leading whitespace.216  context = context.trim();217 218  const auto iter = context.find_if_not([](char current) {219    return std::isalnum(static_cast<unsigned char>(current)) ||220           current == '_' || current == ':';221  });222  return iter == llvm::StringRef::npos;223}224 225/// Writes out the function name in 'full_name' to 'out_stream'226/// but replaces each argument type with the variable name227/// and the corresponding pretty-printed value228static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream,229                                            char const *full_name,230                                            ExecutionContextScope *exe_scope,231                                            VariableList const &args) {232  CPlusPlusLanguage::CxxMethodName cpp_method{ConstString(full_name)};233 234  if (!cpp_method.IsValid())235    return false;236 237  llvm::StringRef return_type = cpp_method.GetReturnType();238  if (!return_type.empty()) {239    out_stream.PutCString(return_type);240    out_stream.PutChar(' ');241  }242 243  out_stream.PutCString(cpp_method.GetScopeQualifiedName());244  out_stream.PutChar('(');245 246  FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope);247 248  out_stream.PutChar(')');249 250  llvm::StringRef qualifiers = cpp_method.GetQualifiers();251  if (!qualifiers.empty()) {252    out_stream.PutChar(' ');253    out_stream.PutCString(qualifiers);254  }255 256  return true;257}258 259static llvm::Expected<std::pair<llvm::StringRef, DemangledNameInfo>>260GetAndValidateInfo(const SymbolContext &sc) {261  Mangled mangled = sc.GetPossiblyInlinedFunctionName();262  if (!mangled)263    return llvm::createStringError("Function does not have a mangled name.");264 265  auto demangled_name = mangled.GetDemangledName().GetStringRef();266  if (demangled_name.empty())267    return llvm::createStringError(268        "Function '%s' does not have a demangled name.",269        mangled.GetMangledName().AsCString(""));270 271  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();272  if (!info)273    return llvm::createStringError(274        "Function '%s' does not have demangled info.", demangled_name.data());275 276  // Function without a basename is nonsense.277  if (!info->hasBasename())278    return llvm::createStringError(279        "DemangledInfo for '%s does not have basename range.",280        demangled_name.data());281 282  return std::make_pair(demangled_name, *info);283}284 285static llvm::Expected<llvm::StringRef>286GetDemangledBasename(const SymbolContext &sc) {287  auto info_or_err = GetAndValidateInfo(sc);288  if (!info_or_err)289    return info_or_err.takeError();290 291  auto [demangled_name, info] = *info_or_err;292 293  return CPlusPlusLanguage::GetDemangledBasename(demangled_name, info);294}295 296llvm::StringRef297CPlusPlusLanguage::GetDemangledBasename(llvm::StringRef demangled,298                                        const DemangledNameInfo &info) {299  assert(info.hasBasename());300  return demangled.slice(info.BasenameRange.first, info.BasenameRange.second);301}302 303llvm::Expected<llvm::StringRef>304CPlusPlusLanguage::GetDemangledTemplateArguments(305    llvm::StringRef demangled, const DemangledNameInfo &info) {306  if (!info.hasTemplateArguments())307    return llvm::createStringError(308        "Template arguments range for '%s' is invalid.", demangled.data());309 310  return demangled.slice(info.TemplateArgumentsRange.first,311                         info.TemplateArgumentsRange.second);312}313 314static llvm::Expected<llvm::StringRef>315GetDemangledTemplateArguments(const SymbolContext &sc) {316  auto info_or_err = GetAndValidateInfo(sc);317  if (!info_or_err)318    return info_or_err.takeError();319 320  auto [demangled_name, info] = *info_or_err;321 322  return CPlusPlusLanguage::GetDemangledTemplateArguments(demangled_name, info);323}324 325llvm::Expected<llvm::StringRef>326CPlusPlusLanguage::GetDemangledReturnTypeLHS(llvm::StringRef demangled,327                                             const DemangledNameInfo &info) {328  if (info.ScopeRange.first >= demangled.size())329    return llvm::createStringError(330        "Scope range for '%s' LHS return type is invalid.", demangled.data());331 332  return demangled.substr(0, info.ScopeRange.first);333}334 335static llvm::Expected<llvm::StringRef>336GetDemangledReturnTypeLHS(const SymbolContext &sc) {337  auto info_or_err = GetAndValidateInfo(sc);338  if (!info_or_err)339    return info_or_err.takeError();340 341  auto [demangled_name, info] = *info_or_err;342 343  return CPlusPlusLanguage::GetDemangledReturnTypeLHS(demangled_name, info);344}345 346llvm::Expected<llvm::StringRef>347CPlusPlusLanguage::GetDemangledFunctionQualifiers(348    llvm::StringRef demangled, const DemangledNameInfo &info) {349  if (!info.hasQualifiers())350    return llvm::createStringError("Qualifiers range for '%s' is invalid.",351                                   demangled.data());352 353  return demangled.slice(info.QualifiersRange.first,354                         info.QualifiersRange.second);355}356 357static llvm::Expected<llvm::StringRef>358GetDemangledFunctionQualifiers(const SymbolContext &sc) {359  auto info_or_err = GetAndValidateInfo(sc);360  if (!info_or_err)361    return info_or_err.takeError();362 363  auto [demangled_name, info] = *info_or_err;364 365  return CPlusPlusLanguage::GetDemangledFunctionQualifiers(demangled_name,366                                                           info);367}368 369llvm::Expected<llvm::StringRef>370CPlusPlusLanguage::GetDemangledReturnTypeRHS(llvm::StringRef demangled,371                                             const DemangledNameInfo &info) {372  if (info.QualifiersRange.first < info.ArgumentsRange.second)373    return llvm::createStringError(374        "Qualifiers range for '%s' RHS return type  is invalid.",375        demangled.data());376 377  return demangled.slice(info.ArgumentsRange.second,378                         info.QualifiersRange.first);379}380 381static llvm::Expected<llvm::StringRef>382GetDemangledReturnTypeRHS(const SymbolContext &sc) {383  auto info_or_err = GetAndValidateInfo(sc);384  if (!info_or_err)385    return info_or_err.takeError();386 387  auto [demangled_name, info] = *info_or_err;388 389  return CPlusPlusLanguage::GetDemangledReturnTypeRHS(demangled_name, info);390}391 392llvm::Expected<llvm::StringRef>393CPlusPlusLanguage::GetDemangledScope(llvm::StringRef demangled,394                                     const DemangledNameInfo &info) {395  if (!info.hasScope())396    return llvm::createStringError("Scope range for '%s' is invalid.",397                                   demangled.data());398 399  return demangled.slice(info.ScopeRange.first, info.ScopeRange.second);400}401 402static llvm::Expected<llvm::StringRef>403GetDemangledScope(const SymbolContext &sc) {404  auto info_or_err = GetAndValidateInfo(sc);405  if (!info_or_err)406    return info_or_err.takeError();407 408  auto [demangled_name, info] = *info_or_err;409 410  return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);411}412 413llvm::Expected<llvm::StringRef>414CPlusPlusLanguage::GetDemangledFunctionSuffix(llvm::StringRef demangled,415                                              const DemangledNameInfo &info) {416  if (!info.hasSuffix())417    return llvm::createStringError("Suffix range for '%s' is invalid.",418                                   demangled.data());419 420  return demangled.slice(info.SuffixRange.first, info.SuffixRange.second);421}422 423static llvm::Expected<llvm::StringRef>424GetDemangledFunctionSuffix(const SymbolContext &sc) {425  auto info_or_err = GetAndValidateInfo(sc);426  if (!info_or_err)427    return info_or_err.takeError();428 429  auto [demangled_name, info] = *info_or_err;430 431  return CPlusPlusLanguage::GetDemangledFunctionSuffix(demangled_name, info);432}433 434llvm::Expected<llvm::StringRef>435CPlusPlusLanguage::GetDemangledFunctionArguments(436    llvm::StringRef demangled, const DemangledNameInfo &info) {437  if (!info.hasArguments())438    return llvm::createStringError(439        "Function arguments range for '%s' is invalid.", demangled.data());440 441  return demangled.slice(info.ArgumentsRange.first, info.ArgumentsRange.second);442}443 444static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {445  assert(sc.symbol);446 447  auto info_or_err = GetAndValidateInfo(sc);448  if (!info_or_err) {449    LLDB_LOG_ERROR(GetLog(LLDBLog::Language), info_or_err.takeError(),450                   "Failed to handle ${{function.formatted-arguments}} "451                   "frame-format variable: {0}");452    return false;453  }454 455  auto [demangled_name, info] = *info_or_err;456 457  auto args_or_err =458      CPlusPlusLanguage::GetDemangledFunctionArguments(demangled_name, info);459  if (!args_or_err) {460    LLDB_LOG_ERROR(GetLog(LLDBLog::Language), args_or_err.takeError(),461                   "Failed to handle ${{function.formatted-arguments}} "462                   "frame-format variable: {0}");463    return false;464  }465 466  s << *args_or_err;467 468  return true;469}470 471bool CPlusPlusLanguage::CxxMethodName::TrySimplifiedParse() {472  // This method tries to parse simple method definitions which are presumably473  // most comman in user programs. Definitions that can be parsed by this474  // function don't have return types and templates in the name.475  // A::B::C::fun(std::vector<T> &) const476  size_t arg_start, arg_end;477  llvm::StringRef full(m_full.GetCString());478  llvm::StringRef parens("()", 2);479  if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {480    m_arguments = full.substr(arg_start, arg_end - arg_start + 1);481    if (arg_end + 1 < full.size())482      m_qualifiers = full.substr(arg_end + 1).ltrim();483 484    if (arg_start == 0)485      return false;486    size_t basename_end = arg_start;487    size_t context_start = 0;488    size_t context_end = full.rfind(':', basename_end);489    if (context_end == llvm::StringRef::npos)490      m_basename = full.substr(0, basename_end);491    else {492      if (context_start < context_end)493        m_context = full.substr(context_start, context_end - 1 - context_start);494      const size_t basename_begin = context_end + 1;495      m_basename = full.substr(basename_begin, basename_end - basename_begin);496    }497 498    if (IsTrivialBasename(m_basename) && IsTrivialContext(m_context)) {499      return true;500    }501    // The C++ basename doesn't match our regular expressions so this can't502    // be a valid C++ method, clear everything out and indicate an error503    m_context = llvm::StringRef();504    m_basename = llvm::StringRef();505    m_arguments = llvm::StringRef();506    m_qualifiers = llvm::StringRef();507    m_return_type = llvm::StringRef();508    return false;509  }510  return false;511}512 513void CPlusPlusLanguage::CxxMethodName::Parse() {514  if (!m_parsed && m_full) {515    if (TrySimplifiedParse()) {516      m_parse_error = false;517    } else {518      CPlusPlusNameParser parser(m_full.GetStringRef());519      if (auto function = parser.ParseAsFunctionDefinition()) {520        m_basename = function->name.basename;521        m_context = function->name.context;522        m_arguments = function->arguments;523        m_qualifiers = function->qualifiers;524        m_return_type = function->return_type;525        m_parse_error = false;526      } else {527        m_parse_error = true;528      }529    }530    if (m_context.empty()) {531      m_scope_qualified = std::string(m_basename);532    } else {533      m_scope_qualified = m_context;534      m_scope_qualified += "::";535      m_scope_qualified += m_basename;536    }537    m_parsed = true;538  }539}540 541llvm::StringRef542CPlusPlusLanguage::CxxMethodName::GetBasenameNoTemplateParameters() {543  llvm::StringRef basename = GetBasename();544  size_t arg_start, arg_end;545  llvm::StringRef parens("<>", 2);546  if (ReverseFindMatchingChars(basename, parens, arg_start, arg_end))547    return basename.substr(0, arg_start);548 549  return basename;550}551 552bool CPlusPlusLanguage::CxxMethodName::ContainsPath(llvm::StringRef path) {553  if (!m_parsed)554    Parse();555 556  // If we can't parse the incoming name, then just check that it contains path.557  if (m_parse_error)558    return m_full.GetStringRef().contains(path);559 560  llvm::StringRef identifier;561  llvm::StringRef context;562  const bool success =563      CPlusPlusLanguage::ExtractContextAndIdentifier(path, context, identifier);564  if (!success)565    return m_full.GetStringRef().contains(path);566 567  // Basename may include template arguments.568  // E.g.,569  // GetBaseName(): func<int>570  // identifier   : func571  //572  // ...but we still want to account for identifiers with template parameter573  // lists, e.g., when users set breakpoints on template specializations.574  //575  // E.g.,576  // GetBaseName(): func<uint32_t>577  // identifier   : func<int32_t*>578  //579  // Try to match the basename with or without template parameters.580  if (GetBasename() != identifier &&581      GetBasenameNoTemplateParameters() != identifier)582    return false;583 584  // Incoming path only had an identifier, so we match.585  if (context.empty())586    return true;587  // Incoming path has context but this method does not, no match.588  if (m_context.empty())589    return false;590 591  llvm::StringRef haystack = m_context;592  if (!haystack.consume_back(context))593    return false;594  if (haystack.empty() || !isalnum(haystack.back()))595    return true;596 597  return false;598}599 600bool CPlusPlusLanguage::DemangledNameContainsPath(llvm::StringRef path,601                                                  ConstString demangled) const {602  CxxMethodName demangled_name(demangled);603  return demangled_name.ContainsPath(path);604}605 606bool CPlusPlusLanguage::ExtractContextAndIdentifier(607    llvm::StringRef name, llvm::StringRef &context,608    llvm::StringRef &identifier) {609  if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name))610    return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context,611                                                                  identifier);612 613  CPlusPlusNameParser parser(name);614  if (auto full_name = parser.ParseAsFullName()) {615    identifier = full_name->basename;616    context = full_name->context;617    return true;618  }619  return false;620}621 622std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings(623    const ConstString mangled_name) const {624  std::vector<ConstString> alternates;625 626  /// Get a basic set of alternative manglings for the given symbol `name`, by627  /// making a few basic possible substitutions on basic types, storage duration628  /// and `const`ness for the given symbol. The output parameter `alternates`629  /// is filled with a best-guess, non-exhaustive set of different manglings630  /// for the given name.631 632  // Maybe we're looking for a const symbol but the debug info told us it was633  // non-const...634  if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&635      strncmp(mangled_name.GetCString(), "_ZNK", 4)) {636    std::string fixed_scratch("_ZNK");637    fixed_scratch.append(mangled_name.GetCString() + 3);638    alternates.push_back(ConstString(fixed_scratch));639  }640 641  // Maybe we're looking for a static symbol but we thought it was global...642  if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&643      strncmp(mangled_name.GetCString(), "_ZL", 3)) {644    std::string fixed_scratch("_ZL");645    fixed_scratch.append(mangled_name.GetCString() + 2);646    alternates.push_back(ConstString(fixed_scratch));647  }648 649  auto *log = GetLog(LLDBLog::Language);650 651  // `char` is implementation defined as either `signed` or `unsigned`.  As a652  // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed653  // char, 'h'-unsigned char.  If we're looking for symbols with a signed char654  // parameter, try finding matches which have the general case 'c'.655  if (auto char_fixup_or_err =656          SubstituteType_ItaniumMangle(mangled_name.GetStringRef(), "a", "c")) {657    // LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);658    if (*char_fixup_or_err)659      alternates.push_back(*char_fixup_or_err);660  } else661    LLDB_LOG_ERROR(log, char_fixup_or_err.takeError(),662                   "Failed to substitute 'char' type mangling: {0}");663 664  // long long parameter mangling 'x', may actually just be a long 'l' argument665  if (auto long_fixup_or_err =666          SubstituteType_ItaniumMangle(mangled_name.GetStringRef(), "x", "l")) {667    if (*long_fixup_or_err)668      alternates.push_back(*long_fixup_or_err);669  } else670    LLDB_LOG_ERROR(log, long_fixup_or_err.takeError(),671                   "Failed to substitute 'long long' type mangling: {0}");672 673  // unsigned long long parameter mangling 'y', may actually just be unsigned674  // long 'm' argument675  if (auto ulong_fixup_or_err =676          SubstituteType_ItaniumMangle(mangled_name.GetStringRef(), "y", "m")) {677    if (*ulong_fixup_or_err)678      alternates.push_back(*ulong_fixup_or_err);679  } else680    LLDB_LOG_ERROR(681        log, ulong_fixup_or_err.takeError(),682        "Failed to substitute 'unsigned long long' type mangling: {0}");683 684  if (auto ctor_fixup_or_err = SubstituteStructorAliases_ItaniumMangle(685          mangled_name.GetStringRef())) {686    if (*ctor_fixup_or_err) {687      alternates.push_back(*ctor_fixup_or_err);688    }689  } else690    LLDB_LOG_ERROR(log, ctor_fixup_or_err.takeError(),691                   "Failed to substitute structor alias manglings: {0}");692 693  return alternates;694}695 696ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName(697    const Mangled mangled, const SymbolContext &sym_ctx) const {698  ConstString demangled = mangled.GetDemangledName();699  if (!demangled)700    return ConstString();701 702  CxxMethodName cpp_name(demangled);703  std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();704 705  if (!scope_qualified_name.size())706    return ConstString();707 708  if (!sym_ctx.module_sp)709    return ConstString();710 711  lldb_private::SymbolFile *sym_file = sym_ctx.module_sp->GetSymbolFile();712  if (!sym_file)713    return ConstString();714 715  std::vector<ConstString> alternates;716  sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);717 718  std::vector<ConstString> param_and_qual_matches;719  std::vector<ConstString> param_matches;720  for (size_t i = 0; i < alternates.size(); i++) {721    ConstString alternate_mangled_name = alternates[i];722    Mangled mangled(alternate_mangled_name);723    ConstString demangled = mangled.GetDemangledName();724 725    CxxMethodName alternate_cpp_name(demangled);726    if (!cpp_name.IsValid())727      continue;728 729    if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) {730      if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())731        param_and_qual_matches.push_back(alternate_mangled_name);732      else733        param_matches.push_back(alternate_mangled_name);734    }735  }736 737  if (param_and_qual_matches.size())738    return param_and_qual_matches[0]; // It is assumed that there will be only739                                      // one!740  else if (param_matches.size())741    return param_matches[0]; // Return one of them as a best match742  else743    return ConstString();744}745 746static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {747  if (!cpp_category_sp)748    return;749 750  TypeSummaryImpl::Flags stl_summary_flags;751  stl_summary_flags.SetCascades(true)752      .SetSkipPointers(false)753      .SetSkipReferences(false)754      .SetDontShowChildren(true)755      .SetDontShowValue(false)756      .SetShowMembersOneLiner(false)757      .SetHideItemNames(false);758 759  AddCXXSummary(cpp_category_sp,760                lldb_private::formatters::LibcxxStringSummaryProviderASCII,761                "std::string summary provider", "^std::__[[:alnum:]]+::string$",762                stl_summary_flags, true);763  AddCXXSummary(cpp_category_sp,764                lldb_private::formatters::LibcxxStringSummaryProviderASCII,765                "std::string summary provider",766                "^std::__[[:alnum:]]+::basic_string<char, "767                "std::__[[:alnum:]]+::char_traits<char>,.*>$",768                stl_summary_flags, true);769  AddCXXSummary(cpp_category_sp,770                lldb_private::formatters::LibcxxStringSummaryProviderASCII,771                "std::string summary provider",772                "^std::__[[:alnum:]]+::basic_string<unsigned char, "773                "std::__[[:alnum:]]+::char_traits<unsigned char>,.*>$",774                stl_summary_flags, true);775 776  AddCXXSummary(cpp_category_sp,777                lldb_private::formatters::LibcxxStringSummaryProviderUTF16,778                "std::u16string summary provider",779                "^std::__[[:alnum:]]+::basic_string<char16_t, "780                "std::__[[:alnum:]]+::char_traits<char16_t>,.*>$",781                stl_summary_flags, true);782 783  AddCXXSummary(cpp_category_sp,784                lldb_private::formatters::LibcxxStringSummaryProviderUTF32,785                "std::u32string summary provider",786                "^std::__[[:alnum:]]+::basic_string<char32_t, "787                "std::__[[:alnum:]]+::char_traits<char32_t>,.*>$",788                stl_summary_flags, true);789 790  AddCXXSummary(cpp_category_sp,791                lldb_private::formatters::LibcxxWStringSummaryProvider,792                "std::wstring summary provider",793                "^std::__[[:alnum:]]+::wstring$", stl_summary_flags, true);794  AddCXXSummary(cpp_category_sp,795                lldb_private::formatters::LibcxxWStringSummaryProvider,796                "std::wstring summary provider",797                "^std::__[[:alnum:]]+::basic_string<wchar_t, "798                "std::__[[:alnum:]]+::char_traits<wchar_t>,.*>$",799                stl_summary_flags, true);800 801  AddCXXSummary(cpp_category_sp,802                lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,803                "std::string_view summary provider",804                "^std::__[[:alnum:]]+::string_view$", stl_summary_flags, true);805  AddCXXSummary(cpp_category_sp,806                lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,807                "std::string_view summary provider",808                "^std::__[[:alnum:]]+::basic_string_view<char, "809                "std::__[[:alnum:]]+::char_traits<char> >$",810                stl_summary_flags, true);811  AddCXXSummary(cpp_category_sp,812                lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,813                "std::string_view summary provider",814                "^std::__[[:alnum:]]+::basic_string_view<unsigned char, "815                "std::__[[:alnum:]]+::char_traits<unsigned char> >$",816                stl_summary_flags, true);817 818  AddCXXSummary(cpp_category_sp,819                lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16,820                "std::u16string_view summary provider",821                "^std::__[[:alnum:]]+::basic_string_view<char16_t, "822                "std::__[[:alnum:]]+::char_traits<char16_t> >$",823                stl_summary_flags, true);824 825  AddCXXSummary(cpp_category_sp,826                lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32,827                "std::u32string_view summary provider",828                "^std::__[[:alnum:]]+::basic_string_view<char32_t, "829                "std::__[[:alnum:]]+::char_traits<char32_t> >$",830                stl_summary_flags, true);831 832  AddCXXSummary(cpp_category_sp,833                lldb_private::formatters::LibcxxWStringViewSummaryProvider,834                "std::wstring_view summary provider",835                "^std::__[[:alnum:]]+::wstring_view$", stl_summary_flags, true);836  AddCXXSummary(cpp_category_sp,837                lldb_private::formatters::LibcxxWStringViewSummaryProvider,838                "std::wstring_view summary provider",839                "^std::__[[:alnum:]]+::basic_string_view<wchar_t, "840                "std::__[[:alnum:]]+::char_traits<wchar_t> >$",841                stl_summary_flags, true);842 843  SyntheticChildren::Flags stl_synth_flags;844  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(845      false);846  SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;847  stl_deref_flags.SetFrontEndWantsDereference();848 849  AddCXXSynthetic(850      cpp_category_sp,851      lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,852      "libc++ std::bitset synthetic children",853      "^std::__[[:alnum:]]+::bitset<.+>$", stl_deref_flags, true);854  AddCXXSynthetic(855      cpp_category_sp,856      lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,857      "libc++ std::vector synthetic children",858      "^std::__[[:alnum:]]+::vector<.+>$", stl_deref_flags, true);859  AddCXXSynthetic(860      cpp_category_sp,861      lldb_private::formatters::LibcxxStdValarraySyntheticFrontEndCreator,862      "libc++ std::valarray synthetic children",863      "^std::__[[:alnum:]]+::valarray<.+>$", stl_deref_flags, true);864  AddCXXSynthetic(865      cpp_category_sp,866      lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator,867      "libc++ std::slice_array synthetic children",868      "^std::__[[:alnum:]]+::slice_array<.+>$", stl_deref_flags, true);869  AddCXXSynthetic(870      cpp_category_sp,871      lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEndCreator,872      "libc++ synthetic children for the valarray proxy arrays",873      "^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$",874      stl_deref_flags, true);875  AddCXXSynthetic(876      cpp_category_sp,877      lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,878      "libc++ std::forward_list synthetic children",879      "^std::__[[:alnum:]]+::forward_list<.+>$", stl_synth_flags, true);880  AddCXXSynthetic(881      cpp_category_sp,882      lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,883      "libc++ std::list synthetic children",884      // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>$"885      // so that it does not clash with: "^std::(__cxx11::)?list<.+>$"886      "^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"887      "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>$",888      stl_deref_flags, true);889  AddCXXSynthetic(890      cpp_category_sp,891      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,892      "libc++ std::map synthetic children", "^std::__[[:alnum:]]+::map<.+> >$",893      stl_synth_flags, true);894  AddCXXSynthetic(895      cpp_category_sp,896      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,897      "libc++ std::set synthetic children", "^std::__[[:alnum:]]+::set<.+> >$",898      stl_deref_flags, true);899  AddCXXSynthetic(900      cpp_category_sp,901      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,902      "libc++ std::multiset synthetic children",903      "^std::__[[:alnum:]]+::multiset<.+> >$", stl_deref_flags, true);904  AddCXXSynthetic(905      cpp_category_sp,906      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,907      "libc++ std::multimap synthetic children",908      "^std::__[[:alnum:]]+::multimap<.+> >$", stl_synth_flags, true);909  AddCXXSynthetic(910      cpp_category_sp,911      lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator,912      "libc++ std::unordered containers synthetic children",913      "^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$",914      stl_synth_flags, true);915  AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,916                  "libc++ std::queue synthetic children",917                  "^std::__[[:alnum:]]+::queue<.+>$", stl_synth_flags, true);918  AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,919                  "libc++ std::tuple synthetic children",920                  "^std::__[[:alnum:]]+::tuple<.*>$", stl_synth_flags, true);921  AddCXXSynthetic(cpp_category_sp, LibcxxOptionalSyntheticFrontEndCreator,922                  "libc++ std::optional synthetic children",923                  "^std::__[[:alnum:]]+::optional<.+>$", stl_synth_flags, true);924  AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,925                  "libc++ std::variant synthetic children",926                  "^std::__[[:alnum:]]+::variant<.+>$", stl_synth_flags, true);927  AddCXXSynthetic(928      cpp_category_sp,929      lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,930      "libc++ std::atomic synthetic children",931      "^std::__[[:alnum:]]+::atomic<.+>$", stl_synth_flags, true);932  AddCXXSynthetic(933      cpp_category_sp,934      lldb_private::formatters::LibcxxStdSpanSyntheticFrontEndCreator,935      "libc++ std::span synthetic children", "^std::__[[:alnum:]]+::span<.+>$",936      stl_deref_flags, true);937  AddCXXSynthetic(938      cpp_category_sp,939      lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEndCreator,940      "libc++ std::ranges::ref_view synthetic children",941      "^std::__[[:alnum:]]+::ranges::ref_view<.+>$", stl_deref_flags, true);942 943  cpp_category_sp->AddTypeSynthetic(944      "^std::__[[:alnum:]]+::deque<.+>$", eFormatterMatchRegex,945      SyntheticChildrenSP(new ScriptedSyntheticChildren(946          stl_synth_flags,947          "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));948 949  AddCXXSynthetic(950      cpp_category_sp,951      lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,952      "shared_ptr synthetic children", "^std::__[[:alnum:]]+::shared_ptr<.+>$",953      stl_synth_flags, true);954 955  static constexpr const char *const libcxx_std_unique_ptr_regex =956      "^std::__[[:alnum:]]+::unique_ptr<.+>$";957  AddCXXSynthetic(958      cpp_category_sp,959      lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator,960      "unique_ptr synthetic children", libcxx_std_unique_ptr_regex,961      stl_synth_flags, true);962 963  AddCXXSynthetic(964      cpp_category_sp,965      lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,966      "weak_ptr synthetic children", "^std::__[[:alnum:]]+::weak_ptr<.+>$",967      stl_synth_flags, true);968  AddCXXSummary(cpp_category_sp,969                lldb_private::formatters::LibcxxFunctionSummaryProvider,970                "libc++ std::function summary provider",971                "^std::__[[:alnum:]]+::function<.+>$", stl_summary_flags, true);972 973  static constexpr const char *const libcxx_std_coroutine_handle_regex =974      "^std::__[[:alnum:]]+::coroutine_handle<.+>$";975  AddCXXSynthetic(976      cpp_category_sp,977      lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator,978      "coroutine_handle synthetic children", libcxx_std_coroutine_handle_regex,979      stl_deref_flags, true);980 981  stl_summary_flags.SetDontShowChildren(false);982  stl_summary_flags.SetSkipPointers(false);983  AddCXXSummary(cpp_category_sp,984                lldb_private::formatters::ContainerSizeSummaryProvider,985                "libc++ std::bitset summary provider",986                "^std::__[[:alnum:]]+::bitset<.+>$", stl_summary_flags, true);987  AddCXXSummary(cpp_category_sp,988                lldb_private::formatters::ContainerSizeSummaryProvider,989                "libc++ std::vector summary provider",990                "^std::__[[:alnum:]]+::vector<.+>$", stl_summary_flags, true);991  AddCXXSummary(cpp_category_sp,992                lldb_private::formatters::ContainerSizeSummaryProvider,993                "libc++ std::valarray summary provider",994                "^std::__[[:alnum:]]+::valarray<.+>$", stl_summary_flags, true);995  AddCXXSummary(cpp_category_sp,996                lldb_private::formatters::LibcxxStdSliceArraySummaryProvider,997                "libc++ std::slice_array summary provider",998                "^std::__[[:alnum:]]+::slice_array<.+>$", stl_summary_flags,999                true);1000  AddCXXSummary(cpp_category_sp,1001                lldb_private::formatters::ContainerSizeSummaryProvider,1002                "libc++ summary provider for the valarray proxy arrays",1003                "^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$",1004                stl_summary_flags, true);1005  AddCXXSummary(1006      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,1007      "libc++ std::list summary provider",1008      "^std::__[[:alnum:]]+::forward_list<.+>$", stl_summary_flags, true);1009  AddCXXSummary(1010      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,1011      "libc++ std::list summary provider",1012      // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>$"1013      // so that it does not clash with: "^std::(__cxx11::)?list<.+>$"1014      "^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"1015      "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>$",1016      stl_summary_flags, true);1017  AddCXXSummary(cpp_category_sp,1018                lldb_private::formatters::ContainerSizeSummaryProvider,1019                "libc++ std::map summary provider",1020                "^std::__[[:alnum:]]+::map<.+>$", stl_summary_flags, true);1021  AddCXXSummary(cpp_category_sp,1022                lldb_private::formatters::ContainerSizeSummaryProvider,1023                "libc++ std::deque summary provider",1024                "^std::__[[:alnum:]]+::deque<.+>$", stl_summary_flags, true);1025  AddCXXSummary(cpp_category_sp,1026                lldb_private::formatters::ContainerSizeSummaryProvider,1027                "libc++ std::queue summary provider",1028                "^std::__[[:alnum:]]+::queue<.+>$", stl_summary_flags, true);1029  AddCXXSummary(cpp_category_sp,1030                lldb_private::formatters::ContainerSizeSummaryProvider,1031                "libc++ std::set summary provider",1032                "^std::__[[:alnum:]]+::set<.+>$", stl_summary_flags, true);1033  AddCXXSummary(cpp_category_sp,1034                lldb_private::formatters::ContainerSizeSummaryProvider,1035                "libc++ std::multiset summary provider",1036                "^std::__[[:alnum:]]+::multiset<.+>$", stl_summary_flags, true);1037  AddCXXSummary(cpp_category_sp,1038                lldb_private::formatters::ContainerSizeSummaryProvider,1039                "libc++ std::multimap summary provider",1040                "^std::__[[:alnum:]]+::multimap<.+>$", stl_summary_flags, true);1041  AddCXXSummary(cpp_category_sp,1042                lldb_private::formatters::ContainerSizeSummaryProvider,1043                "libc++ std::unordered containers summary provider",1044                "^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$",1045                stl_summary_flags, true);1046  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1047                "libc++ std::tuple summary provider",1048                "^std::__[[:alnum:]]+::tuple<.*>$", stl_summary_flags, true);1049  AddCXXSummary(cpp_category_sp,1050                lldb_private::formatters::LibCxxAtomicSummaryProvider,1051                "libc++ std::atomic summary provider",1052                "^std::__[[:alnum:]]+::atomic<.+>$", stl_summary_flags, true);1053  AddCXXSummary(cpp_category_sp,1054                lldb_private::formatters::GenericOptionalSummaryProvider,1055                "libc++ std::optional summary provider",1056                "^std::__[[:alnum:]]+::optional<.+>$", stl_summary_flags, true);1057  AddCXXSummary(cpp_category_sp,1058                lldb_private::formatters::LibcxxVariantSummaryProvider,1059                "libc++ std::variant summary provider",1060                "^std::__[[:alnum:]]+::variant<.+>$", stl_summary_flags, true);1061  AddCXXSummary(cpp_category_sp,1062                lldb_private::formatters::ContainerSizeSummaryProvider,1063                "libc++ std::span summary provider",1064                "^std::__[[:alnum:]]+::span<.+>$", stl_summary_flags, true);1065 1066  stl_summary_flags.SetSkipPointers(true);1067 1068  AddCXXSummary(cpp_category_sp,1069                lldb_private::formatters::LibcxxSmartPointerSummaryProvider,1070                "libc++ std::shared_ptr summary provider",1071                "^std::__[[:alnum:]]+::shared_ptr<.+>$", stl_summary_flags,1072                true);1073  AddCXXSummary(cpp_category_sp,1074                lldb_private::formatters::LibcxxSmartPointerSummaryProvider,1075                "libc++ std::weak_ptr summary provider",1076                "^std::__[[:alnum:]]+::weak_ptr<.+>$", stl_summary_flags, true);1077  AddCXXSummary(cpp_category_sp,1078                lldb_private::formatters::LibcxxUniquePointerSummaryProvider,1079                "libc++ std::unique_ptr summary provider",1080                libcxx_std_unique_ptr_regex, stl_summary_flags, true);1081 1082  AddCXXSummary(cpp_category_sp,1083                lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,1084                "libc++ std::coroutine_handle summary provider",1085                libcxx_std_coroutine_handle_regex, stl_summary_flags, true);1086 1087  AddCXXSynthetic(1088      cpp_category_sp,1089      lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator,1090      "std::vector iterator synthetic children",1091      "^std::__[[:alnum:]]+::__wrap_iter<.+>$", stl_synth_flags, true);1092 1093  AddCXXSynthetic(1094      cpp_category_sp,1095      lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,1096      "std::map iterator synthetic children",1097      "^std::__[[:alnum:]]+::__map_(const_)?iterator<.+>$", stl_synth_flags,1098      true);1099 1100  AddCXXSynthetic(cpp_category_sp,1101                  lldb_private::formatters::1102                      LibCxxUnorderedMapIteratorSyntheticFrontEndCreator,1103                  "std::unordered_map iterator synthetic children",1104                  "^std::__[[:alnum:]]+::__hash_map_(const_)?iterator<.+>$",1105                  stl_synth_flags, true);1106  // Chrono duration typedefs1107  cpp_category_sp->AddTypeSummary(1108      "^std::__[[:alnum:]]+::chrono::nanoseconds", eFormatterMatchRegex,1109      TypeSummaryImplSP(new StringSummaryFormat(1110          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ns")));1111  cpp_category_sp->AddTypeSummary(1112      "^std::__[[:alnum:]]+::chrono::microseconds", eFormatterMatchRegex,1113      TypeSummaryImplSP(new StringSummaryFormat(1114          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} µs")));1115  cpp_category_sp->AddTypeSummary(1116      "^std::__[[:alnum:]]+::chrono::milliseconds", eFormatterMatchRegex,1117      TypeSummaryImplSP(new StringSummaryFormat(1118          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ms")));1119  cpp_category_sp->AddTypeSummary(1120      "^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,1121      TypeSummaryImplSP(new StringSummaryFormat(1122          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));1123  cpp_category_sp->AddTypeSummary(1124      "^std::__[[:alnum:]]+::chrono::minutes", eFormatterMatchRegex,1125      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1126                                                    eTypeOptionHideValue,1127                                                "${var.__rep_} min")));1128  cpp_category_sp->AddTypeSummary(1129      "^std::__[[:alnum:]]+::chrono::hours", eFormatterMatchRegex,1130      TypeSummaryImplSP(new StringSummaryFormat(1131          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} h")));1132 1133  cpp_category_sp->AddTypeSummary(1134      "^std::__[[:alnum:]]+::chrono::days", eFormatterMatchRegex,1135      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1136                                                    eTypeOptionHideValue,1137                                                "${var.__rep_} days")));1138  cpp_category_sp->AddTypeSummary(1139      "^std::__[[:alnum:]]+::chrono::weeks", eFormatterMatchRegex,1140      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1141                                                    eTypeOptionHideValue,1142                                                "${var.__rep_} weeks")));1143  cpp_category_sp->AddTypeSummary(1144      "^std::__[[:alnum:]]+::chrono::months", eFormatterMatchRegex,1145      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1146                                                    eTypeOptionHideValue,1147                                                "${var.__rep_} months")));1148  cpp_category_sp->AddTypeSummary(1149      "^std::__[[:alnum:]]+::chrono::years", eFormatterMatchRegex,1150      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1151                                                    eTypeOptionHideValue,1152                                                "${var.__rep_} years")));1153  cpp_category_sp->AddTypeSummary(1154      "^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,1155      TypeSummaryImplSP(new StringSummaryFormat(1156          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));1157 1158  // Chrono time point types1159 1160  AddCXXSummary(cpp_category_sp,1161                lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider,1162                "libc++ std::chrono::sys_seconds summary provider",1163                "^std::__[[:alnum:]]+::chrono::time_point<"1164                "std::__[[:alnum:]]+::chrono::system_clock, "1165                "std::__[[:alnum:]]+::chrono::duration<.*, "1166                "std::__[[:alnum:]]+::ratio<1, 1> "1167                "> >$",1168                eTypeOptionHideChildren | eTypeOptionHideValue |1169                    eTypeOptionCascade,1170                true);1171  AddCXXSummary(cpp_category_sp,1172                lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider,1173                "libc++ std::chrono::sys_seconds summary provider",1174                "^std::__[[:alnum:]]+::chrono::time_point<"1175                "std::__[[:alnum:]]+::chrono::system_clock, "1176                "std::__[[:alnum:]]+::chrono::duration<int, "1177                "std::__[[:alnum:]]+::ratio<86400, 1> "1178                "> >$",1179                eTypeOptionHideChildren | eTypeOptionHideValue |1180                    eTypeOptionCascade,1181                true);1182 1183  AddCXXSummary(1184      cpp_category_sp,1185      lldb_private::formatters::LibcxxChronoLocalSecondsSummaryProvider,1186      "libc++ std::chrono::local_seconds summary provider",1187      "^std::__[[:alnum:]]+::chrono::time_point<"1188      "std::__[[:alnum:]]+::chrono::local_t, "1189      "std::__[[:alnum:]]+::chrono::duration<.*, "1190      "std::__[[:alnum:]]+::ratio<1, 1> "1191      "> >$",1192      eTypeOptionHideChildren | eTypeOptionHideValue | eTypeOptionCascade,1193      true);1194  AddCXXSummary(cpp_category_sp,1195                lldb_private::formatters::LibcxxChronoLocalDaysSummaryProvider,1196                "libc++ std::chrono::local_seconds summary provider",1197                "^std::__[[:alnum:]]+::chrono::time_point<"1198                "std::__[[:alnum:]]+::chrono::local_t, "1199                "std::__[[:alnum:]]+::chrono::duration<int, "1200                "std::__[[:alnum:]]+::ratio<86400, 1> "1201                "> >$",1202                eTypeOptionHideChildren | eTypeOptionHideValue |1203                    eTypeOptionCascade,1204                true);1205 1206  // Chrono calendar types1207 1208  cpp_category_sp->AddTypeSummary(1209      "^std::__[[:alnum:]]+::chrono::day$", eFormatterMatchRegex,1210      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1211                                                    eTypeOptionHideValue,1212                                                "day=${var.__d_%u}")));1213 1214  AddCXXSummary(cpp_category_sp,1215                lldb_private::formatters::LibcxxChronoMonthSummaryProvider,1216                "libc++ std::chrono::month summary provider",1217                "^std::__[[:alnum:]]+::chrono::month$",1218                eTypeOptionHideChildren | eTypeOptionHideValue, true);1219 1220  cpp_category_sp->AddTypeSummary(1221      "^std::__[[:alnum:]]+::chrono::year$", eFormatterMatchRegex,1222      TypeSummaryImplSP(new StringSummaryFormat(1223          eTypeOptionHideChildren | eTypeOptionHideValue, "year=${var.__y_}")));1224 1225  AddCXXSummary(cpp_category_sp,1226                lldb_private::formatters::LibcxxChronoWeekdaySummaryProvider,1227                "libc++ std::chrono::weekday summary provider",1228                "^std::__[[:alnum:]]+::chrono::weekday$",1229                eTypeOptionHideChildren | eTypeOptionHideValue, true);1230 1231  cpp_category_sp->AddTypeSummary(1232      "^std::__[[:alnum:]]+::chrono::weekday_indexed$", eFormatterMatchRegex,1233      TypeSummaryImplSP(new StringSummaryFormat(1234          eTypeOptionHideChildren | eTypeOptionHideValue,1235          "${var.__wd_} index=${var.__idx_%u}")));1236 1237  cpp_category_sp->AddTypeSummary(1238      "^std::__[[:alnum:]]+::chrono::weekday_last$", eFormatterMatchRegex,1239      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1240                                                    eTypeOptionHideValue,1241                                                "${var.__wd_} index=last")));1242  cpp_category_sp->AddTypeSummary(1243      "^std::__[[:alnum:]]+::chrono::month_day$", eFormatterMatchRegex,1244      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1245                                                    eTypeOptionHideValue,1246                                                "${var.__m_} ${var.__d_}")));1247  cpp_category_sp->AddTypeSummary(1248      "^std::__[[:alnum:]]+::chrono::month_day_last$", eFormatterMatchRegex,1249      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1250                                                    eTypeOptionHideValue,1251                                                "${var.__m_} day=last")));1252 1253  cpp_category_sp->AddTypeSummary(1254      "^std::__[[:alnum:]]+::chrono::month_weekday$", eFormatterMatchRegex,1255      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1256                                                    eTypeOptionHideValue,1257                                                "${var.__m_} ${var.__wdi_}")));1258 1259  cpp_category_sp->AddTypeSummary(1260      "^std::__[[:alnum:]]+::chrono::month_weekday_last$", eFormatterMatchRegex,1261      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1262                                                    eTypeOptionHideValue,1263                                                "${var.__m_} ${var.__wdl_}")));1264 1265  cpp_category_sp->AddTypeSummary(1266      "^std::__[[:alnum:]]+::chrono::year_month$", eFormatterMatchRegex,1267      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1268                                                    eTypeOptionHideValue,1269                                                "${var.__y_} ${var.__m_}")));1270 1271  AddCXXSummary(1272      cpp_category_sp,1273      lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider,1274      "libc++ std::chrono::year_month_day summary provider",1275      "^std::__[[:alnum:]]+::chrono::year_month_day$",1276      eTypeOptionHideChildren | eTypeOptionHideValue, true);1277 1278  cpp_category_sp->AddTypeSummary(1279      "^std::__[[:alnum:]]+::chrono::year_month_day_last$",1280      eFormatterMatchRegex,1281      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |1282                                                    eTypeOptionHideValue,1283                                                "${var.__y_} ${var.__mdl_}")));1284 1285  cpp_category_sp->AddTypeSummary(1286      "^std::__[[:alnum:]]+::chrono::year_month_weekday$", eFormatterMatchRegex,1287      TypeSummaryImplSP(new StringSummaryFormat(1288          eTypeOptionHideChildren | eTypeOptionHideValue,1289          "${var.__y_} ${var.__m_} ${var.__wdi_}")));1290 1291  cpp_category_sp->AddTypeSummary(1292      "^std::__[[:alnum:]]+::chrono::year_month_weekday_last$",1293      eFormatterMatchRegex,1294      TypeSummaryImplSP(new StringSummaryFormat(1295          eTypeOptionHideChildren | eTypeOptionHideValue,1296          "${var.__y_} ${var.__m_} ${var.__wdl_}")));1297}1298 1299static void RegisterStdStringSummaryProvider(1300    const lldb::TypeCategoryImplSP &category_sp, llvm::StringRef string_ty,1301    llvm::StringRef char_ty, lldb::TypeSummaryImplSP summary_sp) {1302  auto makeSpecifier = [](llvm::StringRef name) {1303    return std::make_shared<lldb_private::TypeNameSpecifierImpl>(1304        name, eFormatterMatchExact);1305  };1306 1307  category_sp->AddTypeSummary(makeSpecifier(string_ty), summary_sp);1308 1309  category_sp->AddTypeSummary(1310      makeSpecifier(llvm::formatv("std::basic_string<{}>", char_ty).str()),1311      summary_sp);1312 1313  category_sp->AddTypeSummary(1314      std::make_shared<lldb_private::TypeNameSpecifierImpl>(1315          llvm::formatv("^std::basic_string<{0}, ?std::char_traits<{0}>,.*>$",1316                        char_ty)1317              .str(),1318          eFormatterMatchRegex),1319      summary_sp);1320}1321 1322static void RegisterStdStringViewSummaryProvider(1323    const lldb::TypeCategoryImplSP &category_sp, llvm::StringRef string_ty,1324    llvm::StringRef char_ty, lldb::TypeSummaryImplSP summary_sp) {1325  // std::string_view1326  category_sp->AddTypeSummary(1327      std::make_shared<lldb_private::TypeNameSpecifierImpl>(1328          string_ty, eFormatterMatchExact),1329      summary_sp);1330 1331  // std::basic_string_view<char, std::char_traits<char>>1332  // NativePDB has spaces at different positions compared to PDB and DWARF, so1333  // use a regex and make them optional.1334  category_sp->AddTypeSummary(1335      std::make_shared<lldb_private::TypeNameSpecifierImpl>(1336          llvm::formatv(1337              "^std::basic_string_view<{0}, ?std::char_traits<{0}> ?>$",1338              char_ty)1339              .str(),1340          eFormatterMatchRegex),1341      summary_sp);1342}1343 1344static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {1345  if (!cpp_category_sp)1346    return;1347 1348  TypeSummaryImpl::Flags stl_summary_flags;1349  stl_summary_flags.SetCascades(true)1350      .SetSkipPointers(false)1351      .SetSkipReferences(false)1352      .SetDontShowChildren(true)1353      .SetDontShowValue(false)1354      .SetShowMembersOneLiner(false)1355      .SetHideItemNames(false);1356 1357  lldb::TypeSummaryImplSP string_summary_sp(new CXXFunctionSummaryFormat(1358      stl_summary_flags, LibStdcppStringSummaryProvider,1359      "libstdc++ std::(w)string summary provider"));1360  cpp_category_sp->AddTypeSummary("std::__cxx11::string", eFormatterMatchExact,1361                                  string_summary_sp);1362  cpp_category_sp->AddTypeSummary(1363      "^std::__cxx11::basic_string<char, std::char_traits<char>,.*>$",1364      eFormatterMatchRegex, string_summary_sp);1365  cpp_category_sp->AddTypeSummary("^std::__cxx11::basic_string<unsigned char, "1366                                  "std::char_traits<unsigned char>,.*>$",1367                                  eFormatterMatchRegex, string_summary_sp);1368 1369  cpp_category_sp->AddTypeSummary("std::__cxx11::wstring", eFormatterMatchExact,1370                                  string_summary_sp);1371  cpp_category_sp->AddTypeSummary(1372      "^std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>,.*>$",1373      eFormatterMatchRegex, string_summary_sp);1374 1375  SyntheticChildren::Flags stl_synth_flags;1376  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(1377      false);1378  SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;1379  stl_deref_flags.SetFrontEndWantsDereference();1380 1381  cpp_category_sp->AddTypeSynthetic(1382      "^std::__debug::vector<.+>(( )?&)?$", eFormatterMatchRegex,1383      SyntheticChildrenSP(new ScriptedSyntheticChildren(1384          stl_synth_flags,1385          "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));1386  cpp_category_sp->AddTypeSynthetic(1387      "^std::__debug::map<.+> >(( )?&)?$", eFormatterMatchRegex,1388      SyntheticChildrenSP(new ScriptedSyntheticChildren(1389          stl_synth_flags,1390          "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));1391  cpp_category_sp->AddTypeSynthetic(1392      "^std::__debug::deque<.+>(( )?&)?$", eFormatterMatchRegex,1393      SyntheticChildrenSP(new ScriptedSyntheticChildren(1394          stl_deref_flags,1395          "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider")));1396  cpp_category_sp->AddTypeSynthetic(1397      "^std::__debug::set<.+> >(( )?&)?$", eFormatterMatchRegex,1398      SyntheticChildrenSP(new ScriptedSyntheticChildren(1399          stl_deref_flags,1400          "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));1401  cpp_category_sp->AddTypeSynthetic(1402      "^std::__debug::multimap<.+> >(( )?&)?$", eFormatterMatchRegex,1403      SyntheticChildrenSP(new ScriptedSyntheticChildren(1404          stl_deref_flags,1405          "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));1406  cpp_category_sp->AddTypeSynthetic(1407      "^std::__debug::multiset<.+> >(( )?&)?$", eFormatterMatchRegex,1408      SyntheticChildrenSP(new ScriptedSyntheticChildren(1409          stl_deref_flags,1410          "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));1411  cpp_category_sp->AddTypeSynthetic(1412      "^std::__debug::unordered_(multi)?(map|set)<.+> >$", eFormatterMatchRegex,1413      SyntheticChildrenSP(new ScriptedSyntheticChildren(1414          stl_deref_flags,1415          "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));1416  cpp_category_sp->AddTypeSynthetic(1417      "^std::__(debug|cxx11)::list<.+>(( )?&)?$", eFormatterMatchRegex,1418      SyntheticChildrenSP(new ScriptedSyntheticChildren(1419          stl_deref_flags,1420          "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));1421  cpp_category_sp->AddTypeSynthetic(1422      "^std::__(debug|cxx11)::forward_list<.+>(( )?&)?$", eFormatterMatchRegex,1423      SyntheticChildrenSP(new ScriptedSyntheticChildren(1424          stl_synth_flags,1425          "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));1426 1427  stl_summary_flags.SetDontShowChildren(false);1428  stl_summary_flags.SetSkipPointers(false);1429 1430  AddCXXSummary(1431      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,1432      "libstdc++ std::bitset summary provider",1433      "^std::(__debug::)?bitset<.+>(( )?&)?$", stl_summary_flags, true);1434 1435  AddCXXSummary(cpp_category_sp,1436                lldb_private::formatters::ContainerSizeSummaryProvider,1437                "libstdc++ std::__debug::vector summary provider",1438                "^std::__debug::vector<.+>(( )?&)?$", stl_summary_flags, true);1439 1440  AddCXXSummary(cpp_category_sp,1441                lldb_private::formatters::ContainerSizeSummaryProvider,1442                "libstdc++ debug std::map summary provider",1443                "^std::__debug::map<.+> >(( )?&)?$", stl_summary_flags, true);1444 1445  AddCXXSummary(cpp_category_sp,1446                lldb_private::formatters::ContainerSizeSummaryProvider,1447                "libstdc++ debug std::set summary provider",1448                "^std::__debug::set<.+> >(( )?&)?$", stl_summary_flags, true);1449 1450  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1451                "libstdc++ debug std::deque summary provider",1452                "^std::__debug::deque<.+>(( )?&)?$", stl_summary_flags, true);1453 1454  AddCXXSummary(1455      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,1456      "libstdc++ debug std::multimap summary provider",1457      "^std::__debug::multimap<.+> >(( )?&)?$", stl_summary_flags, true);1458 1459  AddCXXSummary(1460      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,1461      "libstdc++ debug std::multiset summary provider",1462      "^std::__debug::multiset<.+> >(( )?&)?$", stl_summary_flags, true);1463 1464  AddCXXSummary(cpp_category_sp,1465                lldb_private::formatters::ContainerSizeSummaryProvider,1466                "libstdc++ debug std unordered container summary provider",1467                "^std::__debug::unordered_(multi)?(map|set)<.+> >$",1468                stl_summary_flags, true);1469 1470  AddCXXSummary(1471      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,1472      "libstdc++ debug std::list summary provider",1473      "^std::__(debug|cxx11)::list<.+>(( )?&)?$", stl_summary_flags, true);1474 1475  cpp_category_sp->AddTypeSummary(1476      "^std::__(debug|cxx11)::forward_list<.+>(( )?&)?$", eFormatterMatchRegex,1477      TypeSummaryImplSP(new ScriptSummaryFormat(1478          stl_summary_flags,1479          "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));1480 1481  AddCXXSynthetic(1482      cpp_category_sp,1483      lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator,1484      "std::vector iterator synthetic children",1485      "^__gnu_cxx::__normal_iterator<.+>$", stl_synth_flags, true);1486 1487  AddCXXSynthetic(1488      cpp_category_sp,1489      lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator,1490      "std::map iterator synthetic children",1491      "^std::_Rb_tree_(const_)?iterator<.+>$", stl_synth_flags, true);1492 1493  AddCXXSynthetic(1494      cpp_category_sp,1495      lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,1496      "std::unique_ptr synthetic children", "^std::unique_ptr<.+>(( )?&)?$",1497      stl_synth_flags, true);1498 1499  static constexpr const char *const libstdcpp_std_coroutine_handle_regex =1500      "^std::coroutine_handle<.+>(( )?&)?$";1501  AddCXXSynthetic(1502      cpp_category_sp,1503      lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator,1504      "std::coroutine_handle synthetic children",1505      libstdcpp_std_coroutine_handle_regex, stl_deref_flags, true);1506 1507  AddCXXSynthetic(1508      cpp_category_sp,1509      lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator,1510      "std::bitset synthetic child", "^std::(__debug::)?bitset<.+>(( )?&)?$",1511      stl_deref_flags, true);1512 1513  AddCXXSummary(cpp_category_sp,1514                lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,1515                "libstdc++ std::coroutine_handle summary provider",1516                libstdcpp_std_coroutine_handle_regex, stl_summary_flags, true);1517}1518 1519static lldb_private::SyntheticChildrenFrontEnd *1520GenericSmartPointerSyntheticFrontEndCreator(CXXSyntheticChildren *children,1521                                            lldb::ValueObjectSP valobj_sp) {1522  if (!valobj_sp)1523    return nullptr;1524 1525  if (IsMsvcStlSmartPointer(*valobj_sp))1526    return MsvcStlSmartPointerSyntheticFrontEndCreator(valobj_sp);1527  return LibStdcppSharedPtrSyntheticFrontEndCreator(children, valobj_sp);1528}1529 1530static bool1531GenericSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream,1532                                   const TypeSummaryOptions &options) {1533  if (IsMsvcStlSmartPointer(valobj))1534    return MsvcStlSmartPointerSummaryProvider(valobj, stream, options);1535  return LibStdcppSmartPointerSummaryProvider(valobj, stream, options);1536}1537 1538static lldb_private::SyntheticChildrenFrontEnd *1539GenericUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *children,1540                                         lldb::ValueObjectSP valobj_sp) {1541  if (!valobj_sp)1542    return nullptr;1543 1544  if (IsMsvcStlUniquePtr(*valobj_sp))1545    return MsvcStlUniquePtrSyntheticFrontEndCreator(valobj_sp);1546  return LibStdcppUniquePtrSyntheticFrontEndCreator(children, valobj_sp);1547}1548 1549static bool GenericUniquePtrSummaryProvider(ValueObject &valobj, Stream &stream,1550                                            const TypeSummaryOptions &options) {1551  if (IsMsvcStlUniquePtr(valobj))1552    return MsvcStlUniquePtrSummaryProvider(valobj, stream, options);1553  return LibStdcppUniquePointerSummaryProvider(valobj, stream, options);1554}1555 1556static SyntheticChildrenFrontEnd *1557GenericTupleSyntheticFrontEndCreator(CXXSyntheticChildren *children,1558                                     lldb::ValueObjectSP valobj_sp) {1559  if (!valobj_sp)1560    return nullptr;1561 1562  if (IsMsvcStlTuple(*valobj_sp))1563    return MsvcStlTupleSyntheticFrontEndCreator(children, valobj_sp);1564  return LibStdcppTupleSyntheticFrontEndCreator(children, valobj_sp);1565}1566 1567static SyntheticChildrenFrontEnd *1568GenericVectorSyntheticFrontEndCreator(CXXSyntheticChildren *children,1569                                      lldb::ValueObjectSP valobj_sp) {1570  if (!valobj_sp)1571    return nullptr;1572 1573  // checks for vector<T> and vector<bool>1574  if (auto *msvc = MsvcStlVectorSyntheticFrontEndCreator(valobj_sp))1575    return msvc;1576 1577  return new ScriptedSyntheticChildren::FrontEnd(1578      "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider", *valobj_sp);1579}1580 1581static SyntheticChildrenFrontEnd *1582GenericListSyntheticFrontEndCreator(CXXSyntheticChildren *children,1583                                    lldb::ValueObjectSP valobj_sp) {1584  if (!valobj_sp)1585    return nullptr;1586 1587  if (IsMsvcStlList(*valobj_sp))1588    return MsvcStlListSyntheticFrontEndCreator(children, valobj_sp);1589  return new ScriptedSyntheticChildren::FrontEnd(1590      "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider", *valobj_sp);1591}1592 1593static SyntheticChildrenFrontEnd *1594GenericForwardListSyntheticFrontEndCreator(CXXSyntheticChildren *children,1595                                           lldb::ValueObjectSP valobj_sp) {1596  if (!valobj_sp)1597    return nullptr;1598 1599  if (IsMsvcStlList(*valobj_sp))1600    return MsvcStlForwardListSyntheticFrontEndCreator(children, valobj_sp);1601  return new ScriptedSyntheticChildren::FrontEnd(1602      "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider",1603      *valobj_sp);1604}1605 1606static SyntheticChildrenFrontEnd *1607GenericOptionalSyntheticFrontEndCreator(CXXSyntheticChildren *children,1608                                        lldb::ValueObjectSP valobj_sp) {1609  if (!valobj_sp)1610    return nullptr;1611 1612  if (IsMsvcStlOptional(*valobj_sp))1613    return MsvcStlOptionalSyntheticFrontEndCreator(children, valobj_sp);1614  return LibStdcppOptionalSyntheticFrontEndCreator(children, valobj_sp);1615}1616 1617static SyntheticChildrenFrontEnd *1618GenericVariantSyntheticFrontEndCreator(CXXSyntheticChildren *children,1619                                       lldb::ValueObjectSP valobj_sp) {1620  if (!valobj_sp)1621    return nullptr;1622 1623  if (IsMsvcStlVariant(*valobj_sp))1624    return MsvcStlVariantSyntheticFrontEndCreator(children, valobj_sp);1625  return new ScriptedSyntheticChildren::FrontEnd(1626      "lldb.formatters.cpp.gnu_libstdcpp.VariantSynthProvider", *valobj_sp);1627}1628 1629static bool GenericVariantSummaryProvider(ValueObject &valobj, Stream &stream,1630                                          const TypeSummaryOptions &options) {1631  if (IsMsvcStlVariant(valobj))1632    return MsvcStlVariantSummaryProvider(valobj, stream, options);1633  return LibStdcppVariantSummaryProvider(valobj, stream, options);1634}1635 1636static SyntheticChildrenFrontEnd *1637GenericUnorderedSyntheticFrontEndCreator(CXXSyntheticChildren *children,1638                                         ValueObjectSP valobj_sp) {1639  if (!valobj_sp)1640    return nullptr;1641 1642  if (IsMsvcStlUnordered(*valobj_sp))1643    return MsvcStlUnorderedSyntheticFrontEndCreator(children, valobj_sp);1644  return new ScriptedSyntheticChildren::FrontEnd(1645      "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider",1646      *valobj_sp);1647}1648 1649static SyntheticChildrenFrontEnd *1650GenericMapLikeSyntheticFrontEndCreator(CXXSyntheticChildren *children,1651                                       ValueObjectSP valobj_sp) {1652  if (!valobj_sp)1653    return nullptr;1654 1655  if (IsMsvcStlMapLike(*valobj_sp))1656    return MsvcStlMapLikeSyntheticFrontEndCreator(valobj_sp);1657  return new ScriptedSyntheticChildren::FrontEnd(1658      "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider", *valobj_sp);1659}1660 1661static SyntheticChildrenFrontEnd *1662GenericDequeSyntheticFrontEndCreator(CXXSyntheticChildren *children,1663                                     ValueObjectSP valobj_sp) {1664  if (!valobj_sp)1665    return nullptr;1666 1667  if (IsMsvcStlDeque(*valobj_sp))1668    return MsvcStlDequeSyntheticFrontEndCreator(children, valobj_sp);1669  return new ScriptedSyntheticChildren::FrontEnd(1670      "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider", *valobj_sp);1671}1672 1673/// Load formatters that are formatting types from more than one STL1674static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {1675  if (!cpp_category_sp)1676    return;1677 1678  TypeSummaryImpl::Flags stl_summary_flags;1679  stl_summary_flags.SetCascades(true)1680      .SetSkipPointers(false)1681      .SetSkipReferences(false)1682      .SetDontShowChildren(true)1683      .SetDontShowValue(false)1684      .SetShowMembersOneLiner(false)1685      .SetHideItemNames(false);1686  SyntheticChildren::Flags stl_synth_flags;1687  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(1688      false);1689 1690  using StringElementType = StringPrinter::StringElementType;1691 1692  RegisterStdStringSummaryProvider(1693      cpp_category_sp, "std::string", "char",1694      std::make_shared<CXXFunctionSummaryFormat>(1695          stl_summary_flags,1696          [](ValueObject &valobj, Stream &stream,1697             const TypeSummaryOptions &options) {1698            if (IsMsvcStlStringType(valobj))1699              return MsvcStlStringSummaryProvider<StringElementType::ASCII>(1700                  valobj, stream, options);1701            return LibStdcppStringSummaryProvider(valobj, stream, options);1702          },1703          "MSVC STL/libstdc++ std::string summary provider"));1704  RegisterStdStringSummaryProvider(1705      cpp_category_sp, "std::wstring", "wchar_t",1706      std::make_shared<CXXFunctionSummaryFormat>(1707          stl_summary_flags,1708          [](ValueObject &valobj, Stream &stream,1709             const TypeSummaryOptions &options) {1710            if (IsMsvcStlStringType(valobj))1711              return MsvcStlWStringSummaryProvider(valobj, stream, options);1712            return LibStdcppStringSummaryProvider(valobj, stream, options);1713          },1714          "MSVC STL/libstdc++ std::wstring summary provider"));1715 1716  // NOTE: it is loaded as a common formatter because the libc++ version is not1717  // in the `__1` namespace, hence we need to dispatch based on the class1718  // layout.1719  AddCXXSynthetic(cpp_category_sp,1720                  GenericInitializerListSyntheticFrontEndCreator,1721                  "std::initializer_list synthetic children",1722                  "^std::initializer_list<.+>$", stl_synth_flags, true);1723 1724  stl_summary_flags.SetDontShowChildren(false);1725  stl_summary_flags.SetSkipPointers(false);1726 1727  AddCXXSynthetic(cpp_category_sp, GenericSmartPointerSyntheticFrontEndCreator,1728                  "std::shared_ptr synthetic children",1729                  "^std::shared_ptr<.+>(( )?&)?$", stl_synth_flags, true);1730  AddCXXSynthetic(cpp_category_sp, GenericSmartPointerSyntheticFrontEndCreator,1731                  "std::weak_ptr synthetic children",1732                  "^std::weak_ptr<.+>(( )?&)?$", stl_synth_flags, true);1733  AddCXXSynthetic(cpp_category_sp, GenericUniquePtrSyntheticFrontEndCreator,1734                  "std::unique_ptr synthetic children",1735                  "^std::unique_ptr<.+>(( )?&)?$", stl_synth_flags, true);1736  AddCXXSynthetic(cpp_category_sp, GenericTupleSyntheticFrontEndCreator,1737                  "std::tuple synthetic children", "^std::tuple<.*>(( )?&)?$",1738                  stl_synth_flags, true);1739  AddCXXSynthetic(cpp_category_sp, GenericListSyntheticFrontEndCreator,1740                  "std::list synthetic children", "^std::list<.+>(( )?&)?$",1741                  stl_synth_flags, true);1742  AddCXXSynthetic(cpp_category_sp, GenericForwardListSyntheticFrontEndCreator,1743                  "std::forward_list synthetic children",1744                  "^std::forward_list<.+>(( )?&)?$", stl_synth_flags, true);1745  AddCXXSynthetic(cpp_category_sp, GenericVariantSyntheticFrontEndCreator,1746                  "std::variant synthetic children", "^std::variant<.*>$",1747                  stl_synth_flags, true);1748  AddCXXSynthetic(cpp_category_sp, GenericUnorderedSyntheticFrontEndCreator,1749                  "std::unordered container synthetic children",1750                  "^std::unordered_(multi)?(map|set)<.+> ?>$", stl_synth_flags,1751                  true);1752 1753  SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;1754  stl_deref_flags.SetFrontEndWantsDereference();1755  AddCXXSynthetic(cpp_category_sp, GenericOptionalSyntheticFrontEndCreator,1756                  "std::optional synthetic children",1757                  "^std::optional<.+>(( )?&)?$", stl_deref_flags, true);1758  AddCXXSynthetic(cpp_category_sp, GenericDequeSyntheticFrontEndCreator,1759                  "std::deque container synthetic children",1760                  "^std::deque<.+>(( )?&)?$", stl_deref_flags, true);1761 1762  AddCXXSynthetic(cpp_category_sp, GenericMapLikeSyntheticFrontEndCreator,1763                  "std::(multi)?map/set synthetic children",1764                  "^std::(multi)?(map|set)<.+>(( )?&)?$", stl_synth_flags,1765                  true);1766 1767  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1768                "std::initializer_list summary provider",1769                "^std::initializer_list<.+>$", stl_summary_flags, true);1770  AddCXXSummary(cpp_category_sp, GenericSmartPointerSummaryProvider,1771                "MSVC STL/libstdc++ std::shared_ptr summary provider",1772                "^std::shared_ptr<.+>(( )?&)?$", stl_summary_flags, true);1773  AddCXXSummary(cpp_category_sp, GenericSmartPointerSummaryProvider,1774                "MSVC STL/libstdc++ std::weak_ptr summary provider",1775                "^std::weak_ptr<.+>(( )?&)?$", stl_summary_flags, true);1776  AddCXXSummary(cpp_category_sp, GenericUniquePtrSummaryProvider,1777                "MSVC STL/libstdc++ std::unique_ptr summary provider",1778                "^std::unique_ptr<.+>(( )?&)?$", stl_summary_flags, true);1779  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1780                "MSVC STL/libstdc++ std::tuple summary provider",1781                "^std::tuple<.*>(( )?&)?$", stl_summary_flags, true);1782  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1783                "MSVC/libstdc++ std::vector summary provider",1784                "^std::vector<.+>(( )?&)?$", stl_summary_flags, true);1785  AddCXXSynthetic(cpp_category_sp, GenericVectorSyntheticFrontEndCreator,1786                  "MSVC/libstdc++ std::vector synthetic provider",1787                  "^std::vector<.+>(( )?&)?$", stl_synth_flags, true);1788  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1789                "MSVC STL/libstdc++ std::list summary provider",1790                "^std::list<.+>(( )?&)?$", stl_summary_flags, true);1791  cpp_category_sp->AddTypeSummary(1792      "^std::forward_list<.+>(( )?&)?$", eFormatterMatchRegex,1793      TypeSummaryImplSP(new ScriptSummaryFormat(1794          stl_summary_flags,1795          "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));1796  AddCXXSummary(cpp_category_sp, GenericOptionalSummaryProvider,1797                "MSVC STL/libstd++ std::optional summary provider",1798                "^std::optional<.+>(( )?&)?$", stl_summary_flags, true);1799  AddCXXSummary(cpp_category_sp, GenericVariantSummaryProvider,1800                "MSVC STL/libstdc++ std::variant summary provider",1801                "^std::variant<.*>$", stl_summary_flags, true);1802  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1803                "MSVC STL/libstdc++ std unordered container summary provider",1804                "^std::unordered_(multi)?(map|set)<.+> ?>$", stl_summary_flags,1805                true);1806  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1807                "MSVC STL/libstdc++ std::(multi)?map/set summary provider",1808                "^std::(multi)?(map|set)<.+>(( )?&)?$", stl_summary_flags,1809                true);1810  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,1811                "MSVC STL/libstd++ std::deque summary provider",1812                "^std::deque<.+>(( )?&)?$", stl_summary_flags, true);1813}1814 1815static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {1816  if (!cpp_category_sp)1817    return;1818 1819  TypeSummaryImpl::Flags stl_summary_flags;1820  stl_summary_flags.SetCascades(true)1821      .SetSkipPointers(false)1822      .SetSkipReferences(false)1823      .SetDontShowChildren(true)1824      .SetDontShowValue(false)1825      .SetShowMembersOneLiner(false)1826      .SetHideItemNames(false);1827  SyntheticChildren::Flags stl_synth_flags;1828  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(1829      false);1830 1831  using StringElementType = StringPrinter::StringElementType;1832 1833  RegisterStdStringSummaryProvider(1834      cpp_category_sp, "std::u8string", "char8_t",1835      std::make_shared<CXXFunctionSummaryFormat>(1836          stl_summary_flags,1837          MsvcStlStringSummaryProvider<StringElementType::UTF8>,1838          "MSVC STL std::u8string summary provider"));1839  RegisterStdStringSummaryProvider(1840      cpp_category_sp, "std::u16string", "char16_t",1841      std::make_shared<CXXFunctionSummaryFormat>(1842          stl_summary_flags,1843          MsvcStlStringSummaryProvider<StringElementType::UTF16>,1844          "MSVC STL std::u16string summary provider"));1845  RegisterStdStringSummaryProvider(1846      cpp_category_sp, "std::u32string", "char32_t",1847      std::make_shared<CXXFunctionSummaryFormat>(1848          stl_summary_flags,1849          MsvcStlStringSummaryProvider<StringElementType::UTF32>,1850          "MSVC STL std::u32string summary provider"));1851 1852  RegisterStdStringViewSummaryProvider(1853      cpp_category_sp, "std::string_view", "char",1854      std::make_shared<CXXFunctionSummaryFormat>(1855          stl_summary_flags,1856          MsvcStlStringViewSummaryProvider<StringElementType::ASCII>,1857          "MSVC STL std::string_view summary provider"));1858  RegisterStdStringViewSummaryProvider(1859      cpp_category_sp, "std::u8string_view", "char8_t",1860      std::make_shared<CXXFunctionSummaryFormat>(1861          stl_summary_flags,1862          MsvcStlStringViewSummaryProvider<StringElementType::UTF8>,1863          "MSVC STL std::u8string_view summary provider"));1864  RegisterStdStringViewSummaryProvider(1865      cpp_category_sp, "std::u16string_view", "char16_t",1866      std::make_shared<CXXFunctionSummaryFormat>(1867          stl_summary_flags,1868          MsvcStlStringViewSummaryProvider<StringElementType::UTF16>,1869          "MSVC STL std::u16string_view summary provider"));1870  RegisterStdStringViewSummaryProvider(1871      cpp_category_sp, "std::u32string_view", "char32_t",1872      std::make_shared<CXXFunctionSummaryFormat>(1873          stl_summary_flags,1874          MsvcStlStringViewSummaryProvider<StringElementType::UTF32>,1875          "MSVC STL std::u32string_view summary provider"));1876  RegisterStdStringViewSummaryProvider(1877      cpp_category_sp, "std::wstring_view", "wchar_t",1878      std::make_shared<CXXFunctionSummaryFormat>(1879          stl_summary_flags, MsvcStlWStringViewSummaryProvider,1880          "MSVC STL std::wstring_view summary provider"));1881 1882  stl_summary_flags.SetDontShowChildren(false);1883 1884  AddCXXSynthetic(cpp_category_sp, MsvcStlAtomicSyntheticFrontEndCreator,1885                  "MSVC STL std::atomic synthetic children",1886                  "^std::atomic<.+>$", stl_synth_flags, true);1887 1888  AddCXXSummary(cpp_category_sp, MsvcStlAtomicSummaryProvider,1889                "MSVC STL std::atomic summary provider", "^std::atomic<.+>$",1890                stl_summary_flags, true);1891  AddCXXSynthetic(cpp_category_sp, MsvcStlTreeIterSyntheticFrontEndCreator,1892                  "MSVC STL tree iterator synthetic children",1893                  "^std::_Tree(_const)?_iterator<.+>(( )?&)?$", stl_synth_flags,1894                  true);1895  AddCXXSummary(cpp_category_sp, MsvcStlTreeIterSummaryProvider,1896                "MSVC STL tree iterator summary",1897                "^std::_Tree(_const)?_iterator<.+>(( )?&)?$", stl_summary_flags,1898                true);1899}1900 1901static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {1902  if (!cpp_category_sp)1903    return;1904 1905  TypeSummaryImpl::Flags string_flags;1906  string_flags.SetCascades(true)1907      .SetSkipPointers(true)1908      .SetSkipReferences(false)1909      .SetDontShowChildren(true)1910      .SetDontShowValue(false)1911      .SetShowMembersOneLiner(false)1912      .SetHideItemNames(false);1913 1914  TypeSummaryImpl::Flags string_array_flags;1915  string_array_flags.SetCascades(true)1916      .SetSkipPointers(true)1917      .SetSkipReferences(false)1918      .SetDontShowChildren(true)1919      .SetDontShowValue(true)1920      .SetShowMembersOneLiner(false)1921      .SetHideItemNames(false);1922 1923  AddCXXSummary(cpp_category_sp,1924                lldb_private::formatters::Char8StringSummaryProvider,1925                "char8_t * summary provider", "char8_t *", string_flags);1926  AddCXXSummary(cpp_category_sp,1927                lldb_private::formatters::Char8StringSummaryProvider,1928                "char8_t [] summary provider", "char8_t ?\\[[0-9]+\\]",1929                string_array_flags, true);1930 1931  AddCXXSummary(cpp_category_sp,1932                lldb_private::formatters::Char16StringSummaryProvider,1933                "char16_t * summary provider", "char16_t *", string_flags);1934  AddCXXSummary(cpp_category_sp,1935                lldb_private::formatters::Char16StringSummaryProvider,1936                "char16_t [] summary provider", "char16_t ?\\[[0-9]+\\]",1937                string_array_flags, true);1938 1939  AddCXXSummary(cpp_category_sp,1940                lldb_private::formatters::Char32StringSummaryProvider,1941                "char32_t * summary provider", "char32_t *", string_flags);1942  AddCXXSummary(cpp_category_sp,1943                lldb_private::formatters::Char32StringSummaryProvider,1944                "char32_t [] summary provider", "char32_t ?\\[[0-9]+\\]",1945                string_array_flags, true);1946 1947  AddCXXSummary(cpp_category_sp,1948                lldb_private::formatters::WCharStringSummaryProvider,1949                "wchar_t * summary provider", "wchar_t *", string_flags);1950  AddCXXSummary(cpp_category_sp,1951                lldb_private::formatters::WCharStringSummaryProvider,1952                "wchar_t * summary provider", "wchar_t ?\\[[0-9]+\\]",1953                string_array_flags, true);1954 1955  AddCXXSummary(cpp_category_sp,1956                lldb_private::formatters::Char16StringSummaryProvider,1957                "unichar * summary provider", "unichar *", string_flags);1958 1959  TypeSummaryImpl::Flags widechar_flags;1960  widechar_flags.SetDontShowValue(true)1961      .SetSkipPointers(true)1962      .SetSkipReferences(false)1963      .SetCascades(true)1964      .SetDontShowChildren(true)1965      .SetHideItemNames(true)1966      .SetShowMembersOneLiner(false);1967 1968  AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,1969                "char8_t summary provider", "char8_t", widechar_flags);1970  AddCXXSummary(cpp_category_sp,1971                lldb_private::formatters::Char16SummaryProvider,1972                "char16_t summary provider", "char16_t", widechar_flags);1973  AddCXXSummary(cpp_category_sp,1974                lldb_private::formatters::Char32SummaryProvider,1975                "char32_t summary provider", "char32_t", widechar_flags);1976  AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider,1977                "wchar_t summary provider", "wchar_t", widechar_flags);1978 1979  AddCXXSummary(cpp_category_sp,1980                lldb_private::formatters::Char16SummaryProvider,1981                "unichar summary provider", "unichar", widechar_flags);1982}1983 1984std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {1985  class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {1986  public:1987    CompilerType AdjustForInclusion(CompilerType &candidate) override {1988      LanguageType lang_type(candidate.GetMinimumLanguage());1989      if (!Language::LanguageIsC(lang_type) &&1990          !Language::LanguageIsCPlusPlus(lang_type))1991        return CompilerType();1992      if (candidate.IsTypedefType())1993        return candidate.GetTypedefedType();1994      return candidate;1995    }1996  };1997 1998  return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());1999}2000 2001lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {2002  static llvm::once_flag g_initialize;2003  static TypeCategoryImplSP g_category;2004 2005  llvm::call_once(g_initialize, [this]() -> void {2006    DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),2007                                               g_category);2008    if (g_category) {2009      // NOTE: the libstdcpp formatters are loaded after libcxx formatters2010      // because we don't want to the libcxx formatters to match the potential2011      // `__debug` inline namespace that libstdcpp may use.2012      // LLDB prioritizes the last loaded matching formatter.2013      LoadLibCxxFormatters(g_category);2014      LoadLibStdcppFormatters(g_category);2015      LoadMsvcStlFormatters(g_category);2016      LoadCommonStlFormatters(g_category);2017      LoadSystemFormatters(g_category);2018    }2019  });2020  return g_category;2021}2022 2023HardcodedFormatters::HardcodedSummaryFinder2024CPlusPlusLanguage::GetHardcodedSummaries() {2025  static llvm::once_flag g_initialize;2026  static ConstString g_vectortypes("VectorTypes");2027  static HardcodedFormatters::HardcodedSummaryFinder g_formatters;2028 2029  llvm::call_once(g_initialize, []() -> void {2030    g_formatters.push_back(2031        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,2032           FormatManager &) -> TypeSummaryImpl::SharedPointer {2033          static CXXFunctionSummaryFormat::SharedPointer formatter_sp(2034              new CXXFunctionSummaryFormat(2035                  TypeSummaryImpl::Flags(),2036                  lldb_private::formatters::CXXFunctionPointerSummaryProvider,2037                  "Function pointer summary provider"));2038          if (CompilerType CT = valobj.GetCompilerType();2039              CT.IsFunctionPointerType() || CT.IsMemberFunctionPointerType() ||2040              valobj.GetValueType() == lldb::eValueTypeVTableEntry) {2041            return formatter_sp;2042          }2043          return nullptr;2044        });2045    g_formatters.push_back(2046        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,2047           FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {2048          static CXXFunctionSummaryFormat::SharedPointer formatter_sp(2049              new CXXFunctionSummaryFormat(2050                  TypeSummaryImpl::Flags()2051                      .SetCascades(true)2052                      .SetDontShowChildren(true)2053                      .SetHideItemNames(true)2054                      .SetShowMembersOneLiner(true)2055                      .SetSkipPointers(true)2056                      .SetSkipReferences(false),2057                  lldb_private::formatters::VectorTypeSummaryProvider,2058                  "vector_type pointer summary provider"));2059          if (valobj.GetCompilerType().IsVectorType()) {2060            if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())2061              return formatter_sp;2062          }2063          return nullptr;2064        });2065    g_formatters.push_back(2066        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,2067           FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {2068          static CXXFunctionSummaryFormat::SharedPointer formatter_sp(2069              new CXXFunctionSummaryFormat(2070                  TypeSummaryImpl::Flags()2071                      .SetCascades(true)2072                      .SetDontShowChildren(true)2073                      .SetHideItemNames(true)2074                      .SetShowMembersOneLiner(true)2075                      .SetSkipPointers(true)2076                      .SetSkipReferences(false),2077                  lldb_private::formatters::BlockPointerSummaryProvider,2078                  "block pointer summary provider"));2079          if (valobj.GetCompilerType().IsBlockPointerType()) {2080            return formatter_sp;2081          }2082          return nullptr;2083        });2084  });2085 2086  return g_formatters;2087}2088 2089HardcodedFormatters::HardcodedSyntheticFinder2090CPlusPlusLanguage::GetHardcodedSynthetics() {2091  static llvm::once_flag g_initialize;2092  static ConstString g_vectortypes("VectorTypes");2093  static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;2094 2095  llvm::call_once(g_initialize, []() -> void {2096    g_formatters.push_back([](lldb_private::ValueObject &valobj,2097                              lldb::DynamicValueType, FormatManager &fmt_mgr)2098                               -> SyntheticChildren::SharedPointer {2099      static CXXSyntheticChildren::SharedPointer formatter_sp(2100          new CXXSyntheticChildren(2101              SyntheticChildren::Flags()2102                  .SetCascades(true)2103                  .SetSkipPointers(true)2104                  .SetSkipReferences(true)2105                  .SetNonCacheable(true),2106              "vector_type synthetic children",2107              lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));2108      if (valobj.GetCompilerType().IsVectorType()) {2109        if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())2110          return formatter_sp;2111      }2112      return nullptr;2113    });2114    g_formatters.push_back([](lldb_private::ValueObject &valobj,2115                              lldb::DynamicValueType, FormatManager &fmt_mgr)2116                               -> SyntheticChildren::SharedPointer {2117      static CXXSyntheticChildren::SharedPointer formatter_sp(2118          new CXXSyntheticChildren(2119              SyntheticChildren::Flags()2120                  .SetCascades(true)2121                  .SetSkipPointers(true)2122                  .SetSkipReferences(true)2123                  .SetNonCacheable(true),2124              "block pointer synthetic children",2125              lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));2126      if (valobj.GetCompilerType().IsBlockPointerType()) {2127        return formatter_sp;2128      }2129      return nullptr;2130    });2131  });2132 2133  return g_formatters;2134}2135 2136bool CPlusPlusLanguage::IsNilReference(ValueObject &valobj) {2137  if (!Language::LanguageIsCPlusPlus(valobj.GetObjectRuntimeLanguage()) ||2138      !valobj.IsPointerType())2139    return false;2140  bool canReadValue = true;2141  bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;2142  return canReadValue && isZero;2143}2144 2145bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {2146  const auto suffixes = {".cpp", ".cxx", ".c++", ".cc",  ".c",2147                         ".h",   ".hh",  ".hpp", ".hxx", ".h++"};2148  for (auto suffix : suffixes) {2149    if (file_path.ends_with_insensitive(suffix))2150      return true;2151  }2152 2153  // Check if we're in a STL path (where the files usually have no extension2154  // that we could check for.2155  return file_path.contains("/usr/include/c++/");2156}2157 2158static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {2159  assert(sc.function);2160 2161  if (sc.block)2162    if (Block *inline_block = sc.block->GetContainingInlinedBlock())2163      return inline_block->GetBlockVariableList(true);2164 2165  return sc.function->GetBlock(true).GetBlockVariableList(true);2166}2167 2168static bool PrintFunctionNameWithArgs(Stream &s,2169                                      const ExecutionContext *exe_ctx,2170                                      const SymbolContext &sc) {2171  assert(sc.function);2172 2173  ExecutionContextScope *exe_scope =2174      exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;2175 2176  const char *cstr = sc.GetPossiblyInlinedFunctionName()2177                         .GetName(Mangled::NamePreference::ePreferDemangled)2178                         .AsCString();2179  if (!cstr)2180    return false;2181 2182  VariableList args;2183  if (auto variable_list_sp = GetFunctionVariableList(sc))2184    variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,2185                                               args);2186 2187  if (args.GetSize() > 0)2188    return PrettyPrintFunctionNameWithArgs(s, cstr, exe_scope, args);2189 2190  // FIXME: can we just unconditionally call PrettyPrintFunctionNameWithArgs?2191  // It should be able to handle the "no arguments" case.2192  s.PutCString(cstr);2193 2194  return true;2195}2196 2197bool CPlusPlusLanguage::GetFunctionDisplayName(2198    const SymbolContext &sc, const ExecutionContext *exe_ctx,2199    FunctionNameRepresentation representation, Stream &s) {2200  switch (representation) {2201  case FunctionNameRepresentation::eNameWithArgs: {2202    // Print the function name with arguments in it2203    if (sc.function)2204      return PrintFunctionNameWithArgs(s, exe_ctx, sc);2205 2206    if (!sc.symbol)2207      return false;2208 2209    const char *cstr = sc.symbol->GetName().AsCString(nullptr);2210    if (!cstr)2211      return false;2212 2213    s.PutCString(cstr);2214 2215    return true;2216  }2217  case FunctionNameRepresentation::eNameWithNoArgs:2218  case FunctionNameRepresentation::eName:2219    return false;2220  }2221  llvm_unreachable("Fully covered switch above");2222}2223 2224bool CPlusPlusLanguage::HandleFrameFormatVariable(2225    const SymbolContext &sc, const ExecutionContext *exe_ctx,2226    FormatEntity::Entry::Type type, Stream &s) {2227  switch (type) {2228  case FormatEntity::Entry::Type::FunctionScope: {2229    auto scope_or_err = ::GetDemangledScope(sc);2230    if (!scope_or_err) {2231      LLDB_LOG_ERROR(2232          GetLog(LLDBLog::Language), scope_or_err.takeError(),2233          "Failed to handle ${{function.scope}} frame-format variable: {0}");2234      return false;2235    }2236 2237    s << *scope_or_err;2238 2239    return true;2240  }2241 2242  case FormatEntity::Entry::Type::FunctionBasename: {2243    auto name_or_err = ::GetDemangledBasename(sc);2244    if (!name_or_err) {2245      LLDB_LOG_ERROR(2246          GetLog(LLDBLog::Language), name_or_err.takeError(),2247          "Failed to handle ${{function.basename}} frame-format variable: {0}");2248      return false;2249    }2250 2251    s << *name_or_err;2252 2253    return true;2254  }2255 2256  case FormatEntity::Entry::Type::FunctionTemplateArguments: {2257    auto template_args_or_err = ::GetDemangledTemplateArguments(sc);2258    if (!template_args_or_err) {2259      LLDB_LOG_ERROR(GetLog(LLDBLog::Language),2260                     template_args_or_err.takeError(),2261                     "Failed to handle ${{function.template-arguments}} "2262                     "frame-format variable: {0}");2263      return false;2264    }2265 2266    s << *template_args_or_err;2267 2268    return true;2269  }2270 2271  case FormatEntity::Entry::Type::FunctionFormattedArguments: {2272    // This ensures we print the arguments even when no debug-info is available.2273    //2274    // FIXME: we should have a Entry::Type::FunctionArguments and2275    // use it in the plugin.cplusplus.display.function-name-format2276    // once we have a "fallback operator" in the frame-format language.2277    if (!sc.function && sc.symbol)2278      return PrintDemangledArgumentList(s, sc);2279 2280    VariableList args;2281    if (auto variable_list_sp = GetFunctionVariableList(sc))2282      variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,2283                                                 args);2284 2285    ExecutionContextScope *exe_scope =2286        exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;2287 2288    s << '(';2289    FormatEntity::PrettyPrintFunctionArguments(s, args, exe_scope);2290    s << ')';2291 2292    return true;2293  }2294  case FormatEntity::Entry::Type::FunctionReturnRight: {2295    auto return_rhs_or_err = ::GetDemangledReturnTypeRHS(sc);2296    if (!return_rhs_or_err) {2297      LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_rhs_or_err.takeError(),2298                     "Failed to handle ${{function.return-right}} frame-format "2299                     "variable: {0}");2300      return false;2301    }2302 2303    s << *return_rhs_or_err;2304 2305    return true;2306  }2307  case FormatEntity::Entry::Type::FunctionReturnLeft: {2308    auto return_lhs_or_err = ::GetDemangledReturnTypeLHS(sc);2309    if (!return_lhs_or_err) {2310      LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_lhs_or_err.takeError(),2311                     "Failed to handle ${{function.return-left}} frame-format "2312                     "variable: {0}");2313      return false;2314    }2315 2316    s << *return_lhs_or_err;2317 2318    return true;2319  }2320  case FormatEntity::Entry::Type::FunctionQualifiers: {2321    auto quals_or_err = ::GetDemangledFunctionQualifiers(sc);2322    if (!quals_or_err) {2323      LLDB_LOG_ERROR(GetLog(LLDBLog::Language), quals_or_err.takeError(),2324                     "Failed to handle ${{function.qualifiers}} frame-format "2325                     "variable: {0}");2326      return false;2327    }2328 2329    s << *quals_or_err;2330 2331    return true;2332  }2333  case FormatEntity::Entry::Type::FunctionSuffix: {2334    auto suffix_or_err = ::GetDemangledFunctionSuffix(sc);2335    if (!suffix_or_err) {2336      LLDB_LOG_ERROR(2337          GetLog(LLDBLog::Language), suffix_or_err.takeError(),2338          "Failed to handle ${{function.suffix}} frame-format variable: {0}");2339      return false;2340    }2341 2342    s << *suffix_or_err;2343 2344    return true;2345  }2346  default:2347    return false;2348  }2349}2350 2351namespace {2352class NodeAllocator {2353  llvm::BumpPtrAllocator Alloc;2354 2355public:2356  void reset() { Alloc.Reset(); }2357 2358  template <typename T, typename... Args> T *makeNode(Args &&...args) {2359    return new (Alloc.Allocate(sizeof(T), alignof(T)))2360        T(std::forward<Args>(args)...);2361  }2362 2363  void *allocateNodeArray(size_t sz) {2364    return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,2365                          alignof(llvm::itanium_demangle::Node *));2366  }2367};2368 2369template <typename Derived>2370class ManglingSubstitutor2371    : public llvm::itanium_demangle::AbstractManglingParser<Derived,2372                                                            NodeAllocator> {2373  using Base =2374      llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;2375 2376public:2377  ManglingSubstitutor() : Base(nullptr, nullptr) {}2378 2379  template <typename... Ts>2380  llvm::Expected<ConstString> substitute(llvm::StringRef Mangled,2381                                         Ts &&...Vals) {2382    this->getDerived().reset(Mangled, std::forward<Ts>(Vals)...);2383    return substituteImpl(Mangled);2384  }2385 2386protected:2387  void reset(llvm::StringRef Mangled) {2388    Base::reset(Mangled.begin(), Mangled.end());2389    Written = Mangled.begin();2390    Result.clear();2391    Substituted = false;2392  }2393 2394  llvm::Expected<ConstString> substituteImpl(llvm::StringRef Mangled) {2395    if (this->parse() == nullptr)2396      return llvm::createStringError(2397          llvm::formatv("Failed to substitute mangling in '{0}'", Mangled));2398 2399    if (!Substituted)2400      return ConstString();2401 2402    // Append any trailing unmodified input.2403    appendUnchangedInput();2404    return ConstString(Result);2405  }2406 2407  void trySubstitute(llvm::StringRef From, llvm::StringRef To) {2408    if (!llvm::StringRef(currentParserPos(), this->numLeft()).starts_with(From))2409      return;2410 2411    // We found a match. Append unmodified input up to this point.2412    appendUnchangedInput();2413 2414    // And then perform the replacement.2415    Result += To;2416    Written += From.size();2417    Substituted = true;2418  }2419 2420private:2421  /// Input character until which we have constructed the respective output2422  /// already.2423  const char *Written = "";2424 2425  llvm::SmallString<128> Result;2426 2427  /// Whether we have performed any substitutions.2428  bool Substituted = false;2429 2430  const char *currentParserPos() const { return this->First; }2431 2432  void appendUnchangedInput() {2433    Result +=2434        llvm::StringRef(Written, std::distance(Written, currentParserPos()));2435    Written = currentParserPos();2436  }2437};2438 2439/// Given a mangled function `Mangled`, replace all the primitive function type2440/// arguments of `Search` with type `Replace`.2441class TypeSubstitutor : public ManglingSubstitutor<TypeSubstitutor> {2442  llvm::StringRef Search;2443  llvm::StringRef Replace;2444 2445public:2446  void reset(llvm::StringRef Mangled, llvm::StringRef Search,2447             llvm::StringRef Replace) {2448    ManglingSubstitutor::reset(Mangled);2449    this->Search = Search;2450    this->Replace = Replace;2451  }2452 2453  llvm::itanium_demangle::Node *parseType() {2454    trySubstitute(Search, Replace);2455    return ManglingSubstitutor::parseType();2456  }2457};2458 2459class CtorDtorSubstitutor : public ManglingSubstitutor<CtorDtorSubstitutor> {2460  llvm::StringRef Search;2461  llvm::StringRef Replace;2462 2463public:2464  void reset(llvm::StringRef Mangled, llvm::StringRef Search,2465             llvm::StringRef Replace) {2466    ManglingSubstitutor::reset(Mangled);2467    this->Search = Search;2468    this->Replace = Replace;2469  }2470 2471  void reset(llvm::StringRef Mangled) { ManglingSubstitutor::reset(Mangled); }2472 2473  llvm::itanium_demangle::Node *2474  parseCtorDtorName(llvm::itanium_demangle::Node *&SoFar, NameState *State) {2475    if (!Search.empty() && !Replace.empty()) {2476      trySubstitute(Search, Replace);2477    } else {2478      trySubstitute("D1", "D2");2479      trySubstitute("C1", "C2");2480    }2481    return ManglingSubstitutor::parseCtorDtorName(SoFar, State);2482  }2483};2484} // namespace2485 2486llvm::Expected<ConstString>2487CPlusPlusLanguage::SubstituteType_ItaniumMangle(llvm::StringRef mangled_name,2488                                                llvm::StringRef subst_from,2489                                                llvm::StringRef subst_to) {2490  return TypeSubstitutor().substitute(mangled_name, subst_from, subst_to);2491}2492 2493llvm::Expected<ConstString> CPlusPlusLanguage::SubstituteStructor_ItaniumMangle(2494    llvm::StringRef mangled_name, llvm::StringRef subst_from,2495    llvm::StringRef subst_to) {2496  return CtorDtorSubstitutor().substitute(mangled_name, subst_from, subst_to);2497}2498 2499llvm::Expected<ConstString>2500CPlusPlusLanguage::SubstituteStructorAliases_ItaniumMangle(2501    llvm::StringRef mangled_name) {2502  return CtorDtorSubstitutor().substitute(mangled_name);2503}2504 2505#define LLDB_PROPERTIES_language_cplusplus2506#include "LanguageCPlusPlusProperties.inc"2507 2508enum {2509#define LLDB_PROPERTIES_language_cplusplus2510#include "LanguageCPlusPlusPropertiesEnum.inc"2511};2512 2513namespace {2514class PluginProperties : public Properties {2515public:2516  static llvm::StringRef GetSettingName() { return "display"; }2517 2518  PluginProperties() {2519    m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());2520    m_collection_sp->Initialize(g_language_cplusplus_properties);2521  }2522 2523  FormatEntity::Entry GetFunctionNameFormat() const {2524    return GetPropertyAtIndexAs<FormatEntity::Entry>(2525        ePropertyFunctionNameFormat, {});2526  }2527};2528} // namespace2529 2530static PluginProperties &GetGlobalPluginProperties() {2531  static PluginProperties g_settings;2532  return g_settings;2533}2534 2535FormatEntity::Entry CPlusPlusLanguage::GetFunctionNameFormat() const {2536  return GetGlobalPluginProperties().GetFunctionNameFormat();2537}2538 2539void CPlusPlusLanguage::DebuggerInitialize(Debugger &debugger) {2540  if (!PluginManager::GetSettingForCPlusPlusLanguagePlugin(2541          debugger, PluginProperties::GetSettingName())) {2542    PluginManager::CreateSettingForCPlusPlusLanguagePlugin(2543        debugger, GetGlobalPluginProperties().GetValueProperties(),2544        "Properties for the CPlusPlus language plug-in.",2545        /*is_global_property=*/true);2546  }2547}2548