//===-- 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 <cstring>

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

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

#include "lldb/Core/DemangledNameInfo.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.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(ConstString full_name) const {
  std::unique_ptr<CxxMethodName> cpp_method =
      std::make_unique<CxxMethodName>(full_name);
  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);
  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 mangling_scheme == Mangled::eManglingSchemeItanium ||
         mangling_scheme == Mangled::eManglingSchemeMSVC;
}

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);
      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,
                                            char const *full_name,
                                            ExecutionContextScope *exe_scope,
                                            VariableList const &args) {
  CPlusPlusLanguage::CxxMethodName cpp_method{ConstString(full_name)};

  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 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::createStringError(
        "Function '%s' does not have a demangled name.",
        mangled.GetMangledName().AsCString(""));

  const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
  if (!info)
    return llvm::createStringError(
        "Function '%s' does not have demangled info.", demangled_name.data());

  // Function without a basename is nonsense.
  if (!info->hasBasename())
    return llvm::createStringError(
        "DemangledInfo for '%s does not have basename range.",
        demangled_name.data());

  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::createStringError(
        "Template arguments range for '%s' is invalid.", demangled.data());

  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::createStringError(
        "Scope range for '%s' LHS return type is invalid.", demangled.data());

  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::createStringError("Qualifiers range for '%s' is invalid.",
                                   demangled.data());

  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::createStringError(
        "Qualifiers range for '%s' RHS return type  is invalid.",
        demangled.data());

  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::createStringError("Scope range for '%s' is invalid.",
                                   demangled.data());

  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::createStringError("Suffix range for '%s' is invalid.",
                                   demangled.data());

  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::createStringError(
        "Function arguments range for '%s' is invalid.", demangled.data());

  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.GetCString());
  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) {
    if (TrySimplifiedParse()) {
      m_parse_error = false;
    } else {
      CPlusPlusNameParser parser(m_full.GetStringRef());
      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 m_full.GetStringRef().contains(path);

  llvm::StringRef identifier;
  llvm::StringRef context;
  const bool success =
      CPlusPlusLanguage::ExtractContextAndIdentifier(path, context, identifier);
  if (!success)
    return m_full.GetStringRef().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);
  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);
  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);
    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, LibcxxQueueFrontEndCreator,
                  "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);
}

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);
}

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);
}

/// 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);

  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);

  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);
}

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);
}

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();
  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::createStringError(
          llvm::formatv("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);
  }
}
