//===-- 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 "llvm/Support/ErrorExtras.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::createStringErrorV(
        "function '{0}' does not have a demangled name",
        mangled.GetMangledName());

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

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

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

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

  auto [demangled_name, info] = *info_or_err;

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

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

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

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

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

  auto [demangled_name, info] = *info_or_err;

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

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

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

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

  auto [demangled_name, info] = *info_or_err;

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

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

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

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

  auto [demangled_name, info] = *info_or_err;

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

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

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

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

  auto [demangled_name, info] = *info_or_err;

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

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

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

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

  auto [demangled_name, info] = *info_or_err;

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

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

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

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

  auto [demangled_name, info] = *info_or_err;

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

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

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

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

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

  auto [demangled_name, info] = *info_or_err;

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

  s << *args_or_err;

  return true;
}

bool CPlusPlusLanguage::CxxMethodName::TrySimplifiedParse() {
  // This method tries to parse simple method definitions which are presumably
  // most comman in user programs. Definitions that can be parsed by this
  // function don't have return types and templates in the name.
  // A::B::C::fun(std::vector<T> &) const
  size_t arg_start, arg_end;
  llvm::StringRef full(m_full.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(nullptr);
  if (!cstr)
    return false;

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

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

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

  return true;
}

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

    if (!sc.symbol)
      return false;

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

    s.PutCString(cstr);

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

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

    s << *scope_or_err;

    return true;
  }

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

    s << *name_or_err;

    return true;
  }

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

    s << *template_args_or_err;

    return true;
  }

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

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

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

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

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

    s << *return_rhs_or_err;

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

    s << *return_lhs_or_err;

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

    s << *quals_or_err;

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

    s << *suffix_or_err;

    return true;
  }
  default:
    return false;
  }
}

namespace {
class NodeAllocator {
  llvm::BumpPtrAllocator Alloc;

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

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

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

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

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

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

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

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

    if (!Substituted)
      return ConstString();

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

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

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

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

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

  llvm::SmallString<128> Result;

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

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

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

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

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

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

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

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

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

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

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

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

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

#define LLDB_PROPERTIES_language_cplusplus
#include "LanguageCPlusPlusProperties.inc"

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

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

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

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

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

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

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