//===-- CPlusPlusLanguage.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "CPlusPlusLanguage.h"

#include <cctype>
#include <cstdlib>
#include <cstring>

#include <functional>
#include <memory>
#include <mutex>
#include <set>

#include "llvm/ADT/StringRef.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Demangle/ItaniumDemangle.h"
#include "llvm/Support/ErrorExtras.h"

#include "lldb/Core/DemangledNameInfo.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RichManglingContext.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/DataFormatters/CXXFunctionPointer.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/VectorType.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/ValueObject/ValueObjectVariable.h"

#include "BlockPointer.h"
#include "CPlusPlusNameParser.h"
#include "Coroutines.h"
#include "CxxStringTypes.h"
#include "Generic.h"
#include "LibCxx.h"
#include "LibCxxAtomic.h"
#include "LibCxxVariant.h"
#include "LibStdcpp.h"
#include "MSVCUndecoratedNameParser.h"
#include "MsvcStl.h"
#include "lldb/lldb-enumerations.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)

void CPlusPlusLanguage::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
                                CreateInstance, &DebuggerInitialize);
}

void CPlusPlusLanguage::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

std::unique_ptr<Language::MethodName>
CPlusPlusLanguage::GetMethodName(llvm::StringRef full_name) const {
  std::unique_ptr<CxxMethodName> cpp_method =
      std::make_unique<CxxMethodName>(full_name.str());
  cpp_method->IsValid();
  return cpp_method;
}

std::pair<FunctionNameType, std::optional<ConstString>>
CPlusPlusLanguage::GetFunctionNameInfo(ConstString name) const {
  if (Mangled::IsMangledName(name.GetCString()))
    return {eFunctionNameTypeFull, std::nullopt};

  FunctionNameType func_name_type = eFunctionNameTypeNone;
  CxxMethodName method(name.GetStringRef().str());
  llvm::StringRef basename = method.GetBasename();
  if (basename.empty()) {
    llvm::StringRef context;
    func_name_type |=
        (ExtractContextAndIdentifier(name.GetStringRef(), context, basename)
             ? (eFunctionNameTypeMethod | eFunctionNameTypeBase)
             : eFunctionNameTypeFull);
  } else {
    func_name_type |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
  }

  if (!method.GetQualifiers().empty()) {
    // There is a 'const' or other qualifier following the end of the function
    // parens, this can't be a eFunctionNameTypeBase.
    func_name_type &= ~(eFunctionNameTypeBase);
  }

  if (basename.empty())
    return {func_name_type, std::nullopt};
  else
    return {func_name_type, ConstString(basename)};
}

bool CPlusPlusLanguage::SymbolNameFitsToLanguage(const Mangled &mangled) const {
  auto mangling_scheme =
      Mangled::GetManglingScheme(mangled.GetMangledName().GetStringRef());
  return HandlesManglingScheme(mangling_scheme);
}

bool CPlusPlusLanguage::HandlesManglingScheme(
    Mangled::ManglingScheme scheme) const {
  return scheme == Mangled::eManglingSchemeItanium ||
         scheme == Mangled::eManglingSchemeMSVC;
}

static char *GetMSVCDemangledStr(llvm::StringRef M) {
  char *demangled_cstr = llvm::microsoftDemangle(
      M, nullptr, nullptr,
      llvm::MSDemangleFlags(
          llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention |
          llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType));

  if (Log *log = GetLog(LLDBLog::Demangle)) {
    if (demangled_cstr && demangled_cstr[0])
      LLDB_LOGF(log, "demangled msvc: %s -> \"%s\"", M.data(), demangled_cstr);
    else
      LLDB_LOGF(log, "demangled msvc: %s -> error", M.data());
  }

  return demangled_cstr;
}

static std::pair<char *, DemangledNameInfo>
GetItaniumDemangledStr(const char *M) {
  char *demangled_cstr = nullptr;

  DemangledNameInfo info;
  llvm::ItaniumPartialDemangler ipd;
  bool err = ipd.partialDemangle(M);
  if (!err) {
    // Default buffer and size (OutputBuffer will realloc in case it's too
    // small).
    size_t demangled_size = 80;
    demangled_cstr = static_cast<char *>(std::malloc(80));

    TrackingOutputBuffer OB(demangled_cstr, demangled_size);
    demangled_cstr = ipd.finishDemangle(&OB);
    info = std::move(OB.NameInfo);

    assert(demangled_cstr &&
           "finishDemangle must always succeed if partialDemangle did");
    assert(demangled_cstr[OB.getCurrentPosition() - 1] == '\0' &&
           "Expected demangled_size to return length including trailing null");
  }

  if (Log *log = GetLog(LLDBLog::Demangle)) {
    if (demangled_cstr)
      LLDB_LOGF(log, "demangled itanium: %s -> \"%s\"", M, demangled_cstr);
    else
      LLDB_LOGF(log, "demangled itanium: %s -> error: failed to demangle", M);

    if (!info.hasBasename())
      LLDB_LOGF(log,
                "demangled itanium: %s -> error: failed to retrieve name info",
                M);
  }

  return {demangled_cstr, std::move(info)};
}

Language::DemangledName
CPlusPlusLanguage::DemangleSymbol(ConstString mangled,
                                  Mangled::ManglingScheme scheme,
                                  const DemangleOptions &options) const {
  DemangledName demangled;
  switch (scheme) {
  case Mangled::eManglingSchemeItanium: {
    auto [demangled_cstr, info] = GetItaniumDemangledStr(mangled.GetCString());
    if (demangled_cstr) {
      demangled.name = demangled_cstr;
      std::free(demangled_cstr);
    }
    if (options.want_info)
      demangled.info = std::move(info);
    break;
  }
  case Mangled::eManglingSchemeMSVC:
    if (char *demangled_cstr = GetMSVCDemangledStr(mangled.GetStringRef())) {
      demangled.name = demangled_cstr;
      std::free(demangled_cstr);
    }
    break;
  default:
    break;
  }
  return demangled;
}

/// Returns true for the Itanium names that aren't worth indexing as functions.
static bool SkipItaniumName(llvm::StringRef mangled) {
  if (mangled.size() < 3 || !mangled.starts_with("_Z"))
    return true;

  // Avoid the following types of symbols in the index.
  switch (mangled[2]) {
  case 'G': // guard variables
  case 'T': // virtual tables, VTT structures, typeinfo structures + names
  case 'Z': // named local entities (if we eventually handle
            // eSymbolTypeData, we will want this back)
    return true;

  default:
    return false;
  }
}

namespace {
/// Parses Itanium or MSVC mangled function names. Their mangling doesn't tell
/// whether a declaration context is a class or a namespace.
class CPlusPlusMangledNameParser : public Language::MangledNameParser {
public:
  explicit CPlusPlusMangledNameParser(Mangled::ManglingScheme scheme)
      : m_scheme(scheme) {}

  std::optional<Mangled::FunctionNameParts>
  Parse(const Mangled &mangled) override {
    if (!ParseRichManglingInfo(mangled))
      return std::nullopt;

    Mangled::FunctionNameParts parts;
    llvm::StringRef base_name = m_rmc.ParseFunctionBaseName();
    if (base_name.empty())
      return parts;

    // Parsing the context reuses the buffer that base_name points into.
    parts.basename = ConstString(base_name);
    llvm::StringRef decl_context = m_rmc.ParseFunctionDeclContextName();
    if (decl_context.empty()) {
      parts.kind = Mangled::FunctionNameKind::TopLevel;
      return parts;
    }

    parts.decl_context = ConstString(decl_context);
    parts.kind = m_rmc.IsCtorOrDtor()
                     ? Mangled::FunctionNameKind::ConstructorOrDestructor
                     : Mangled::FunctionNameKind::Unknown;
    return parts;
  }

private:
  bool ParseRichManglingInfo(const Mangled &mangled) {
    ConstString mangled_name = mangled.GetMangledName();
    if (m_scheme == Mangled::eManglingSchemeItanium)
      return !SkipItaniumName(mangled_name) &&
             m_rmc.FromItaniumName(mangled_name);

    // There is no rich mangling info for MSVC names, so parse the demangled
    // name with CPlusPlusLanguage::CxxMethodName instead.
    ConstString demangled = mangled.GetDemangledName();
    return !demangled.IsEmpty() && m_rmc.FromCxxMethodName(demangled);
  }

  Mangled::ManglingScheme m_scheme;
  /// Instantiation of the demangler is expensive, so better use a single one
  /// for all entries during batch processing.
  RichManglingContext m_rmc;
};
} // namespace

std::unique_ptr<Language::MangledNameParser>
CPlusPlusLanguage::CreateMangledNameParser(
    Mangled::ManglingScheme scheme) const {
  if (!HandlesManglingScheme(scheme))
    return nullptr;
  return std::make_unique<CPlusPlusMangledNameParser>(scheme);
}

ConstString CPlusPlusLanguage::GetDemangledFunctionNameWithoutArguments(
    Mangled mangled) const {
  const char *mangled_name_cstr = mangled.GetMangledName().GetCString();
  ConstString demangled_name = mangled.GetDemangledName();
  if (demangled_name && mangled_name_cstr && mangled_name_cstr[0]) {
    if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
        (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
                                        // typeinfo structure, and typeinfo
                                        // mangled_name
         mangled_name_cstr[2] != 'G' && // avoid guard variables
         mangled_name_cstr[2] != 'Z'))  // named local entities (if we
                                        // eventually handle eSymbolTypeData,
                                        // we will want this back)
    {
      CxxMethodName cxx_method(demangled_name.GetStringRef().str());
      if (!cxx_method.GetBasename().empty()) {
        std::string shortname;
        if (!cxx_method.GetContext().empty())
          shortname = cxx_method.GetContext().str() + "::";
        shortname += cxx_method.GetBasename().str();
        return ConstString(shortname);
      }
    }
  }
  if (demangled_name)
    return demangled_name;
  return mangled.GetMangledName();
}

// Static Functions

Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
  // Use plugin for C++ but not for Objective-C++ (which has its own plugin).
  if (Language::LanguageIsCPlusPlus(language) &&
      language != eLanguageTypeObjC_plus_plus)
    return new CPlusPlusLanguage();
  return nullptr;
}

static bool ReverseFindMatchingChars(const llvm::StringRef &s,
                                     const llvm::StringRef &left_right_chars,
                                     size_t &left_pos, size_t &right_pos,
                                     size_t pos = llvm::StringRef::npos) {
  assert(left_right_chars.size() == 2);
  left_pos = llvm::StringRef::npos;
  const char left_char = left_right_chars[0];
  const char right_char = left_right_chars[1];
  pos = s.find_last_of(left_right_chars, pos);
  if (pos == llvm::StringRef::npos || s[pos] == left_char)
    return false;
  right_pos = pos;
  uint32_t depth = 1;
  while (pos > 0 && depth > 0) {
    pos = s.find_last_of(left_right_chars, pos);
    if (pos == llvm::StringRef::npos)
      return false;
    if (s[pos] == left_char) {
      if (--depth == 0) {
        left_pos = pos;
        return left_pos < right_pos;
      }
    } else if (s[pos] == right_char) {
      ++depth;
    }
  }
  return false;
}

static bool IsTrivialBasename(const llvm::StringRef &basename) {
  // Check that the basename matches with the following regular expression
  // "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation
  // because it is significantly more efficient then using the general purpose
  // regular expression library.
  size_t idx = 0;
  if (basename.starts_with('~'))
    idx = 1;

  if (basename.size() <= idx)
    return false; // Empty string or "~"

  if (!std::isalpha(static_cast<unsigned char>(basename[idx])) &&
      basename[idx] != '_')
    return false; // First character (after removing the possible '~'') isn't in
                  // [A-Za-z_]

  // Read all characters matching [A-Za-z_0-9]
  ++idx;
  while (idx < basename.size()) {
    if (!std::isalnum(static_cast<unsigned char>(basename[idx])) &&
        basename[idx] != '_')
      break;
    ++idx;
  }

  // We processed all characters. It is a vaild basename.
  return idx == basename.size();
}

/// A context is trivial if an only if it matches this pattern.
/// "^\s*([A-Za-z_:]*)\s*$". for example function `foo::bar::func()`
/// has a trivial context but. but `foo<int>::bar::func()` doesn't.
static bool IsTrivialContext(llvm::StringRef context) {
  // remove trailing or leading whitespace.
  context = context.trim();

  const auto iter = context.find_if_not([](char current) {
    return std::isalnum(static_cast<unsigned char>(current)) ||
           current == '_' || current == ':';
  });
  return iter == llvm::StringRef::npos;
}

/// Writes out the function name in 'full_name' to 'out_stream'
/// but replaces each argument type with the variable name
/// and the corresponding pretty-printed value
static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream,
                                            llvm::StringRef full_name,
                                            ExecutionContextScope *exe_scope,
                                            VariableList const &args) {
  CPlusPlusLanguage::CxxMethodName cpp_method{full_name.str()};

  if (!cpp_method.IsValid())
    return false;

  llvm::StringRef return_type = cpp_method.GetReturnType();
  if (!return_type.empty()) {
    out_stream.PutCString(return_type);
    out_stream.PutChar(' ');
  }

  out_stream.PutCString(cpp_method.GetScopeQualifiedName());
  out_stream.PutChar('(');

  FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope);

  out_stream.PutChar(')');

  llvm::StringRef qualifiers = cpp_method.GetQualifiers();
  if (!qualifiers.empty()) {
    out_stream.PutChar(' ');
    out_stream.PutCString(qualifiers);
  }

  return true;
}

static DemangledNameInfoCache &GetDemangledInfoCache() {
  static DemangledNameInfoCache g_cache;
  // Pick up any changes to the size the user made since the last call.
  g_cache.SetMaxEntries(ModuleList::GetGlobalModuleListProperties()
                            .GetDemangledNameInfoCacheSize());
  return g_cache;
}

static llvm::Expected<std::pair<llvm::StringRef, DemangledNameInfo>>
GetAndValidateInfo(const SymbolContext &sc) {
  Mangled mangled = sc.GetPossiblyInlinedFunctionName();
  if (!mangled)
    return llvm::createStringError("function does not have a mangled name");

  auto demangled_name = mangled.GetDemangledName().GetStringRef();
  if (demangled_name.empty())
    return llvm::createStringErrorV(
        "function '{0}' does not have a demangled name",
        mangled.GetMangledName());

  std::optional<DemangledNameInfo> info = GetDemangledInfoCache().Get(mangled);
  if (!info)
    return llvm::createStringErrorV(
        "function '{0}' does not have demangled info", demangled_name);

  // Function without a basename is nonsense.
  if (!info->hasBasename())
    return llvm::createStringErrorV(
        "demangled info for '{0}' does not have a basename range",
        demangled_name);

  return std::make_pair(demangled_name, *info);
}

static llvm::Expected<llvm::StringRef>
GetDemangledBasename(const SymbolContext &sc) {
  auto info_or_err = GetAndValidateInfo(sc);
  if (!info_or_err)
    return info_or_err.takeError();

  auto [demangled_name, info] = *info_or_err;

  return CPlusPlusLanguage::GetDemangledBasename(demangled_name, info);
}

llvm::StringRef
CPlusPlusLanguage::GetDemangledBasename(llvm::StringRef demangled,
                                        const DemangledNameInfo &info) {
  assert(info.hasBasename());
  return demangled.slice(info.BasenameRange.first, info.BasenameRange.second);
}

llvm::Expected<llvm::StringRef>
CPlusPlusLanguage::GetDemangledTemplateArguments(
    llvm::StringRef demangled, const DemangledNameInfo &info) {
  if (!info.hasTemplateArguments())
    return llvm::createStringErrorV(
        "template arguments range for '{0}' is invalid", demangled);

  return demangled.slice(info.TemplateArgumentsRange.first,
                         info.TemplateArgumentsRange.second);
}

static llvm::Expected<llvm::StringRef>
GetDemangledTemplateArguments(const SymbolContext &sc) {
  auto info_or_err = GetAndValidateInfo(sc);
  if (!info_or_err)
    return info_or_err.takeError();

  auto [demangled_name, info] = *info_or_err;

  return CPlusPlusLanguage::GetDemangledTemplateArguments(demangled_name, info);
}

llvm::Expected<llvm::StringRef>
CPlusPlusLanguage::GetDemangledReturnTypeLHS(llvm::StringRef demangled,
                                             const DemangledNameInfo &info) {
  if (info.ScopeRange.first >= demangled.size())
    return llvm::createStringErrorV(
        "scope range for '{0}' LHS return type is invalid", demangled);

  return demangled.substr(0, info.ScopeRange.first);
}

static llvm::Expected<llvm::StringRef>
GetDemangledReturnTypeLHS(const SymbolContext &sc) {
  auto info_or_err = GetAndValidateInfo(sc);
  if (!info_or_err)
    return info_or_err.takeError();

  auto [demangled_name, info] = *info_or_err;

  return CPlusPlusLanguage::GetDemangledReturnTypeLHS(demangled_name, info);
}

llvm::Expected<llvm::StringRef>
CPlusPlusLanguage::GetDemangledFunctionQualifiers(
    llvm::StringRef demangled, const DemangledNameInfo &info) {
  if (!info.hasQualifiers())
    return llvm::createStringErrorV("qualifiers range for '{0}' is invalid",
                                    demangled);

  return demangled.slice(info.QualifiersRange.first,
                         info.QualifiersRange.second);
}

static llvm::Expected<llvm::StringRef>
GetDemangledFunctionQualifiers(const SymbolContext &sc) {
  auto info_or_err = GetAndValidateInfo(sc);
  if (!info_or_err)
    return info_or_err.takeError();

  auto [demangled_name, info] = *info_or_err;

  return CPlusPlusLanguage::GetDemangledFunctionQualifiers(demangled_name,
                                                           info);
}

llvm::Expected<llvm::StringRef>
CPlusPlusLanguage::GetDemangledReturnTypeRHS(llvm::StringRef demangled,
                                             const DemangledNameInfo &info) {
  if (info.QualifiersRange.first < info.ArgumentsRange.second)
    return llvm::createStringErrorV(
        "qualifiers range for '{0}' RHS return type is invalid", demangled);

  return demangled.slice(info.ArgumentsRange.second,
                         info.QualifiersRange.first);
}

static llvm::Expected<llvm::StringRef>
GetDemangledReturnTypeRHS(const SymbolContext &sc) {
  auto info_or_err = GetAndValidateInfo(sc);
  if (!info_or_err)
    return info_or_err.takeError();

  auto [demangled_name, info] = *info_or_err;

  return CPlusPlusLanguage::GetDemangledReturnTypeRHS(demangled_name, info);
}

llvm::Expected<llvm::StringRef>
CPlusPlusLanguage::GetDemangledScope(llvm::StringRef demangled,
                                     const DemangledNameInfo &info) {
  if (!info.hasScope())
    return llvm::createStringErrorV("scope range for '{0}' is invalid",
                                    demangled);

  return demangled.slice(info.ScopeRange.first, info.ScopeRange.second);
}

static llvm::Expected<llvm::StringRef>
GetDemangledScope(const SymbolContext &sc) {
  auto info_or_err = GetAndValidateInfo(sc);
  if (!info_or_err)
    return info_or_err.takeError();

  auto [demangled_name, info] = *info_or_err;

  return CPlusPlusLanguage::GetDemangledScope(demangled_name, info);
}

llvm::Expected<llvm::StringRef>
CPlusPlusLanguage::GetDemangledFunctionSuffix(llvm::StringRef demangled,
                                              const DemangledNameInfo &info) {
  if (!info.hasSuffix())
    return llvm::createStringErrorV("suffix range for '{0}' is invalid",
                                    demangled);

  return demangled.slice(info.SuffixRange.first, info.SuffixRange.second);
}

static llvm::Expected<llvm::StringRef>
GetDemangledFunctionSuffix(const SymbolContext &sc) {
  auto info_or_err = GetAndValidateInfo(sc);
  if (!info_or_err)
    return info_or_err.takeError();

  auto [demangled_name, info] = *info_or_err;

  return CPlusPlusLanguage::GetDemangledFunctionSuffix(demangled_name, info);
}

llvm::Expected<llvm::StringRef>
CPlusPlusLanguage::GetDemangledFunctionArguments(
    llvm::StringRef demangled, const DemangledNameInfo &info) {
  if (!info.hasArguments())
    return llvm::createStringErrorV(
        "function arguments range for '{0}' is invalid", demangled);

  return demangled.slice(info.ArgumentsRange.first, info.ArgumentsRange.second);
}

static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
  assert(sc.symbol);

  auto info_or_err = GetAndValidateInfo(sc);
  if (!info_or_err) {
    LLDB_LOG_ERROR(GetLog(LLDBLog::Language), info_or_err.takeError(),
                   "Failed to handle ${{function.formatted-arguments}} "
                   "frame-format variable: {0}");
    return false;
  }

  auto [demangled_name, info] = *info_or_err;

  auto args_or_err =
      CPlusPlusLanguage::GetDemangledFunctionArguments(demangled_name, info);
  if (!args_or_err) {
    LLDB_LOG_ERROR(GetLog(LLDBLog::Language), args_or_err.takeError(),
                   "Failed to handle ${{function.formatted-arguments}} "
                   "frame-format variable: {0}");
    return false;
  }

  s << *args_or_err;

  return true;
}

bool CPlusPlusLanguage::CxxMethodName::TrySimplifiedParse() {
  // This method tries to parse simple method definitions which are presumably
  // most comman in user programs. Definitions that can be parsed by this
  // function don't have return types and templates in the name.
  // A::B::C::fun(std::vector<T> &) const
  size_t arg_start, arg_end;
  llvm::StringRef full(m_full);
  llvm::StringRef parens("()", 2);
  if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {
    m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
    if (arg_end + 1 < full.size())
      m_qualifiers = full.substr(arg_end + 1).ltrim();

    if (arg_start == 0)
      return false;
    size_t basename_end = arg_start;
    size_t context_start = 0;
    size_t context_end = full.rfind(':', basename_end);
    if (context_end == llvm::StringRef::npos)
      m_basename = full.substr(0, basename_end);
    else {
      if (context_start < context_end)
        m_context = full.substr(context_start, context_end - 1 - context_start);
      const size_t basename_begin = context_end + 1;
      m_basename = full.substr(basename_begin, basename_end - basename_begin);
    }

    if (IsTrivialBasename(m_basename) && IsTrivialContext(m_context)) {
      return true;
    }
    // The C++ basename doesn't match our regular expressions so this can't
    // be a valid C++ method, clear everything out and indicate an error
    m_context = llvm::StringRef();
    m_basename = llvm::StringRef();
    m_arguments = llvm::StringRef();
    m_qualifiers = llvm::StringRef();
    m_return_type = llvm::StringRef();
    return false;
  }
  return false;
}

void CPlusPlusLanguage::CxxMethodName::Parse() {
  if (!m_parsed && !m_full.empty()) {
    if (TrySimplifiedParse()) {
      m_parse_error = false;
    } else {
      CPlusPlusNameParser parser(m_full);
      if (auto function = parser.ParseAsFunctionDefinition()) {
        m_basename = function->name.basename;
        m_context = function->name.context;
        m_arguments = function->arguments;
        m_qualifiers = function->qualifiers;
        m_return_type = function->return_type;
        m_parse_error = false;
      } else {
        m_parse_error = true;
      }
    }
    if (m_context.empty()) {
      m_scope_qualified = std::string(m_basename);
    } else {
      m_scope_qualified = m_context;
      m_scope_qualified += "::";
      m_scope_qualified += m_basename;
    }
    m_parsed = true;
  }
}

llvm::StringRef
CPlusPlusLanguage::CxxMethodName::GetBasenameNoTemplateParameters() {
  llvm::StringRef basename = GetBasename();
  size_t arg_start, arg_end;
  llvm::StringRef parens("<>", 2);
  if (ReverseFindMatchingChars(basename, parens, arg_start, arg_end))
    return basename.substr(0, arg_start);

  return basename;
}

bool CPlusPlusLanguage::CxxMethodName::ContainsPath(llvm::StringRef path) {
  if (!m_parsed)
    Parse();

  // If we can't parse the incoming name, then just check that it contains path.
  if (m_parse_error)
    return llvm::StringRef(m_full).contains(path);

  llvm::StringRef identifier;
  llvm::StringRef context;
  const bool success =
      CPlusPlusLanguage::ExtractContextAndIdentifier(path, context, identifier);
  if (!success)
    return llvm::StringRef(m_full).contains(path);

  // Basename may include template arguments.
  // E.g.,
  // GetBaseName(): func<int>
  // identifier   : func
  //
  // ...but we still want to account for identifiers with template parameter
  // lists, e.g., when users set breakpoints on template specializations.
  //
  // E.g.,
  // GetBaseName(): func<uint32_t>
  // identifier   : func<int32_t*>
  //
  // Try to match the basename with or without template parameters.
  if (GetBasename() != identifier &&
      GetBasenameNoTemplateParameters() != identifier)
    return false;

  // Incoming path only had an identifier, so we match.
  if (context.empty())
    return true;
  // Incoming path has context but this method does not, no match.
  if (m_context.empty())
    return false;

  llvm::StringRef haystack = m_context;
  if (!haystack.consume_back(context))
    return false;
  if (haystack.empty() || !isalnum(haystack.back()))
    return true;

  return false;
}

bool CPlusPlusLanguage::DemangledNameContainsPath(llvm::StringRef path,
                                                  ConstString demangled) const {
  CxxMethodName demangled_name(demangled.GetStringRef().str());
  return demangled_name.ContainsPath(path);
}

bool CPlusPlusLanguage::ExtractContextAndIdentifier(
    llvm::StringRef name, llvm::StringRef &context,
    llvm::StringRef &identifier) {
  if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name))
    return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context,
                                                                  identifier);

  CPlusPlusNameParser parser(name);
  if (auto full_name = parser.ParseAsFullName()) {
    identifier = full_name->basename;
    context = full_name->context;
    return true;
  }
  return false;
}

std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings(
    const ConstString mangled_name) const {
  std::vector<ConstString> alternates;

  /// Get a basic set of alternative manglings for the given symbol `name`, by
  /// making a few basic possible substitutions on basic types, storage duration
  /// and `const`ness for the given symbol. The output parameter `alternates`
  /// is filled with a best-guess, non-exhaustive set of different manglings
  /// for the given name.

  // Maybe we're looking for a const symbol but the debug info told us it was
  // non-const...
  if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&
      strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
    std::string fixed_scratch("_ZNK");
    fixed_scratch.append(mangled_name.GetCString() + 3);
    alternates.push_back(ConstString(fixed_scratch));
  }

  // Maybe we're looking for a static symbol but we thought it was global...
  if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&
      strncmp(mangled_name.GetCString(), "_ZL", 3)) {
    std::string fixed_scratch("_ZL");
    fixed_scratch.append(mangled_name.GetCString() + 2);
    alternates.push_back(ConstString(fixed_scratch));
  }

  auto *log = GetLog(LLDBLog::Language);

  // `char` is implementation defined as either `signed` or `unsigned`.  As a
  // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
  // char, 'h'-unsigned char.  If we're looking for symbols with a signed char
  // parameter, try finding matches which have the general case 'c'.
  if (auto char_fixup_or_err =
          SubstituteType_ItaniumMangle(mangled_name.GetStringRef(), "a", "c")) {
    // LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
    if (*char_fixup_or_err)
      alternates.push_back(*char_fixup_or_err);
  } else
    LLDB_LOG_ERROR(log, char_fixup_or_err.takeError(),
                   "Failed to substitute 'char' type mangling: {0}");

  // long long parameter mangling 'x', may actually just be a long 'l' argument
  if (auto long_fixup_or_err =
          SubstituteType_ItaniumMangle(mangled_name.GetStringRef(), "x", "l")) {
    if (*long_fixup_or_err)
      alternates.push_back(*long_fixup_or_err);
  } else
    LLDB_LOG_ERROR(log, long_fixup_or_err.takeError(),
                   "Failed to substitute 'long long' type mangling: {0}");

  // unsigned long long parameter mangling 'y', may actually just be unsigned
  // long 'm' argument
  if (auto ulong_fixup_or_err =
          SubstituteType_ItaniumMangle(mangled_name.GetStringRef(), "y", "m")) {
    if (*ulong_fixup_or_err)
      alternates.push_back(*ulong_fixup_or_err);
  } else
    LLDB_LOG_ERROR(
        log, ulong_fixup_or_err.takeError(),
        "Failed to substitute 'unsigned long long' type mangling: {0}");

  if (auto ctor_fixup_or_err = SubstituteStructorAliases_ItaniumMangle(
          mangled_name.GetStringRef())) {
    if (*ctor_fixup_or_err) {
      alternates.push_back(*ctor_fixup_or_err);
    }
  } else
    LLDB_LOG_ERROR(log, ctor_fixup_or_err.takeError(),
                   "Failed to substitute structor alias manglings: {0}");

  return alternates;
}

ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName(
    const Mangled mangled, const SymbolContext &sym_ctx) const {
  ConstString demangled = mangled.GetDemangledName();
  if (!demangled)
    return ConstString();

  CxxMethodName cpp_name(demangled.GetStringRef().str());
  std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();

  if (!scope_qualified_name.size())
    return ConstString();

  if (!sym_ctx.module_sp)
    return ConstString();

  lldb_private::SymbolFile *sym_file = sym_ctx.module_sp->GetSymbolFile();
  if (!sym_file)
    return ConstString();

  std::vector<ConstString> alternates;
  sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);

  std::vector<ConstString> param_and_qual_matches;
  std::vector<ConstString> param_matches;
  for (size_t i = 0; i < alternates.size(); i++) {
    ConstString alternate_mangled_name = alternates[i];
    Mangled mangled(alternate_mangled_name);
    ConstString demangled = mangled.GetDemangledName();

    CxxMethodName alternate_cpp_name(demangled.GetStringRef().str());
    if (!cpp_name.IsValid())
      continue;

    if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) {
      if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
        param_and_qual_matches.push_back(alternate_mangled_name);
      else
        param_matches.push_back(alternate_mangled_name);
    }
  }

  if (param_and_qual_matches.size())
    return param_and_qual_matches[0]; // It is assumed that there will be only
                                      // one!
  else if (param_matches.size())
    return param_matches[0]; // Return one of them as a best match
  else
    return ConstString();
}

static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
  if (!cpp_category_sp)
    return;

  TypeSummaryImpl::Flags stl_summary_flags;
  stl_summary_flags.SetCascades(true)
      .SetSkipPointers(false)
      .SetSkipReferences(false)
      .SetDontShowChildren(true)
      .SetDontShowValue(false)
      .SetShowMembersOneLiner(false)
      .SetHideItemNames(false);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringSummaryProviderASCII,
                "std::string summary provider", "^std::__[[:alnum:]]+::string$",
                stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringSummaryProviderASCII,
                "std::string summary provider",
                "^std::__[[:alnum:]]+::basic_string<char, "
                "std::__[[:alnum:]]+::char_traits<char>,.*>$",
                stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringSummaryProviderASCII,
                "std::string summary provider",
                "^std::__[[:alnum:]]+::basic_string<unsigned char, "
                "std::__[[:alnum:]]+::char_traits<unsigned char>,.*>$",
                stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
                "std::u16string summary provider",
                "^std::__[[:alnum:]]+::basic_string<char16_t, "
                "std::__[[:alnum:]]+::char_traits<char16_t>,.*>$",
                stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
                "std::u32string summary provider",
                "^std::__[[:alnum:]]+::basic_string<char32_t, "
                "std::__[[:alnum:]]+::char_traits<char32_t>,.*>$",
                stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxWStringSummaryProvider,
                "std::wstring summary provider",
                "^std::__[[:alnum:]]+::wstring$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxWStringSummaryProvider,
                "std::wstring summary provider",
                "^std::__[[:alnum:]]+::basic_string<wchar_t, "
                "std::__[[:alnum:]]+::char_traits<wchar_t>,.*>$",
                stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
                "std::string_view summary provider",
                "^std::__[[:alnum:]]+::string_view$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
                "std::string_view summary provider",
                "^std::__[[:alnum:]]+::basic_string_view<char, "
                "std::__[[:alnum:]]+::char_traits<char> >$",
                stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
                "std::string_view summary provider",
                "^std::__[[:alnum:]]+::basic_string_view<unsigned char, "
                "std::__[[:alnum:]]+::char_traits<unsigned char> >$",
                stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16,
                "std::u16string_view summary provider",
                "^std::__[[:alnum:]]+::basic_string_view<char16_t, "
                "std::__[[:alnum:]]+::char_traits<char16_t> >$",
                stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32,
                "std::u32string_view summary provider",
                "^std::__[[:alnum:]]+::basic_string_view<char32_t, "
                "std::__[[:alnum:]]+::char_traits<char32_t> >$",
                stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxWStringViewSummaryProvider,
                "std::wstring_view summary provider",
                "^std::__[[:alnum:]]+::wstring_view$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxWStringViewSummaryProvider,
                "std::wstring_view summary provider",
                "^std::__[[:alnum:]]+::basic_string_view<wchar_t, "
                "std::__[[:alnum:]]+::char_traits<wchar_t> >$",
                stl_summary_flags, true);

  SyntheticChildren::Flags stl_synth_flags;
  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
      false);
  SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
  stl_deref_flags.SetFrontEndWantsDereference();

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
      "libc++ std::bitset synthetic children",
      "^std::__[[:alnum:]]+::bitset<.+>$", stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
      "libc++ std::vector synthetic children",
      "^std::__[[:alnum:]]+::vector<.+>$", stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdValarraySyntheticFrontEndCreator,
      "libc++ std::valarray synthetic children",
      "^std::__[[:alnum:]]+::valarray<.+>$", stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator,
      "libc++ std::slice_array synthetic children",
      "^std::__[[:alnum:]]+::slice_array<.+>$", stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEndCreator,
      "libc++ synthetic children for the valarray proxy arrays",
      "^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$",
      stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
      "libc++ std::forward_list synthetic children",
      "^std::__[[:alnum:]]+::forward_list<.+>$", stl_synth_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
      "libc++ std::list synthetic children", "^std::__[[:alnum:]]+::list<.+>$",
      stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
      "libc++ std::map synthetic children", "^std::__[[:alnum:]]+::map<.+> >$",
      stl_synth_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
      "libc++ std::set synthetic children", "^std::__[[:alnum:]]+::set<.+> >$",
      stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
      "libc++ std::multiset synthetic children",
      "^std::__[[:alnum:]]+::multiset<.+> >$", stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
      "libc++ std::multimap synthetic children",
      "^std::__[[:alnum:]]+::multimap<.+> >$", stl_synth_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator,
      "libc++ std::unordered containers synthetic children",
      "^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$",
      stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericContainerAdaptorFrontEndCreator,
                  "libc++ std::queue synthetic children",
                  "^std::__[[:alnum:]]+::queue<.+>$", stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
                  "libc++ std::tuple synthetic children",
                  "^std::__[[:alnum:]]+::tuple<.*>$", stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, LibcxxOptionalSyntheticFrontEndCreator,
                  "libc++ std::optional synthetic children",
                  "^std::__[[:alnum:]]+::optional<.+>$", stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,
                  "libc++ std::variant synthetic children",
                  "^std::__[[:alnum:]]+::variant<.+>$", stl_synth_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
      "libc++ std::atomic synthetic children",
      "^std::__[[:alnum:]]+::atomic<.+>$", stl_synth_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdSpanSyntheticFrontEndCreator,
      "libc++ std::span synthetic children", "^std::__[[:alnum:]]+::span<.+>$",
      stl_deref_flags, true);
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEndCreator,
      "libc++ std::ranges::ref_view synthetic children",
      "^std::__[[:alnum:]]+::ranges::ref_view<.+>$", stl_deref_flags, true);

  cpp_category_sp->AddTypeSynthetic(
      "^std::__[[:alnum:]]+::deque<.+>$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_synth_flags,
          "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
      "shared_ptr synthetic children", "^std::__[[:alnum:]]+::shared_ptr<.+>$",
      stl_synth_flags, true);

  static constexpr const char *const libcxx_std_unique_ptr_regex =
      "^std::__[[:alnum:]]+::unique_ptr<.+>$";
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator,
      "unique_ptr synthetic children", libcxx_std_unique_ptr_regex,
      stl_synth_flags, true);

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
      "weak_ptr synthetic children", "^std::__[[:alnum:]]+::weak_ptr<.+>$",
      stl_synth_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxFunctionSummaryProvider,
                "libc++ std::function summary provider",
                "^std::__[[:alnum:]]+::function<.+>$", stl_summary_flags, true);

  static constexpr const char *const libcxx_std_coroutine_handle_regex =
      "^std::__[[:alnum:]]+::coroutine_handle<.+>$";
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator,
      "coroutine_handle synthetic children", libcxx_std_coroutine_handle_regex,
      stl_deref_flags, true);

  stl_summary_flags.SetDontShowChildren(false);
  stl_summary_flags.SetSkipPointers(false);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::bitset summary provider",
                "^std::__[[:alnum:]]+::bitset<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::vector summary provider",
                "^std::__[[:alnum:]]+::vector<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::valarray summary provider",
                "^std::__[[:alnum:]]+::valarray<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStdSliceArraySummaryProvider,
                "libc++ std::slice_array summary provider",
                "^std::__[[:alnum:]]+::slice_array<.+>$", stl_summary_flags,
                true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ summary provider for the valarray proxy arrays",
                "^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$",
                stl_summary_flags, true);
  AddCXXSummary(
      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,
      "libc++ std::list summary provider",
      "^std::__[[:alnum:]]+::forward_list<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::list summary provider",
                "^std::__[[:alnum:]]+::list<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::map summary provider",
                "^std::__[[:alnum:]]+::map<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::deque summary provider",
                "^std::__[[:alnum:]]+::deque<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::queue summary provider",
                "^std::__[[:alnum:]]+::queue<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::set summary provider",
                "^std::__[[:alnum:]]+::set<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::multiset summary provider",
                "^std::__[[:alnum:]]+::multiset<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::multimap summary provider",
                "^std::__[[:alnum:]]+::multimap<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::unordered containers summary provider",
                "^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$",
                stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "libc++ std::tuple summary provider",
                "^std::__[[:alnum:]]+::tuple<.*>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibCxxAtomicSummaryProvider,
                "libc++ std::atomic summary provider",
                "^std::__[[:alnum:]]+::atomic<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::GenericOptionalSummaryProvider,
                "libc++ std::optional summary provider",
                "^std::__[[:alnum:]]+::optional<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxVariantSummaryProvider,
                "libc++ std::variant summary provider",
                "^std::__[[:alnum:]]+::variant<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libc++ std::span summary provider",
                "^std::__[[:alnum:]]+::span<.+>$", stl_summary_flags, true);

  stl_summary_flags.SetSkipPointers(true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
                "libc++ std::shared_ptr summary provider",
                "^std::__[[:alnum:]]+::shared_ptr<.+>$", stl_summary_flags,
                true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
                "libc++ std::weak_ptr summary provider",
                "^std::__[[:alnum:]]+::weak_ptr<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxUniquePointerSummaryProvider,
                "libc++ std::unique_ptr summary provider",
                libcxx_std_unique_ptr_regex, stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,
                "libc++ std::coroutine_handle summary provider",
                libcxx_std_coroutine_handle_regex, stl_summary_flags, true);

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator,
      "std::vector iterator synthetic children",
      "^std::__[[:alnum:]]+::__wrap_iter<.+>$", stl_synth_flags, true);

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,
      "std::map iterator synthetic children",
      "^std::__[[:alnum:]]+::__map_(const_)?iterator<.+>$", stl_synth_flags,
      true);

  AddCXXSynthetic(cpp_category_sp,
                  lldb_private::formatters::
                      LibCxxUnorderedMapIteratorSyntheticFrontEndCreator,
                  "std::unordered_map iterator synthetic children",
                  "^std::__[[:alnum:]]+::__hash_map_(const_)?iterator<.+>$",
                  stl_synth_flags, true);
  // Chrono duration typedefs
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::nanoseconds", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ns")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::microseconds", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} µs")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::milliseconds", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ms")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::minutes", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__rep_} min")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::hours", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} h")));

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::days", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__rep_} days")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::weeks", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__rep_} weeks")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::months", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__rep_} months")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::years", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__rep_} years")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));

  // Chrono time point types

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider,
                "libc++ std::chrono::sys_seconds summary provider",
                "^std::__[[:alnum:]]+::chrono::time_point<"
                "std::__[[:alnum:]]+::chrono::system_clock, "
                "std::__[[:alnum:]]+::chrono::duration<.*, "
                "std::__[[:alnum:]]+::ratio<1, 1> "
                "> >$",
                eTypeOptionHideChildren | eTypeOptionHideValue |
                    eTypeOptionCascade,
                true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider,
                "libc++ std::chrono::sys_seconds summary provider",
                "^std::__[[:alnum:]]+::chrono::time_point<"
                "std::__[[:alnum:]]+::chrono::system_clock, "
                "std::__[[:alnum:]]+::chrono::duration<int, "
                "std::__[[:alnum:]]+::ratio<86400, 1> "
                "> >$",
                eTypeOptionHideChildren | eTypeOptionHideValue |
                    eTypeOptionCascade,
                true);

  AddCXXSummary(
      cpp_category_sp,
      lldb_private::formatters::LibcxxChronoLocalSecondsSummaryProvider,
      "libc++ std::chrono::local_seconds summary provider",
      "^std::__[[:alnum:]]+::chrono::time_point<"
      "std::__[[:alnum:]]+::chrono::local_t, "
      "std::__[[:alnum:]]+::chrono::duration<.*, "
      "std::__[[:alnum:]]+::ratio<1, 1> "
      "> >$",
      eTypeOptionHideChildren | eTypeOptionHideValue | eTypeOptionCascade,
      true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxChronoLocalDaysSummaryProvider,
                "libc++ std::chrono::local_seconds summary provider",
                "^std::__[[:alnum:]]+::chrono::time_point<"
                "std::__[[:alnum:]]+::chrono::local_t, "
                "std::__[[:alnum:]]+::chrono::duration<int, "
                "std::__[[:alnum:]]+::ratio<86400, 1> "
                "> >$",
                eTypeOptionHideChildren | eTypeOptionHideValue |
                    eTypeOptionCascade,
                true);

  // Chrono calendar types

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::day$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "day=${var.__d_%u}")));

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxChronoMonthSummaryProvider,
                "libc++ std::chrono::month summary provider",
                "^std::__[[:alnum:]]+::chrono::month$",
                eTypeOptionHideChildren | eTypeOptionHideValue, true);

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::year$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue, "year=${var.__y_}")));

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxChronoWeekdaySummaryProvider,
                "libc++ std::chrono::weekday summary provider",
                "^std::__[[:alnum:]]+::chrono::weekday$",
                eTypeOptionHideChildren | eTypeOptionHideValue, true);

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::weekday_indexed$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue,
          "${var.__wd_} index=${var.__idx_%u}")));

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::weekday_last$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__wd_} index=last")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::month_day$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__m_} ${var.__d_}")));
  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::month_day_last$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__m_} day=last")));

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::month_weekday$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__m_} ${var.__wdi_}")));

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::month_weekday_last$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__m_} ${var.__wdl_}")));

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::year_month$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__y_} ${var.__m_}")));

  AddCXXSummary(
      cpp_category_sp,
      lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider,
      "libc++ std::chrono::year_month_day summary provider",
      "^std::__[[:alnum:]]+::chrono::year_month_day$",
      eTypeOptionHideChildren | eTypeOptionHideValue, true);

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::year_month_day_last$",
      eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
                                                    eTypeOptionHideValue,
                                                "${var.__y_} ${var.__mdl_}")));

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::year_month_weekday$", eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue,
          "${var.__y_} ${var.__m_} ${var.__wdi_}")));

  cpp_category_sp->AddTypeSummary(
      "^std::__[[:alnum:]]+::chrono::year_month_weekday_last$",
      eFormatterMatchRegex,
      TypeSummaryImplSP(new StringSummaryFormat(
          eTypeOptionHideChildren | eTypeOptionHideValue,
          "${var.__y_} ${var.__m_} ${var.__wdl_}")));

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxPartialOrderingSummaryProvider,
                "libc++ std::partial_ordering summary provider",
                "^std::__[[:alnum:]]+::partial_ordering$",
                eTypeOptionHideChildren | eTypeOptionHideValue, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxWeakOrderingSummaryProvider,
                "libc++ std::weak_ordering summary provider",
                "^std::__[[:alnum:]]+::weak_ordering$",
                eTypeOptionHideChildren | eTypeOptionHideValue, true);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxStrongOrderingSummaryProvider,
                "libc++ std::strong_ordering summary provider",
                "^std::__[[:alnum:]]+::strong_ordering$",
                eTypeOptionHideChildren | eTypeOptionHideValue, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::LibcxxSourceLocationSummaryProvider,
                "libc++ std::source_location summary provider",
                "^std::__[[:alnum:]]+::source_location$", stl_summary_flags,
                true);
}

static void RegisterStdStringSummaryProvider(
    const lldb::TypeCategoryImplSP &category_sp, llvm::StringRef string_ty,
    llvm::StringRef char_ty, lldb::TypeSummaryImplSP summary_sp) {
  auto makeSpecifier = [](llvm::StringRef name) {
    return std::make_shared<lldb_private::TypeNameSpecifierImpl>(
        name, eFormatterMatchExact);
  };

  category_sp->AddTypeSummary(makeSpecifier(string_ty), summary_sp);

  category_sp->AddTypeSummary(
      makeSpecifier(llvm::formatv("std::basic_string<{}>", char_ty).str()),
      summary_sp);

  category_sp->AddTypeSummary(
      std::make_shared<lldb_private::TypeNameSpecifierImpl>(
          llvm::formatv("^std::basic_string<{0}, ?std::char_traits<{0}>,.*>$",
                        char_ty)
              .str(),
          eFormatterMatchRegex),
      summary_sp);
}

static void RegisterStdStringViewSummaryProvider(
    const lldb::TypeCategoryImplSP &category_sp, llvm::StringRef string_ty,
    llvm::StringRef char_ty, lldb::TypeSummaryImplSP summary_sp) {
  // std::string_view
  category_sp->AddTypeSummary(
      std::make_shared<lldb_private::TypeNameSpecifierImpl>(
          string_ty, eFormatterMatchExact),
      summary_sp);

  // std::basic_string_view<char, std::char_traits<char>>
  // NativePDB has spaces at different positions compared to PDB and DWARF, so
  // use a regex and make them optional.
  category_sp->AddTypeSummary(
      std::make_shared<lldb_private::TypeNameSpecifierImpl>(
          llvm::formatv(
              "^std::basic_string_view<{0}, ?std::char_traits<{0}> ?>$",
              char_ty)
              .str(),
          eFormatterMatchRegex),
      summary_sp);
}

static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
  if (!cpp_category_sp)
    return;

  TypeSummaryImpl::Flags stl_summary_flags;
  stl_summary_flags.SetCascades(true)
      .SetSkipPointers(false)
      .SetSkipReferences(false)
      .SetDontShowChildren(true)
      .SetDontShowValue(false)
      .SetShowMembersOneLiner(false)
      .SetHideItemNames(false);

  lldb::TypeSummaryImplSP string_summary_sp(new CXXFunctionSummaryFormat(
      stl_summary_flags, LibStdcppStringSummaryProvider,
      "libstdc++ std::(w)string summary provider"));
  cpp_category_sp->AddTypeSummary("std::__cxx11::string", eFormatterMatchExact,
                                  string_summary_sp);
  cpp_category_sp->AddTypeSummary(
      "^std::__cxx11::basic_string<char, std::char_traits<char>,.*>$",
      eFormatterMatchRegex, string_summary_sp);
  cpp_category_sp->AddTypeSummary("^std::__cxx11::basic_string<unsigned char, "
                                  "std::char_traits<unsigned char>,.*>$",
                                  eFormatterMatchRegex, string_summary_sp);

  cpp_category_sp->AddTypeSummary("std::__cxx11::wstring", eFormatterMatchExact,
                                  string_summary_sp);
  cpp_category_sp->AddTypeSummary(
      "^std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>,.*>$",
      eFormatterMatchRegex, string_summary_sp);

  SyntheticChildren::Flags stl_synth_flags;
  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
      false);
  SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
  stl_deref_flags.SetFrontEndWantsDereference();

  cpp_category_sp->AddTypeSynthetic(
      "^std::__debug::vector<.+>(( )?&)?$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_synth_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
  cpp_category_sp->AddTypeSynthetic(
      "^std::__debug::map<.+> >(( )?&)?$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_synth_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
  cpp_category_sp->AddTypeSynthetic(
      "^std::__debug::deque<.+>(( )?&)?$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_deref_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider")));
  cpp_category_sp->AddTypeSynthetic(
      "^std::__debug::set<.+> >(( )?&)?$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_deref_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
  cpp_category_sp->AddTypeSynthetic(
      "^std::__debug::multimap<.+> >(( )?&)?$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_deref_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
  cpp_category_sp->AddTypeSynthetic(
      "^std::__debug::multiset<.+> >(( )?&)?$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_deref_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
  cpp_category_sp->AddTypeSynthetic(
      "^std::__debug::unordered_(multi)?(map|set)<.+> >$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_deref_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));
  cpp_category_sp->AddTypeSynthetic(
      "^std::__(debug|cxx11)::list<.+>(( )?&)?$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_deref_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
  cpp_category_sp->AddTypeSynthetic(
      "^std::__(debug|cxx11)::forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
      SyntheticChildrenSP(new ScriptedSyntheticChildren(
          stl_synth_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));

  stl_summary_flags.SetDontShowChildren(false);
  stl_summary_flags.SetSkipPointers(false);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libstdc++ std::bitset summary provider",
                "^std::__debug::bitset<.+>(( )?&)?$", stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libstdc++ std::__debug::vector summary provider",
                "^std::__debug::vector<.+>(( )?&)?$", stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libstdc++ debug std::map summary provider",
                "^std::__debug::map<.+> >(( )?&)?$", stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libstdc++ debug std::set summary provider",
                "^std::__debug::set<.+> >(( )?&)?$", stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "libstdc++ debug std::deque summary provider",
                "^std::__debug::deque<.+>(( )?&)?$", stl_summary_flags, true);

  AddCXXSummary(
      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,
      "libstdc++ debug std::multimap summary provider",
      "^std::__debug::multimap<.+> >(( )?&)?$", stl_summary_flags, true);

  AddCXXSummary(
      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,
      "libstdc++ debug std::multiset summary provider",
      "^std::__debug::multiset<.+> >(( )?&)?$", stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::ContainerSizeSummaryProvider,
                "libstdc++ debug std unordered container summary provider",
                "^std::__debug::unordered_(multi)?(map|set)<.+> >$",
                stl_summary_flags, true);

  AddCXXSummary(
      cpp_category_sp, lldb_private::formatters::ContainerSizeSummaryProvider,
      "libstdc++ debug std::list summary provider",
      "^std::__(debug|cxx11)::list<.+>(( )?&)?$", stl_summary_flags, true);

  cpp_category_sp->AddTypeSummary(
      "^std::__(debug|cxx11)::forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
      TypeSummaryImplSP(new ScriptSummaryFormat(
          stl_summary_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator,
      "std::vector iterator synthetic children",
      "^__gnu_cxx::__normal_iterator<.+>$", stl_synth_flags, true);

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator,
      "std::map iterator synthetic children",
      "^std::_Rb_tree_(const_)?iterator<.+>$", stl_synth_flags, true);

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,
      "std::unique_ptr synthetic children", "^std::unique_ptr<.+>(( )?&)?$",
      stl_synth_flags, true);

  static constexpr const char *const libstdcpp_std_coroutine_handle_regex =
      "^std::coroutine_handle<.+>(( )?&)?$";
  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator,
      "std::coroutine_handle synthetic children",
      libstdcpp_std_coroutine_handle_regex, stl_deref_flags, true);

  AddCXXSynthetic(
      cpp_category_sp,
      lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator,
      "std::bitset synthetic child", "^std::__debug::bitset<.+>(( )?&)?$",
      stl_deref_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,
                "libstdc++ std::coroutine_handle summary provider",
                libstdcpp_std_coroutine_handle_regex, stl_summary_flags, true);

  AddCXXSummary(
      cpp_category_sp,
      lldb_private::formatters::LibStdcppSourceLocationSummaryProvider,
      "libstdc++ std::source_location summary provider", "std::source_location",
      stl_summary_flags);
}

static lldb_private::SyntheticChildrenFrontEnd *
GenericSmartPointerSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                            lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlSmartPointer(*valobj_sp))
    return MsvcStlSmartPointerSyntheticFrontEndCreator(valobj_sp);
  return LibStdcppSharedPtrSyntheticFrontEndCreator(children, valobj_sp);
}

static bool
GenericSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream,
                                   const TypeSummaryOptions &options) {
  if (IsMsvcStlSmartPointer(valobj))
    return MsvcStlSmartPointerSummaryProvider(valobj, stream, options);
  return LibStdcppSmartPointerSummaryProvider(valobj, stream, options);
}

static lldb_private::SyntheticChildrenFrontEnd *
GenericUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                         lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlUniquePtr(*valobj_sp))
    return MsvcStlUniquePtrSyntheticFrontEndCreator(valobj_sp);
  return LibStdcppUniquePtrSyntheticFrontEndCreator(children, valobj_sp);
}

static bool GenericUniquePtrSummaryProvider(ValueObject &valobj, Stream &stream,
                                            const TypeSummaryOptions &options) {
  if (IsMsvcStlUniquePtr(valobj))
    return MsvcStlUniquePtrSummaryProvider(valobj, stream, options);
  return LibStdcppUniquePointerSummaryProvider(valobj, stream, options);
}

static SyntheticChildrenFrontEnd *
GenericTupleSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                     lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlTuple(*valobj_sp))
    return MsvcStlTupleSyntheticFrontEndCreator(children, valobj_sp);
  return LibStdcppTupleSyntheticFrontEndCreator(children, valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericVectorSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                      lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  // checks for vector<T> and vector<bool>
  if (auto *msvc = MsvcStlVectorSyntheticFrontEndCreator(valobj_sp))
    return msvc;

  return new ScriptedSyntheticChildren::FrontEnd(
      "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider", *valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericListSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                    lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlList(*valobj_sp))
    return MsvcStlListSyntheticFrontEndCreator(children, valobj_sp);
  return new ScriptedSyntheticChildren::FrontEnd(
      "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider", *valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericForwardListSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                           lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlList(*valobj_sp))
    return MsvcStlForwardListSyntheticFrontEndCreator(children, valobj_sp);
  return new ScriptedSyntheticChildren::FrontEnd(
      "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider",
      *valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericOptionalSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                        lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlOptional(*valobj_sp))
    return MsvcStlOptionalSyntheticFrontEndCreator(children, valobj_sp);
  return LibStdcppOptionalSyntheticFrontEndCreator(children, valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericVariantSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                       lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlVariant(*valobj_sp))
    return MsvcStlVariantSyntheticFrontEndCreator(children, valobj_sp);
  return new ScriptedSyntheticChildren::FrontEnd(
      "lldb.formatters.cpp.gnu_libstdcpp.VariantSynthProvider", *valobj_sp);
}

static bool GenericVariantSummaryProvider(ValueObject &valobj, Stream &stream,
                                          const TypeSummaryOptions &options) {
  if (IsMsvcStlVariant(valobj))
    return MsvcStlVariantSummaryProvider(valobj, stream, options);
  return LibStdcppVariantSummaryProvider(valobj, stream, options);
}

static SyntheticChildrenFrontEnd *
GenericUnorderedSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                         ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlUnordered(*valobj_sp))
    return MsvcStlUnorderedSyntheticFrontEndCreator(children, valobj_sp);
  return new ScriptedSyntheticChildren::FrontEnd(
      "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider",
      *valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericMapLikeSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                       ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlMapLike(*valobj_sp))
    return MsvcStlMapLikeSyntheticFrontEndCreator(valobj_sp);
  return new ScriptedSyntheticChildren::FrontEnd(
      "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider", *valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericDequeSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                     ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlDeque(*valobj_sp))
    return MsvcStlDequeSyntheticFrontEndCreator(children, valobj_sp);
  return new ScriptedSyntheticChildren::FrontEnd(
      "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider", *valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericSpanSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                    ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlSpan(*valobj_sp))
    return MsvcStlSpanSyntheticFrontEndCreator(children, valobj_sp);
  return LibStdcppSpanSyntheticFrontEndCreator(children, valobj_sp);
}

static bool
GenericPartialOrderingSummaryProvider(ValueObject &valobj, Stream &stream,
                                      const TypeSummaryOptions &options) {
  if (IsMsvcStlOrdering(valobj))
    return MsvcStlPartialOrderingSummaryProvider(valobj, stream, options);
  return LibStdcppPartialOrderingSummaryProvider(valobj, stream, options);
}

static bool
GenericWeakOrderingSummaryProvider(ValueObject &valobj, Stream &stream,
                                   const TypeSummaryOptions &options) {
  if (IsMsvcStlOrdering(valobj))
    return MsvcStlWeakOrderingSummaryProvider(valobj, stream, options);
  return LibStdcppWeakOrderingSummaryProvider(valobj, stream, options);
}

static bool
GenericStrongOrderingSummaryProvider(ValueObject &valobj, Stream &stream,
                                     const TypeSummaryOptions &options) {
  if (IsMsvcStlOrdering(valobj))
    return MsvcStlStrongOrderingSummaryProvider(valobj, stream, options);
  return LibStdcppStrongOrderingSummaryProvider(valobj, stream, options);
}

static SyntheticChildrenFrontEnd *
GenericBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                      ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  if (IsMsvcStlBitset(*valobj_sp))
    return MsvcStlBitsetSyntheticFrontEndCreator(children, valobj_sp);
  return LibStdcppBitsetSyntheticFrontEndCreator(children, valobj_sp);
}

static SyntheticChildrenFrontEnd *
GenericExpectedSyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                        lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;
  if (IsMsvcStlExpected(*valobj_sp))
    return MsvcStlExpectedSyntheticFrontEndCreator(children, valobj_sp);
  return nullptr;
}

static bool GenericExpectedSummaryProvider(ValueObject &valobj, Stream &stream,
                                           const TypeSummaryOptions &options) {
  if (IsMsvcStlExpected(valobj))
    return MsvcStlExpectedSummaryProvider(valobj, stream, options);
  return false;
}

static SyntheticChildrenFrontEnd *
GenericValarraySyntheticFrontEndCreator(CXXSyntheticChildren *children,
                                        lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;
  if (IsMsvcStlValarray(*valobj_sp))
    return MsvcStlValarraySyntheticFrontEndCreator(children, valobj_sp);
  return nullptr;
}

static bool GenericValarraySummaryProvider(ValueObject &valobj, Stream &stream,
                                           const TypeSummaryOptions &options) {
  if (!IsMsvcStlValarray(valobj))
    return false;
  return ContainerSizeSummaryProvider(valobj, stream, options);
}

static bool
GenericSourceLocationSummaryProvider(ValueObject &valobj, Stream &stream,
                                     const TypeSummaryOptions &options) {
  if (IsMsvcStlSourceLocation(valobj))
    return MsvcStlSourceLocationSummaryProvider(valobj, stream, options);
  return LibStdcppSourceLocationSummaryProvider(valobj, stream, options);
}

/// Load formatters that are formatting types from more than one STL
static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
  if (!cpp_category_sp)
    return;

  TypeSummaryImpl::Flags stl_summary_flags;
  stl_summary_flags.SetCascades(true)
      .SetSkipPointers(false)
      .SetSkipReferences(false)
      .SetDontShowChildren(true)
      .SetDontShowValue(false)
      .SetShowMembersOneLiner(false)
      .SetHideItemNames(false);
  SyntheticChildren::Flags stl_synth_flags;
  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
      false);

  using StringElementType = StringPrinter::StringElementType;

  RegisterStdStringSummaryProvider(
      cpp_category_sp, "std::string", "char",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          [](ValueObject &valobj, Stream &stream,
             const TypeSummaryOptions &options) {
            if (IsMsvcStlStringType(valobj))
              return MsvcStlStringSummaryProvider<StringElementType::ASCII>(
                  valobj, stream, options);
            return LibStdcppStringSummaryProvider(valobj, stream, options);
          },
          "MSVC STL/libstdc++ std::string summary provider"));
  RegisterStdStringSummaryProvider(
      cpp_category_sp, "std::wstring", "wchar_t",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          [](ValueObject &valobj, Stream &stream,
             const TypeSummaryOptions &options) {
            if (IsMsvcStlStringType(valobj))
              return MsvcStlWStringSummaryProvider(valobj, stream, options);
            return LibStdcppStringSummaryProvider(valobj, stream, options);
          },
          "MSVC STL/libstdc++ std::wstring summary provider"));

  RegisterStdStringViewSummaryProvider(
      cpp_category_sp, "std::string_view", "char",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          [](ValueObject &valobj, Stream &stream,
             const TypeSummaryOptions &options) {
            if (IsMsvcStlStringViewType(valobj))
              return MsvcStlStringViewSummaryProvider<StringElementType::ASCII>(
                  valobj, stream, options);
            return LibStdcppStringViewSummaryProvider<StringElementType::ASCII>(
                valobj, stream, options);
          },
          "MSVC STL/libstdc++ std::string_view summary provider"));
  RegisterStdStringViewSummaryProvider(
      cpp_category_sp, "std::u8string_view", "char8_t",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          [](ValueObject &valobj, Stream &stream,
             const TypeSummaryOptions &options) {
            if (IsMsvcStlStringViewType(valobj))
              return MsvcStlStringViewSummaryProvider<StringElementType::UTF8>(
                  valobj, stream, options);
            return LibStdcppStringViewSummaryProvider<StringElementType::UTF8>(
                valobj, stream, options);
          },
          "MSVC STL/libstdc++ std::u8string_view summary provider"));
  RegisterStdStringViewSummaryProvider(
      cpp_category_sp, "std::u16string_view", "char16_t",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          [](ValueObject &valobj, Stream &stream,
             const TypeSummaryOptions &options) {
            if (IsMsvcStlStringViewType(valobj))
              return MsvcStlStringViewSummaryProvider<StringElementType::UTF16>(
                  valobj, stream, options);
            return LibStdcppStringViewSummaryProvider<StringElementType::UTF16>(
                valobj, stream, options);
          },
          "MSVC STL/libstdc++ std::u16string_view summary provider"));
  RegisterStdStringViewSummaryProvider(
      cpp_category_sp, "std::u32string_view", "char32_t",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          [](ValueObject &valobj, Stream &stream,
             const TypeSummaryOptions &options) {
            if (IsMsvcStlStringViewType(valobj))
              return MsvcStlStringViewSummaryProvider<StringElementType::UTF32>(
                  valobj, stream, options);
            return LibStdcppStringViewSummaryProvider<StringElementType::UTF32>(
                valobj, stream, options);
          },
          "MSVC STL/libstdc++ std::u32string_view summary provider"));
  RegisterStdStringViewSummaryProvider(
      cpp_category_sp, "std::wstring_view", "wchar_t",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          [](ValueObject &valobj, Stream &stream,
             const TypeSummaryOptions &options) {
            if (IsMsvcStlStringViewType(valobj))
              return MsvcStlWStringViewSummaryProvider(valobj, stream, options);
            return LibStdcppWStringViewSummaryProvider(valobj, stream, options);
          },
          "MSVC STL/libstdc++ std::wstring_view summary provider"));

  // NOTE: it is loaded as a common formatter because the libc++ version is not
  // in the `__1` namespace, hence we need to dispatch based on the class
  // layout.
  AddCXXSynthetic(cpp_category_sp,
                  GenericInitializerListSyntheticFrontEndCreator,
                  "std::initializer_list synthetic children",
                  "^std::initializer_list<.+>$", stl_synth_flags, true);

  AddCXXSummary(cpp_category_sp, GenericFilesystemPathSummaryProvider,
                "MSVC STL/libstdc++ std::filesystem::path summary provider",
                "^std::filesystem::(__cxx11::)?path$", stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp, GenericSourceLocationSummaryProvider,
                "MSVC STL/libstdc++ std::source_location summary provider",
                "std::source_location", stl_summary_flags);

  stl_summary_flags.SetDontShowChildren(false);
  stl_summary_flags.SetSkipPointers(false);

  AddCXXSynthetic(cpp_category_sp, GenericSmartPointerSyntheticFrontEndCreator,
                  "std::shared_ptr synthetic children",
                  "^std::shared_ptr<.+>(( )?&)?$", stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericSmartPointerSyntheticFrontEndCreator,
                  "std::weak_ptr synthetic children",
                  "^std::weak_ptr<.+>(( )?&)?$", stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericUniquePtrSyntheticFrontEndCreator,
                  "std::unique_ptr synthetic children",
                  "^std::unique_ptr<.+>(( )?&)?$", stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericTupleSyntheticFrontEndCreator,
                  "std::tuple synthetic children", "^std::tuple<.*>(( )?&)?$",
                  stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericListSyntheticFrontEndCreator,
                  "std::list synthetic children", "^std::list<.+>(( )?&)?$",
                  stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericForwardListSyntheticFrontEndCreator,
                  "std::forward_list synthetic children",
                  "^std::forward_list<.+>(( )?&)?$", stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericVariantSyntheticFrontEndCreator,
                  "std::variant synthetic children", "^std::variant<.*>$",
                  stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericUnorderedSyntheticFrontEndCreator,
                  "std::unordered container synthetic children",
                  "^std::unordered_(multi)?(map|set)<.+> ?>$", stl_synth_flags,
                  true);

  SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
  stl_deref_flags.SetFrontEndWantsDereference();
  AddCXXSynthetic(cpp_category_sp, GenericOptionalSyntheticFrontEndCreator,
                  "std::optional synthetic children",
                  "^std::optional<.+>(( )?&)?$", stl_deref_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericDequeSyntheticFrontEndCreator,
                  "std::deque container synthetic children",
                  "^std::deque<.+>(( )?&)?$", stl_deref_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericSpanSyntheticFrontEndCreator,
                  "std::span container synthetic children", "^std::span<.+>$",
                  stl_deref_flags, true);

  AddCXXSynthetic(cpp_category_sp, GenericMapLikeSyntheticFrontEndCreator,
                  "std::(multi)?map/set synthetic children",
                  "^std::(multi)?(map|set)<.+>(( )?&)?$", stl_synth_flags,
                  true);
  AddCXXSynthetic(cpp_category_sp, GenericBitsetSyntheticFrontEndCreator,
                  "std::bitset synthetic children", "^std::bitset<.+>(( )?&)?$",
                  stl_deref_flags, true);

  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "std::initializer_list summary provider",
                "^std::initializer_list<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, GenericSmartPointerSummaryProvider,
                "MSVC STL/libstdc++ std::shared_ptr summary provider",
                "^std::shared_ptr<.+>(( )?&)?$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, GenericSmartPointerSummaryProvider,
                "MSVC STL/libstdc++ std::weak_ptr summary provider",
                "^std::weak_ptr<.+>(( )?&)?$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, GenericUniquePtrSummaryProvider,
                "MSVC STL/libstdc++ std::unique_ptr summary provider",
                "^std::unique_ptr<.+>(( )?&)?$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "MSVC STL/libstdc++ std::tuple summary provider",
                "^std::tuple<.*>(( )?&)?$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "MSVC/libstdc++ std::vector summary provider",
                "^std::vector<.+>(( )?&)?$", stl_summary_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericVectorSyntheticFrontEndCreator,
                  "MSVC/libstdc++ std::vector synthetic provider",
                  "^std::vector<.+>(( )?&)?$", stl_synth_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "MSVC STL/libstdc++ std::list summary provider",
                "^std::list<.+>(( )?&)?$", stl_summary_flags, true);
  cpp_category_sp->AddTypeSummary(
      "^std::forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
      TypeSummaryImplSP(new ScriptSummaryFormat(
          stl_summary_flags,
          "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
  AddCXXSummary(cpp_category_sp, GenericOptionalSummaryProvider,
                "MSVC STL/libstd++ std::optional summary provider",
                "^std::optional<.+>(( )?&)?$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, GenericVariantSummaryProvider,
                "MSVC STL/libstdc++ std::variant summary provider",
                "^std::variant<.*>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "MSVC STL/libstdc++ std unordered container summary provider",
                "^std::unordered_(multi)?(map|set)<.+> ?>$", stl_summary_flags,
                true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "MSVC STL/libstdc++ std::(multi)?map/set summary provider",
                "^std::(multi)?(map|set)<.+>(( )?&)?$", stl_summary_flags,
                true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "MSVC STL/libstd++ std::deque summary provider",
                "^std::deque<.+>(( )?&)?$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "MSVC STL/libstd++ std::span summary provider",
                "^std::span<.+>$", stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, GenericPartialOrderingSummaryProvider,
                "MSVC STL/libstdc++ std::partial_ordering summary provider",
                "std::partial_ordering",
                eTypeOptionHideChildren | eTypeOptionHideValue, false);
  AddCXXSummary(cpp_category_sp, GenericWeakOrderingSummaryProvider,
                "MSVC STL/libstdc++ std::weak_ordering summary provider",
                "std::weak_ordering",
                eTypeOptionHideChildren | eTypeOptionHideValue, false);
  AddCXXSummary(cpp_category_sp, GenericStrongOrderingSummaryProvider,
                "MSVC STL/libstdc++ std::strong_ordering summary provider",
                "std::strong_ordering",
                eTypeOptionHideChildren | eTypeOptionHideValue, false);

  // Container adaptors expose the underlying container as the standard
  // protected member `c` ([queue.defn], [stack.defn], [priqueue.overview]).
  AddCXXSynthetic(cpp_category_sp, GenericContainerAdaptorFrontEndCreator,
                  "std::queue synthetic children", "^std::queue<.+>(( )?&)?$",
                  stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericContainerAdaptorFrontEndCreator,
                  "std::stack synthetic children", "^std::stack<.+>(( )?&)?$",
                  stl_synth_flags, true);
  AddCXXSynthetic(cpp_category_sp, GenericContainerAdaptorFrontEndCreator,
                  "std::priority_queue synthetic children",
                  "^std::priority_queue<.+>(( )?&)?$", stl_synth_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "std::queue summary provider", "^std::queue<.+>(( )?&)?$",
                stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "std::stack summary provider", "^std::stack<.+>(( )?&)?$",
                stl_summary_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "std::priority_queue summary provider",
                "^std::priority_queue<.+>(( )?&)?$", stl_summary_flags, true);

  AddCXXSummary(cpp_category_sp, GenericErrorCodeSummaryProvider,
                "MSVC STL/libstdc++ std::error_code summary provider",
                "std::error_code", stl_summary_flags);
  AddCXXSummary(cpp_category_sp, GenericErrorCodeSummaryProvider,
                "MSVC STL/libstdc++ std::error_condition summary provider",
                "std::error_condition", stl_summary_flags);
  AddCXXSynthetic(cpp_category_sp, GenericErrorCodeSyntheticFrontEndCreator,
                  "MSVC STL/libstdc++ std::error_code/error_condition "
                  "synthetic children",
                  "^std::error_(code|condition)$", stl_synth_flags, true);
  AddCXXSummary(cpp_category_sp, ContainerSizeSummaryProvider,
                "MSVC STL/libstdc++ std::bitset summary provider",
                "^std::bitset<.+>(( )?&)?$", stl_summary_flags, true);

  AddCXXSynthetic(cpp_category_sp, GenericExpectedSyntheticFrontEndCreator,
                  "MSVC STL std::expected synthetic children",
                  "^std::expected<.+>(( )?&)?$", stl_deref_flags, true);
  AddCXXSummary(cpp_category_sp, GenericExpectedSummaryProvider,
                "MSVC STL std::expected summary provider",
                "^std::expected<.+>(( )?&)?$", stl_summary_flags, true);

  AddCXXSynthetic(cpp_category_sp, GenericValarraySyntheticFrontEndCreator,
                  "MSVC STL std::valarray synthetic children",
                  "^std::valarray<.+>(( )?&)?$", stl_deref_flags, true);
  AddCXXSummary(cpp_category_sp, GenericValarraySummaryProvider,
                "MSVC STL std::valarray summary provider",
                "^std::valarray<.+>(( )?&)?$", stl_summary_flags, true);
}

static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
  if (!cpp_category_sp)
    return;

  TypeSummaryImpl::Flags stl_summary_flags;
  stl_summary_flags.SetCascades(true)
      .SetSkipPointers(false)
      .SetSkipReferences(false)
      .SetDontShowChildren(true)
      .SetDontShowValue(false)
      .SetShowMembersOneLiner(false)
      .SetHideItemNames(false);
  SyntheticChildren::Flags stl_synth_flags;
  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
      false);

  using StringElementType = StringPrinter::StringElementType;

  RegisterStdStringSummaryProvider(
      cpp_category_sp, "std::u8string", "char8_t",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          MsvcStlStringSummaryProvider<StringElementType::UTF8>,
          "MSVC STL std::u8string summary provider"));
  RegisterStdStringSummaryProvider(
      cpp_category_sp, "std::u16string", "char16_t",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          MsvcStlStringSummaryProvider<StringElementType::UTF16>,
          "MSVC STL std::u16string summary provider"));
  RegisterStdStringSummaryProvider(
      cpp_category_sp, "std::u32string", "char32_t",
      std::make_shared<CXXFunctionSummaryFormat>(
          stl_summary_flags,
          MsvcStlStringSummaryProvider<StringElementType::UTF32>,
          "MSVC STL std::u32string summary provider"));

  stl_summary_flags.SetDontShowChildren(false);

  AddCXXSynthetic(cpp_category_sp, MsvcStlAtomicSyntheticFrontEndCreator,
                  "MSVC STL std::atomic synthetic children",
                  "^std::atomic<.+>$", stl_synth_flags, true);

  AddCXXSummary(cpp_category_sp, MsvcStlAtomicSummaryProvider,
                "MSVC STL std::atomic summary provider", "^std::atomic<.+>$",
                stl_summary_flags, true);
  AddCXXSynthetic(cpp_category_sp, MsvcStlTreeIterSyntheticFrontEndCreator,
                  "MSVC STL tree iterator synthetic children",
                  "^std::_Tree(_const)?_iterator<.+>(( )?&)?$", stl_synth_flags,
                  true);
  AddCXXSummary(cpp_category_sp, MsvcStlTreeIterSummaryProvider,
                "MSVC STL tree iterator summary",
                "^std::_Tree(_const)?_iterator<.+>(( )?&)?$", stl_summary_flags,
                true);
  AddCXXSynthetic(
      cpp_category_sp, MsvcStlVectorIteratorSyntheticFrontEndCreator,
      "MSVC STL vector iterator synthetic children",
      "^std::_Vector(_const)?_iterator<.+>(( )?&)?$", stl_synth_flags, true);
}

static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
  if (!cpp_category_sp)
    return;

  TypeSummaryImpl::Flags string_flags;
  string_flags.SetCascades(true)
      .SetSkipPointers(true)
      .SetSkipReferences(false)
      .SetDontShowChildren(true)
      .SetDontShowValue(false)
      .SetShowMembersOneLiner(false)
      .SetHideItemNames(false);

  TypeSummaryImpl::Flags string_array_flags;
  string_array_flags.SetCascades(true)
      .SetSkipPointers(true)
      .SetSkipReferences(false)
      .SetDontShowChildren(true)
      .SetDontShowValue(true)
      .SetShowMembersOneLiner(false)
      .SetHideItemNames(false);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char8StringSummaryProvider,
                "char8_t * summary provider", "char8_t *", string_flags);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char8StringSummaryProvider,
                "char8_t [] summary provider", "char8_t ?\\[[0-9]+\\]",
                string_array_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char16StringSummaryProvider,
                "char16_t * summary provider", "char16_t *", string_flags);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char16StringSummaryProvider,
                "char16_t [] summary provider", "char16_t ?\\[[0-9]+\\]",
                string_array_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char32StringSummaryProvider,
                "char32_t * summary provider", "char32_t *", string_flags);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char32StringSummaryProvider,
                "char32_t [] summary provider", "char32_t ?\\[[0-9]+\\]",
                string_array_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::WCharStringSummaryProvider,
                "wchar_t * summary provider", "wchar_t *", string_flags);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::WCharStringSummaryProvider,
                "wchar_t * summary provider", "wchar_t ?\\[[0-9]+\\]",
                string_array_flags, true);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char16StringSummaryProvider,
                "unichar * summary provider", "unichar *", string_flags);

  TypeSummaryImpl::Flags widechar_flags;
  widechar_flags.SetDontShowValue(true)
      .SetSkipPointers(true)
      .SetSkipReferences(false)
      .SetCascades(true)
      .SetDontShowChildren(true)
      .SetHideItemNames(true)
      .SetShowMembersOneLiner(false);

  AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,
                "char8_t summary provider", "char8_t", widechar_flags);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char16SummaryProvider,
                "char16_t summary provider", "char16_t", widechar_flags);
  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char32SummaryProvider,
                "char32_t summary provider", "char32_t", widechar_flags);
  AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider,
                "wchar_t summary provider", "wchar_t", widechar_flags);

  AddCXXSummary(cpp_category_sp,
                lldb_private::formatters::Char16SummaryProvider,
                "unichar summary provider", "unichar", widechar_flags);
}

std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
  class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
  public:
    CompilerType AdjustForInclusion(CompilerType &candidate) override {
      LanguageType lang_type(candidate.GetMinimumLanguage());
      if (!Language::LanguageIsC(lang_type) &&
          !Language::LanguageIsCPlusPlus(lang_type))
        return CompilerType();
      if (candidate.IsTypedefType())
        return candidate.GetTypedefedType();
      return candidate;
    }
  };

  return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());
}

lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
  static llvm::once_flag g_initialize;
  static TypeCategoryImplSP g_category;

  llvm::call_once(g_initialize, [this]() -> void {
    DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),
                                               g_category);
    if (g_category) {
      // NOTE: the libstdcpp formatters are loaded after libcxx formatters
      // because we don't want to the libcxx formatters to match the potential
      // `__debug` inline namespace that libstdcpp may use.
      // LLDB prioritizes the last loaded matching formatter.
      LoadLibCxxFormatters(g_category);
      LoadLibStdcppFormatters(g_category);
      LoadMsvcStlFormatters(g_category);
      LoadCommonStlFormatters(g_category);
      LoadSystemFormatters(g_category);
    }
  });
  return g_category;
}

HardcodedFormatters::HardcodedSummaryFinder
CPlusPlusLanguage::GetHardcodedSummaries() {
  static llvm::once_flag g_initialize;
  static ConstString g_vectortypes("VectorTypes");
  static HardcodedFormatters::HardcodedSummaryFinder g_formatters;

  llvm::call_once(g_initialize, []() -> void {
    g_formatters.push_back(
        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
           FormatManager &) -> TypeSummaryImpl::SharedPointer {
          static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
              new CXXFunctionSummaryFormat(
                  TypeSummaryImpl::Flags(),
                  lldb_private::formatters::CXXFunctionPointerSummaryProvider,
                  "Function pointer summary provider"));
          if (CompilerType CT = valobj.GetCompilerType();
              CT.IsFunctionPointerType() || CT.IsMemberFunctionPointerType() ||
              valobj.GetValueType() == lldb::eValueTypeVTableEntry) {
            return formatter_sp;
          }
          return nullptr;
        });
    g_formatters.push_back(
        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
           FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
          static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
              new CXXFunctionSummaryFormat(
                  TypeSummaryImpl::Flags()
                      .SetCascades(true)
                      .SetDontShowChildren(true)
                      .SetHideItemNames(true)
                      .SetShowMembersOneLiner(true)
                      .SetSkipPointers(true)
                      .SetSkipReferences(false),
                  lldb_private::formatters::VectorTypeSummaryProvider,
                  "vector_type pointer summary provider"));
          if (valobj.GetCompilerType().IsVectorType()) {
            if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
              return formatter_sp;
          }
          return nullptr;
        });
    g_formatters.push_back(
        [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
           FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
          static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
              new CXXFunctionSummaryFormat(
                  TypeSummaryImpl::Flags()
                      .SetCascades(true)
                      .SetDontShowChildren(true)
                      .SetHideItemNames(true)
                      .SetShowMembersOneLiner(true)
                      .SetSkipPointers(true)
                      .SetSkipReferences(false),
                  lldb_private::formatters::BlockPointerSummaryProvider,
                  "block pointer summary provider"));
          if (valobj.GetCompilerType().IsBlockPointerType()) {
            return formatter_sp;
          }
          return nullptr;
        });
  });

  return g_formatters;
}

HardcodedFormatters::HardcodedSyntheticFinder
CPlusPlusLanguage::GetHardcodedSynthetics() {
  static llvm::once_flag g_initialize;
  static ConstString g_vectortypes("VectorTypes");
  static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;

  llvm::call_once(g_initialize, []() -> void {
    g_formatters.push_back([](lldb_private::ValueObject &valobj,
                              lldb::DynamicValueType, FormatManager &fmt_mgr)
                               -> SyntheticChildren::SharedPointer {
      static CXXSyntheticChildren::SharedPointer formatter_sp(
          new CXXSyntheticChildren(
              SyntheticChildren::Flags()
                  .SetCascades(true)
                  .SetSkipPointers(true)
                  .SetSkipReferences(true)
                  .SetNonCacheable(true),
              "vector_type synthetic children",
              lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
      if (valobj.GetCompilerType().IsVectorType()) {
        if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
          return formatter_sp;
      }
      return nullptr;
    });
    g_formatters.push_back([](lldb_private::ValueObject &valobj,
                              lldb::DynamicValueType, FormatManager &fmt_mgr)
                               -> SyntheticChildren::SharedPointer {
      static CXXSyntheticChildren::SharedPointer formatter_sp(
          new CXXSyntheticChildren(
              SyntheticChildren::Flags()
                  .SetCascades(true)
                  .SetSkipPointers(true)
                  .SetSkipReferences(true)
                  .SetNonCacheable(true),
              "block pointer synthetic children",
              lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
      if (valobj.GetCompilerType().IsBlockPointerType()) {
        return formatter_sp;
      }
      return nullptr;
    });
  });

  return g_formatters;
}

bool CPlusPlusLanguage::IsNilReference(ValueObject &valobj) {
  if (!Language::LanguageIsCPlusPlus(valobj.GetObjectRuntimeLanguage()) ||
      !valobj.IsPointerType())
    return false;
  bool canReadValue = true;
  bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
  return canReadValue && isZero;
}

bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
  const auto suffixes = {".cpp", ".cxx", ".c++", ".cc",  ".c",
                         ".h",   ".hh",  ".hpp", ".hxx", ".h++"};
  for (auto suffix : suffixes) {
    if (file_path.ends_with_insensitive(suffix))
      return true;
  }

  // Check if we're in a STL path (where the files usually have no extension
  // that we could check for.
  return file_path.contains("/usr/include/c++/");
}

static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
  assert(sc.function);

  if (sc.block)
    if (Block *inline_block = sc.block->GetContainingInlinedBlock())
      return inline_block->GetBlockVariableList(true);

  return sc.function->GetBlock(true).GetBlockVariableList(true);
}

static bool PrintFunctionNameWithArgs(Stream &s,
                                      const ExecutionContext *exe_ctx,
                                      const SymbolContext &sc) {
  assert(sc.function);

  ExecutionContextScope *exe_scope =
      exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;

  const char *cstr = sc.GetPossiblyInlinedFunctionName()
                         .GetName(Mangled::NamePreference::ePreferDemangled)
                         .AsCString(nullptr);
  if (!cstr)
    return false;

  VariableList args;
  if (auto variable_list_sp = GetFunctionVariableList(sc))
    variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
                                               args);

  if (args.GetSize() > 0)
    return PrettyPrintFunctionNameWithArgs(s, cstr, exe_scope, args);

  // FIXME: can we just unconditionally call PrettyPrintFunctionNameWithArgs?
  // It should be able to handle the "no arguments" case.
  s.PutCString(cstr);

  return true;
}

bool CPlusPlusLanguage::GetFunctionDisplayName(
    const SymbolContext &sc, const ExecutionContext *exe_ctx,
    FunctionNameRepresentation representation, Stream &s) {
  switch (representation) {
  case FunctionNameRepresentation::eNameWithArgs: {
    // Print the function name with arguments in it
    if (sc.function)
      return PrintFunctionNameWithArgs(s, exe_ctx, sc);

    if (!sc.symbol)
      return false;

    const char *cstr = sc.symbol->GetName().AsCString(nullptr);
    if (!cstr)
      return false;

    s.PutCString(cstr);

    return true;
  }
  case FunctionNameRepresentation::eNameWithNoArgs:
  case FunctionNameRepresentation::eName:
    return false;
  }
  llvm_unreachable("Fully covered switch above");
}

bool CPlusPlusLanguage::HandleFrameFormatVariable(
    const SymbolContext &sc, const ExecutionContext *exe_ctx,
    FormatEntity::Entry::Type type, Stream &s) {
  switch (type) {
  case FormatEntity::Entry::Type::FunctionScope: {
    auto scope_or_err = ::GetDemangledScope(sc);
    if (!scope_or_err) {
      LLDB_LOG_ERROR(
          GetLog(LLDBLog::Language), scope_or_err.takeError(),
          "Failed to handle ${{function.scope}} frame-format variable: {0}");
      return false;
    }

    s << *scope_or_err;

    return true;
  }

  case FormatEntity::Entry::Type::FunctionBasename: {
    auto name_or_err = ::GetDemangledBasename(sc);
    if (!name_or_err) {
      LLDB_LOG_ERROR(
          GetLog(LLDBLog::Language), name_or_err.takeError(),
          "Failed to handle ${{function.basename}} frame-format variable: {0}");
      return false;
    }

    s << *name_or_err;

    return true;
  }

  case FormatEntity::Entry::Type::FunctionTemplateArguments: {
    auto template_args_or_err = ::GetDemangledTemplateArguments(sc);
    if (!template_args_or_err) {
      LLDB_LOG_ERROR(GetLog(LLDBLog::Language),
                     template_args_or_err.takeError(),
                     "Failed to handle ${{function.template-arguments}} "
                     "frame-format variable: {0}");
      return false;
    }

    s << *template_args_or_err;

    return true;
  }

  case FormatEntity::Entry::Type::FunctionFormattedArguments: {
    // This ensures we print the arguments even when no debug-info is available.
    //
    // FIXME: we should have a Entry::Type::FunctionArguments and
    // use it in the plugin.cplusplus.display.function-name-format
    // once we have a "fallback operator" in the frame-format language.
    if (!sc.function && sc.symbol)
      return PrintDemangledArgumentList(s, sc);

    VariableList args;
    if (auto variable_list_sp = GetFunctionVariableList(sc))
      variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
                                                 args);

    ExecutionContextScope *exe_scope =
        exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;

    s << '(';
    FormatEntity::PrettyPrintFunctionArguments(s, args, exe_scope);
    s << ')';

    return true;
  }
  case FormatEntity::Entry::Type::FunctionReturnRight: {
    auto return_rhs_or_err = ::GetDemangledReturnTypeRHS(sc);
    if (!return_rhs_or_err) {
      LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_rhs_or_err.takeError(),
                     "Failed to handle ${{function.return-right}} frame-format "
                     "variable: {0}");
      return false;
    }

    s << *return_rhs_or_err;

    return true;
  }
  case FormatEntity::Entry::Type::FunctionReturnLeft: {
    auto return_lhs_or_err = ::GetDemangledReturnTypeLHS(sc);
    if (!return_lhs_or_err) {
      LLDB_LOG_ERROR(GetLog(LLDBLog::Language), return_lhs_or_err.takeError(),
                     "Failed to handle ${{function.return-left}} frame-format "
                     "variable: {0}");
      return false;
    }

    s << *return_lhs_or_err;

    return true;
  }
  case FormatEntity::Entry::Type::FunctionQualifiers: {
    auto quals_or_err = ::GetDemangledFunctionQualifiers(sc);
    if (!quals_or_err) {
      LLDB_LOG_ERROR(GetLog(LLDBLog::Language), quals_or_err.takeError(),
                     "Failed to handle ${{function.qualifiers}} frame-format "
                     "variable: {0}");
      return false;
    }

    s << *quals_or_err;

    return true;
  }
  case FormatEntity::Entry::Type::FunctionSuffix: {
    auto suffix_or_err = ::GetDemangledFunctionSuffix(sc);
    if (!suffix_or_err) {
      LLDB_LOG_ERROR(
          GetLog(LLDBLog::Language), suffix_or_err.takeError(),
          "Failed to handle ${{function.suffix}} frame-format variable: {0}");
      return false;
    }

    s << *suffix_or_err;

    return true;
  }
  default:
    return false;
  }
}

namespace {
class NodeAllocator {
  llvm::BumpPtrAllocator Alloc;

public:
  void reset() { Alloc.Reset(); }

  template <typename T, typename... Args> T *makeNode(Args &&...args) {
    return new (Alloc.Allocate(sizeof(T), alignof(T)))
        T(std::forward<Args>(args)...);
  }

  void *allocateNodeArray(size_t sz) {
    return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,
                          alignof(llvm::itanium_demangle::Node *));
  }
};

template <typename Derived>
class ManglingSubstitutor
    : public llvm::itanium_demangle::AbstractManglingParser<Derived,
                                                            NodeAllocator> {
  using Base =
      llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;

public:
  ManglingSubstitutor() : Base(nullptr, nullptr) {}

  template <typename... Ts>
  llvm::Expected<ConstString> substitute(llvm::StringRef Mangled,
                                         Ts &&...Vals) {
    this->getDerived().reset(Mangled, std::forward<Ts>(Vals)...);
    return substituteImpl(Mangled);
  }

protected:
  void reset(llvm::StringRef Mangled) {
    Base::reset(Mangled.begin(), Mangled.end());
    Written = Mangled.begin();
    Result.clear();
    Substituted = false;
  }

  llvm::Expected<ConstString> substituteImpl(llvm::StringRef Mangled) {
    if (this->parse() == nullptr)
      return llvm::createStringErrorV("failed to substitute mangling in '{0}'",
                                      Mangled);

    if (!Substituted)
      return ConstString();

    // Append any trailing unmodified input.
    appendUnchangedInput();
    return ConstString(Result);
  }

  void trySubstitute(llvm::StringRef From, llvm::StringRef To) {
    if (!llvm::StringRef(currentParserPos(), this->numLeft()).starts_with(From))
      return;

    // We found a match. Append unmodified input up to this point.
    appendUnchangedInput();

    // And then perform the replacement.
    Result += To;
    Written += From.size();
    Substituted = true;
  }

private:
  /// Input character until which we have constructed the respective output
  /// already.
  const char *Written = "";

  llvm::SmallString<128> Result;

  /// Whether we have performed any substitutions.
  bool Substituted = false;

  const char *currentParserPos() const { return this->First; }

  void appendUnchangedInput() {
    Result +=
        llvm::StringRef(Written, std::distance(Written, currentParserPos()));
    Written = currentParserPos();
  }
};

/// Given a mangled function `Mangled`, replace all the primitive function type
/// arguments of `Search` with type `Replace`.
class TypeSubstitutor : public ManglingSubstitutor<TypeSubstitutor> {
  llvm::StringRef Search;
  llvm::StringRef Replace;

public:
  void reset(llvm::StringRef Mangled, llvm::StringRef Search,
             llvm::StringRef Replace) {
    ManglingSubstitutor::reset(Mangled);
    this->Search = Search;
    this->Replace = Replace;
  }

  llvm::itanium_demangle::Node *parseType() {
    trySubstitute(Search, Replace);
    return ManglingSubstitutor::parseType();
  }
};

class CtorDtorSubstitutor : public ManglingSubstitutor<CtorDtorSubstitutor> {
  llvm::StringRef Search;
  llvm::StringRef Replace;

public:
  void reset(llvm::StringRef Mangled, llvm::StringRef Search,
             llvm::StringRef Replace) {
    ManglingSubstitutor::reset(Mangled);
    this->Search = Search;
    this->Replace = Replace;
  }

  void reset(llvm::StringRef Mangled) { ManglingSubstitutor::reset(Mangled); }

  llvm::itanium_demangle::Node *
  parseCtorDtorName(llvm::itanium_demangle::Node *&SoFar, NameState *State) {
    if (!Search.empty() && !Replace.empty()) {
      trySubstitute(Search, Replace);
    } else {
      trySubstitute("D1", "D2");
      trySubstitute("C1", "C2");
    }
    return ManglingSubstitutor::parseCtorDtorName(SoFar, State);
  }
};
} // namespace

llvm::Expected<ConstString>
CPlusPlusLanguage::SubstituteType_ItaniumMangle(llvm::StringRef mangled_name,
                                                llvm::StringRef subst_from,
                                                llvm::StringRef subst_to) {
  return TypeSubstitutor().substitute(mangled_name, subst_from, subst_to);
}

llvm::Expected<ConstString> CPlusPlusLanguage::SubstituteStructor_ItaniumMangle(
    llvm::StringRef mangled_name, llvm::StringRef subst_from,
    llvm::StringRef subst_to) {
  return CtorDtorSubstitutor().substitute(mangled_name, subst_from, subst_to);
}

llvm::Expected<ConstString>
CPlusPlusLanguage::SubstituteStructorAliases_ItaniumMangle(
    llvm::StringRef mangled_name) {
  return CtorDtorSubstitutor().substitute(mangled_name);
}

#define LLDB_PROPERTIES_language_cplusplus
#include "LanguageCPlusPlusProperties.inc"

enum {
#define LLDB_PROPERTIES_language_cplusplus
#include "LanguageCPlusPlusPropertiesEnum.inc"
};

namespace {
class PluginProperties : public Properties {
public:
  static llvm::StringRef GetSettingName() { return "display"; }

  PluginProperties() {
    m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
    m_collection_sp->Initialize(g_language_cplusplus_properties_def);
  }

  FormatEntity::Entry GetFunctionNameFormat() const {
    return GetPropertyAtIndexAs<FormatEntity::Entry>(
        ePropertyFunctionNameFormat, {});
  }
};
} // namespace

static PluginProperties &GetGlobalPluginProperties() {
  static PluginProperties g_settings;
  return g_settings;
}

FormatEntity::Entry CPlusPlusLanguage::GetFunctionNameFormat() const {
  return GetGlobalPluginProperties().GetFunctionNameFormat();
}

void CPlusPlusLanguage::DebuggerInitialize(Debugger &debugger) {
  if (!PluginManager::GetSettingForCPlusPlusLanguagePlugin(
          debugger, PluginProperties::GetSettingName())) {
    PluginManager::CreateSettingForCPlusPlusLanguagePlugin(
        debugger, GetGlobalPluginProperties().GetValueProperties(),
        "Properties for the CPlusPlus language plug-in.",
        /*is_global_property=*/true);
  }
}
