xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- CPlusPlusLanguage.cpp ---------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "CPlusPlusLanguage.h"
10061da546Spatrick 
11061da546Spatrick #include <cctype>
12061da546Spatrick #include <cstring>
13061da546Spatrick 
14061da546Spatrick #include <functional>
15061da546Spatrick #include <memory>
16061da546Spatrick #include <mutex>
17061da546Spatrick #include <set>
18061da546Spatrick 
19061da546Spatrick #include "llvm/ADT/StringRef.h"
20061da546Spatrick #include "llvm/Demangle/ItaniumDemangle.h"
21061da546Spatrick 
22061da546Spatrick #include "lldb/Core/Mangled.h"
23*f6aab3d8Srobert #include "lldb/Core/Module.h"
24061da546Spatrick #include "lldb/Core/PluginManager.h"
25061da546Spatrick #include "lldb/Core/UniqueCStringMap.h"
26*f6aab3d8Srobert #include "lldb/Core/ValueObjectVariable.h"
27061da546Spatrick #include "lldb/DataFormatters/CXXFunctionPointer.h"
28061da546Spatrick #include "lldb/DataFormatters/DataVisualization.h"
29061da546Spatrick #include "lldb/DataFormatters/FormattersHelpers.h"
30061da546Spatrick #include "lldb/DataFormatters/VectorType.h"
31*f6aab3d8Srobert #include "lldb/Symbol/SymbolFile.h"
32*f6aab3d8Srobert #include "lldb/Symbol/VariableList.h"
33061da546Spatrick #include "lldb/Utility/ConstString.h"
34*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
35061da546Spatrick #include "lldb/Utility/Log.h"
36061da546Spatrick #include "lldb/Utility/RegularExpression.h"
37061da546Spatrick 
38061da546Spatrick #include "BlockPointer.h"
39061da546Spatrick #include "CPlusPlusNameParser.h"
40*f6aab3d8Srobert #include "Coroutines.h"
41061da546Spatrick #include "CxxStringTypes.h"
42*f6aab3d8Srobert #include "Generic.h"
43061da546Spatrick #include "LibCxx.h"
44061da546Spatrick #include "LibCxxAtomic.h"
45061da546Spatrick #include "LibCxxVariant.h"
46061da546Spatrick #include "LibStdcpp.h"
47061da546Spatrick #include "MSVCUndecoratedNameParser.h"
48061da546Spatrick 
49061da546Spatrick using namespace lldb;
50061da546Spatrick using namespace lldb_private;
51061da546Spatrick using namespace lldb_private::formatters;
52061da546Spatrick 
LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)53dda28197Spatrick LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)
54dda28197Spatrick 
55061da546Spatrick void CPlusPlusLanguage::Initialize() {
56061da546Spatrick   PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
57061da546Spatrick                                 CreateInstance);
58061da546Spatrick }
59061da546Spatrick 
Terminate()60061da546Spatrick void CPlusPlusLanguage::Terminate() {
61061da546Spatrick   PluginManager::UnregisterPlugin(CreateInstance);
62061da546Spatrick }
63061da546Spatrick 
SymbolNameFitsToLanguage(Mangled mangled) const64be691f3bSpatrick bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
65be691f3bSpatrick   const char *mangled_name = mangled.GetMangledName().GetCString();
66be691f3bSpatrick   return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name);
67be691f3bSpatrick }
68be691f3bSpatrick 
GetDemangledFunctionNameWithoutArguments(Mangled mangled) const69*f6aab3d8Srobert ConstString CPlusPlusLanguage::GetDemangledFunctionNameWithoutArguments(
70*f6aab3d8Srobert     Mangled mangled) const {
71*f6aab3d8Srobert   const char *mangled_name_cstr = mangled.GetMangledName().GetCString();
72*f6aab3d8Srobert   ConstString demangled_name = mangled.GetDemangledName();
73*f6aab3d8Srobert   if (demangled_name && mangled_name_cstr && mangled_name_cstr[0]) {
74*f6aab3d8Srobert     if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
75*f6aab3d8Srobert         (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
76*f6aab3d8Srobert                                         // typeinfo structure, and typeinfo
77*f6aab3d8Srobert                                         // mangled_name
78*f6aab3d8Srobert          mangled_name_cstr[2] != 'G' && // avoid guard variables
79*f6aab3d8Srobert          mangled_name_cstr[2] != 'Z'))  // named local entities (if we
80*f6aab3d8Srobert                                         // eventually handle eSymbolTypeData,
81*f6aab3d8Srobert                                         // we will want this back)
82*f6aab3d8Srobert     {
83*f6aab3d8Srobert       CPlusPlusLanguage::MethodName cxx_method(demangled_name);
84*f6aab3d8Srobert       if (!cxx_method.GetBasename().empty()) {
85*f6aab3d8Srobert         std::string shortname;
86*f6aab3d8Srobert         if (!cxx_method.GetContext().empty())
87*f6aab3d8Srobert           shortname = cxx_method.GetContext().str() + "::";
88*f6aab3d8Srobert         shortname += cxx_method.GetBasename().str();
89*f6aab3d8Srobert         return ConstString(shortname);
90061da546Spatrick       }
91*f6aab3d8Srobert     }
92*f6aab3d8Srobert   }
93*f6aab3d8Srobert   if (demangled_name)
94*f6aab3d8Srobert     return demangled_name;
95*f6aab3d8Srobert   return mangled.GetMangledName();
96*f6aab3d8Srobert }
97061da546Spatrick 
98061da546Spatrick // Static Functions
99061da546Spatrick 
CreateInstance(lldb::LanguageType language)100061da546Spatrick Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
101dda28197Spatrick   // Use plugin for C++ but not for Objective-C++ (which has its own plugin).
102dda28197Spatrick   if (Language::LanguageIsCPlusPlus(language) &&
103dda28197Spatrick       language != eLanguageTypeObjC_plus_plus)
104061da546Spatrick     return new CPlusPlusLanguage();
105061da546Spatrick   return nullptr;
106061da546Spatrick }
107061da546Spatrick 
Clear()108061da546Spatrick void CPlusPlusLanguage::MethodName::Clear() {
109061da546Spatrick   m_full.Clear();
110061da546Spatrick   m_basename = llvm::StringRef();
111061da546Spatrick   m_context = llvm::StringRef();
112061da546Spatrick   m_arguments = llvm::StringRef();
113061da546Spatrick   m_qualifiers = llvm::StringRef();
114*f6aab3d8Srobert   m_return_type = llvm::StringRef();
115061da546Spatrick   m_parsed = false;
116061da546Spatrick   m_parse_error = false;
117061da546Spatrick }
118061da546Spatrick 
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)119061da546Spatrick static bool ReverseFindMatchingChars(const llvm::StringRef &s,
120061da546Spatrick                                      const llvm::StringRef &left_right_chars,
121061da546Spatrick                                      size_t &left_pos, size_t &right_pos,
122061da546Spatrick                                      size_t pos = llvm::StringRef::npos) {
123061da546Spatrick   assert(left_right_chars.size() == 2);
124061da546Spatrick   left_pos = llvm::StringRef::npos;
125061da546Spatrick   const char left_char = left_right_chars[0];
126061da546Spatrick   const char right_char = left_right_chars[1];
127061da546Spatrick   pos = s.find_last_of(left_right_chars, pos);
128061da546Spatrick   if (pos == llvm::StringRef::npos || s[pos] == left_char)
129061da546Spatrick     return false;
130061da546Spatrick   right_pos = pos;
131061da546Spatrick   uint32_t depth = 1;
132061da546Spatrick   while (pos > 0 && depth > 0) {
133061da546Spatrick     pos = s.find_last_of(left_right_chars, pos);
134061da546Spatrick     if (pos == llvm::StringRef::npos)
135061da546Spatrick       return false;
136061da546Spatrick     if (s[pos] == left_char) {
137061da546Spatrick       if (--depth == 0) {
138061da546Spatrick         left_pos = pos;
139061da546Spatrick         return left_pos < right_pos;
140061da546Spatrick       }
141061da546Spatrick     } else if (s[pos] == right_char) {
142061da546Spatrick       ++depth;
143061da546Spatrick     }
144061da546Spatrick   }
145061da546Spatrick   return false;
146061da546Spatrick }
147061da546Spatrick 
IsTrivialBasename(const llvm::StringRef & basename)148061da546Spatrick static bool IsTrivialBasename(const llvm::StringRef &basename) {
149061da546Spatrick   // Check that the basename matches with the following regular expression
150061da546Spatrick   // "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation
151061da546Spatrick   // because it is significantly more efficient then using the general purpose
152061da546Spatrick   // regular expression library.
153061da546Spatrick   size_t idx = 0;
154061da546Spatrick   if (basename.size() > 0 && basename[0] == '~')
155061da546Spatrick     idx = 1;
156061da546Spatrick 
157061da546Spatrick   if (basename.size() <= idx)
158061da546Spatrick     return false; // Empty string or "~"
159061da546Spatrick 
160061da546Spatrick   if (!std::isalpha(basename[idx]) && basename[idx] != '_')
161dda28197Spatrick     return false; // First character (after removing the possible '~'') isn't in
162061da546Spatrick                   // [A-Za-z_]
163061da546Spatrick 
164061da546Spatrick   // Read all characters matching [A-Za-z_0-9]
165061da546Spatrick   ++idx;
166061da546Spatrick   while (idx < basename.size()) {
167061da546Spatrick     if (!std::isalnum(basename[idx]) && basename[idx] != '_')
168061da546Spatrick       break;
169061da546Spatrick     ++idx;
170061da546Spatrick   }
171061da546Spatrick 
172061da546Spatrick   // We processed all characters. It is a vaild basename.
173061da546Spatrick   return idx == basename.size();
174061da546Spatrick }
175061da546Spatrick 
176*f6aab3d8Srobert /// Writes out the function name in 'full_name' to 'out_stream'
177*f6aab3d8Srobert /// but replaces each argument type with the variable name
178*f6aab3d8Srobert /// and the corresponding pretty-printed value
PrettyPrintFunctionNameWithArgs(Stream & out_stream,char const * full_name,ExecutionContextScope * exe_scope,VariableList const & args)179*f6aab3d8Srobert static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream,
180*f6aab3d8Srobert                                             char const *full_name,
181*f6aab3d8Srobert                                             ExecutionContextScope *exe_scope,
182*f6aab3d8Srobert                                             VariableList const &args) {
183*f6aab3d8Srobert   CPlusPlusLanguage::MethodName cpp_method{ConstString(full_name)};
184*f6aab3d8Srobert 
185*f6aab3d8Srobert   if (!cpp_method.IsValid())
186*f6aab3d8Srobert     return false;
187*f6aab3d8Srobert 
188*f6aab3d8Srobert   llvm::StringRef return_type = cpp_method.GetReturnType();
189*f6aab3d8Srobert   if (!return_type.empty()) {
190*f6aab3d8Srobert     out_stream.PutCString(return_type);
191*f6aab3d8Srobert     out_stream.PutChar(' ');
192*f6aab3d8Srobert   }
193*f6aab3d8Srobert 
194*f6aab3d8Srobert   out_stream.PutCString(cpp_method.GetScopeQualifiedName());
195*f6aab3d8Srobert   out_stream.PutChar('(');
196*f6aab3d8Srobert 
197*f6aab3d8Srobert   FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope);
198*f6aab3d8Srobert 
199*f6aab3d8Srobert   out_stream.PutChar(')');
200*f6aab3d8Srobert 
201*f6aab3d8Srobert   llvm::StringRef qualifiers = cpp_method.GetQualifiers();
202*f6aab3d8Srobert   if (!qualifiers.empty()) {
203*f6aab3d8Srobert     out_stream.PutChar(' ');
204*f6aab3d8Srobert     out_stream.PutCString(qualifiers);
205*f6aab3d8Srobert   }
206*f6aab3d8Srobert 
207*f6aab3d8Srobert   return true;
208*f6aab3d8Srobert }
209*f6aab3d8Srobert 
TrySimplifiedParse()210061da546Spatrick bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
211061da546Spatrick   // This method tries to parse simple method definitions which are presumably
212061da546Spatrick   // most comman in user programs. Definitions that can be parsed by this
213061da546Spatrick   // function don't have return types and templates in the name.
214061da546Spatrick   // A::B::C::fun(std::vector<T> &) const
215061da546Spatrick   size_t arg_start, arg_end;
216061da546Spatrick   llvm::StringRef full(m_full.GetCString());
217061da546Spatrick   llvm::StringRef parens("()", 2);
218061da546Spatrick   if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {
219061da546Spatrick     m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
220061da546Spatrick     if (arg_end + 1 < full.size())
221061da546Spatrick       m_qualifiers = full.substr(arg_end + 1).ltrim();
222061da546Spatrick 
223061da546Spatrick     if (arg_start == 0)
224061da546Spatrick       return false;
225061da546Spatrick     size_t basename_end = arg_start;
226061da546Spatrick     size_t context_start = 0;
227061da546Spatrick     size_t context_end = full.rfind(':', basename_end);
228061da546Spatrick     if (context_end == llvm::StringRef::npos)
229061da546Spatrick       m_basename = full.substr(0, basename_end);
230061da546Spatrick     else {
231061da546Spatrick       if (context_start < context_end)
232061da546Spatrick         m_context = full.substr(context_start, context_end - 1 - context_start);
233061da546Spatrick       const size_t basename_begin = context_end + 1;
234061da546Spatrick       m_basename = full.substr(basename_begin, basename_end - basename_begin);
235061da546Spatrick     }
236061da546Spatrick 
237061da546Spatrick     if (IsTrivialBasename(m_basename)) {
238061da546Spatrick       return true;
239061da546Spatrick     } else {
240061da546Spatrick       // The C++ basename doesn't match our regular expressions so this can't
241061da546Spatrick       // be a valid C++ method, clear everything out and indicate an error
242061da546Spatrick       m_context = llvm::StringRef();
243061da546Spatrick       m_basename = llvm::StringRef();
244061da546Spatrick       m_arguments = llvm::StringRef();
245061da546Spatrick       m_qualifiers = llvm::StringRef();
246*f6aab3d8Srobert       m_return_type = llvm::StringRef();
247061da546Spatrick       return false;
248061da546Spatrick     }
249061da546Spatrick   }
250061da546Spatrick   return false;
251061da546Spatrick }
252061da546Spatrick 
Parse()253061da546Spatrick void CPlusPlusLanguage::MethodName::Parse() {
254061da546Spatrick   if (!m_parsed && m_full) {
255061da546Spatrick     if (TrySimplifiedParse()) {
256061da546Spatrick       m_parse_error = false;
257061da546Spatrick     } else {
258061da546Spatrick       CPlusPlusNameParser parser(m_full.GetStringRef());
259061da546Spatrick       if (auto function = parser.ParseAsFunctionDefinition()) {
260*f6aab3d8Srobert         m_basename = function->name.basename;
261*f6aab3d8Srobert         m_context = function->name.context;
262*f6aab3d8Srobert         m_arguments = function->arguments;
263*f6aab3d8Srobert         m_qualifiers = function->qualifiers;
264*f6aab3d8Srobert         m_return_type = function->return_type;
265061da546Spatrick         m_parse_error = false;
266061da546Spatrick       } else {
267061da546Spatrick         m_parse_error = true;
268061da546Spatrick       }
269061da546Spatrick     }
270061da546Spatrick     m_parsed = true;
271061da546Spatrick   }
272061da546Spatrick }
273061da546Spatrick 
GetBasename()274061da546Spatrick llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() {
275061da546Spatrick   if (!m_parsed)
276061da546Spatrick     Parse();
277061da546Spatrick   return m_basename;
278061da546Spatrick }
279061da546Spatrick 
GetContext()280061da546Spatrick llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() {
281061da546Spatrick   if (!m_parsed)
282061da546Spatrick     Parse();
283061da546Spatrick   return m_context;
284061da546Spatrick }
285061da546Spatrick 
GetArguments()286061da546Spatrick llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() {
287061da546Spatrick   if (!m_parsed)
288061da546Spatrick     Parse();
289061da546Spatrick   return m_arguments;
290061da546Spatrick }
291061da546Spatrick 
GetQualifiers()292061da546Spatrick llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() {
293061da546Spatrick   if (!m_parsed)
294061da546Spatrick     Parse();
295061da546Spatrick   return m_qualifiers;
296061da546Spatrick }
297061da546Spatrick 
GetReturnType()298*f6aab3d8Srobert llvm::StringRef CPlusPlusLanguage::MethodName::GetReturnType() {
299*f6aab3d8Srobert   if (!m_parsed)
300*f6aab3d8Srobert     Parse();
301*f6aab3d8Srobert   return m_return_type;
302*f6aab3d8Srobert }
303*f6aab3d8Srobert 
GetScopeQualifiedName()304061da546Spatrick std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
305061da546Spatrick   if (!m_parsed)
306061da546Spatrick     Parse();
307061da546Spatrick   if (m_context.empty())
308dda28197Spatrick     return std::string(m_basename);
309061da546Spatrick 
310061da546Spatrick   std::string res;
311061da546Spatrick   res += m_context;
312061da546Spatrick   res += "::";
313061da546Spatrick   res += m_basename;
314061da546Spatrick   return res;
315061da546Spatrick }
316061da546Spatrick 
317*f6aab3d8Srobert llvm::StringRef
GetBasenameNoTemplateParameters()318*f6aab3d8Srobert CPlusPlusLanguage::MethodName::GetBasenameNoTemplateParameters() {
319*f6aab3d8Srobert   llvm::StringRef basename = GetBasename();
320*f6aab3d8Srobert   size_t arg_start, arg_end;
321*f6aab3d8Srobert   llvm::StringRef parens("<>", 2);
322*f6aab3d8Srobert   if (ReverseFindMatchingChars(basename, parens, arg_start, arg_end))
323*f6aab3d8Srobert     return basename.substr(0, arg_start);
324*f6aab3d8Srobert 
325*f6aab3d8Srobert   return basename;
326*f6aab3d8Srobert }
327*f6aab3d8Srobert 
ContainsPath(llvm::StringRef path)328*f6aab3d8Srobert bool CPlusPlusLanguage::MethodName::ContainsPath(llvm::StringRef path) {
329*f6aab3d8Srobert   if (!m_parsed)
330*f6aab3d8Srobert     Parse();
331*f6aab3d8Srobert 
332*f6aab3d8Srobert   // If we can't parse the incoming name, then just check that it contains path.
333*f6aab3d8Srobert   if (m_parse_error)
334*f6aab3d8Srobert     return m_full.GetStringRef().contains(path);
335*f6aab3d8Srobert 
336*f6aab3d8Srobert   llvm::StringRef identifier;
337*f6aab3d8Srobert   llvm::StringRef context;
338*f6aab3d8Srobert   std::string path_str = path.str();
339*f6aab3d8Srobert   bool success
340*f6aab3d8Srobert       = CPlusPlusLanguage::ExtractContextAndIdentifier(path_str.c_str(),
341*f6aab3d8Srobert                                                        context,
342*f6aab3d8Srobert                                                        identifier);
343*f6aab3d8Srobert   if (!success)
344*f6aab3d8Srobert     return m_full.GetStringRef().contains(path);
345*f6aab3d8Srobert 
346*f6aab3d8Srobert   // Basename may include template arguments.
347*f6aab3d8Srobert   // E.g.,
348*f6aab3d8Srobert   // GetBaseName(): func<int>
349*f6aab3d8Srobert   // identifier   : func
350*f6aab3d8Srobert   //
351*f6aab3d8Srobert   // ...but we still want to account for identifiers with template parameter
352*f6aab3d8Srobert   // lists, e.g., when users set breakpoints on template specializations.
353*f6aab3d8Srobert   //
354*f6aab3d8Srobert   // E.g.,
355*f6aab3d8Srobert   // GetBaseName(): func<uint32_t>
356*f6aab3d8Srobert   // identifier   : func<int32_t*>
357*f6aab3d8Srobert   //
358*f6aab3d8Srobert   // Try to match the basename with or without template parameters.
359*f6aab3d8Srobert   if (GetBasename() != identifier &&
360*f6aab3d8Srobert       GetBasenameNoTemplateParameters() != identifier)
361*f6aab3d8Srobert     return false;
362*f6aab3d8Srobert 
363*f6aab3d8Srobert   // Incoming path only had an identifier, so we match.
364*f6aab3d8Srobert   if (context.empty())
365*f6aab3d8Srobert     return true;
366*f6aab3d8Srobert   // Incoming path has context but this method does not, no match.
367*f6aab3d8Srobert   if (m_context.empty())
368*f6aab3d8Srobert     return false;
369*f6aab3d8Srobert 
370*f6aab3d8Srobert   llvm::StringRef haystack = m_context;
371*f6aab3d8Srobert   if (!haystack.consume_back(context))
372*f6aab3d8Srobert     return false;
373*f6aab3d8Srobert   if (haystack.empty() || !isalnum(haystack.back()))
374*f6aab3d8Srobert     return true;
375*f6aab3d8Srobert 
376*f6aab3d8Srobert   return false;
377*f6aab3d8Srobert }
378*f6aab3d8Srobert 
IsCPPMangledName(llvm::StringRef name)379061da546Spatrick bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) {
380061da546Spatrick   // FIXME!! we should really run through all the known C++ Language plugins
381061da546Spatrick   // and ask each one if this is a C++ mangled name
382061da546Spatrick 
383061da546Spatrick   Mangled::ManglingScheme scheme = Mangled::GetManglingScheme(name);
384061da546Spatrick 
385061da546Spatrick   if (scheme == Mangled::eManglingSchemeNone)
386061da546Spatrick     return false;
387061da546Spatrick 
388061da546Spatrick   return true;
389061da546Spatrick }
390061da546Spatrick 
DemangledNameContainsPath(llvm::StringRef path,ConstString demangled) const391*f6aab3d8Srobert bool CPlusPlusLanguage::DemangledNameContainsPath(llvm::StringRef path,
392*f6aab3d8Srobert                                                   ConstString demangled) const {
393*f6aab3d8Srobert   MethodName demangled_name(demangled);
394*f6aab3d8Srobert   return demangled_name.ContainsPath(path);
395*f6aab3d8Srobert }
396*f6aab3d8Srobert 
ExtractContextAndIdentifier(const char * name,llvm::StringRef & context,llvm::StringRef & identifier)397061da546Spatrick bool CPlusPlusLanguage::ExtractContextAndIdentifier(
398061da546Spatrick     const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
399061da546Spatrick   if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name))
400061da546Spatrick     return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context,
401061da546Spatrick                                                                   identifier);
402061da546Spatrick 
403061da546Spatrick   CPlusPlusNameParser parser(name);
404061da546Spatrick   if (auto full_name = parser.ParseAsFullName()) {
405*f6aab3d8Srobert     identifier = full_name->basename;
406*f6aab3d8Srobert     context = full_name->context;
407061da546Spatrick     return true;
408061da546Spatrick   }
409061da546Spatrick   return false;
410061da546Spatrick }
411061da546Spatrick 
412061da546Spatrick namespace {
413061da546Spatrick class NodeAllocator {
414061da546Spatrick   llvm::BumpPtrAllocator Alloc;
415061da546Spatrick 
416061da546Spatrick public:
reset()417061da546Spatrick   void reset() { Alloc.Reset(); }
418061da546Spatrick 
makeNode(Args &&...args)419061da546Spatrick   template <typename T, typename... Args> T *makeNode(Args &&... args) {
420061da546Spatrick     return new (Alloc.Allocate(sizeof(T), alignof(T)))
421061da546Spatrick         T(std::forward<Args>(args)...);
422061da546Spatrick   }
423061da546Spatrick 
allocateNodeArray(size_t sz)424061da546Spatrick   void *allocateNodeArray(size_t sz) {
425061da546Spatrick     return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,
426061da546Spatrick                           alignof(llvm::itanium_demangle::Node *));
427061da546Spatrick   }
428061da546Spatrick };
429061da546Spatrick 
430061da546Spatrick template <typename Derived>
431061da546Spatrick class ManglingSubstitutor
432061da546Spatrick     : public llvm::itanium_demangle::AbstractManglingParser<Derived,
433061da546Spatrick                                                             NodeAllocator> {
434061da546Spatrick   using Base =
435061da546Spatrick       llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
436061da546Spatrick 
437061da546Spatrick public:
ManglingSubstitutor()438061da546Spatrick   ManglingSubstitutor() : Base(nullptr, nullptr) {}
439061da546Spatrick 
440061da546Spatrick   template <typename... Ts>
substitute(llvm::StringRef Mangled,Ts &&...Vals)441061da546Spatrick   ConstString substitute(llvm::StringRef Mangled, Ts &&... Vals) {
442061da546Spatrick     this->getDerived().reset(Mangled, std::forward<Ts>(Vals)...);
443061da546Spatrick     return substituteImpl(Mangled);
444061da546Spatrick   }
445061da546Spatrick 
446061da546Spatrick protected:
reset(llvm::StringRef Mangled)447061da546Spatrick   void reset(llvm::StringRef Mangled) {
448061da546Spatrick     Base::reset(Mangled.begin(), Mangled.end());
449061da546Spatrick     Written = Mangled.begin();
450061da546Spatrick     Result.clear();
451061da546Spatrick     Substituted = false;
452061da546Spatrick   }
453061da546Spatrick 
substituteImpl(llvm::StringRef Mangled)454061da546Spatrick   ConstString substituteImpl(llvm::StringRef Mangled) {
455*f6aab3d8Srobert     Log *log = GetLog(LLDBLog::Language);
456061da546Spatrick     if (this->parse() == nullptr) {
457061da546Spatrick       LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled);
458061da546Spatrick       return ConstString();
459061da546Spatrick     }
460061da546Spatrick     if (!Substituted)
461061da546Spatrick       return ConstString();
462061da546Spatrick 
463061da546Spatrick     // Append any trailing unmodified input.
464061da546Spatrick     appendUnchangedInput();
465061da546Spatrick     LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
466061da546Spatrick     return ConstString(Result);
467061da546Spatrick   }
468061da546Spatrick 
trySubstitute(llvm::StringRef From,llvm::StringRef To)469061da546Spatrick   void trySubstitute(llvm::StringRef From, llvm::StringRef To) {
470061da546Spatrick     if (!llvm::StringRef(currentParserPos(), this->numLeft()).startswith(From))
471061da546Spatrick       return;
472061da546Spatrick 
473061da546Spatrick     // We found a match. Append unmodified input up to this point.
474061da546Spatrick     appendUnchangedInput();
475061da546Spatrick 
476061da546Spatrick     // And then perform the replacement.
477061da546Spatrick     Result += To;
478061da546Spatrick     Written += From.size();
479061da546Spatrick     Substituted = true;
480061da546Spatrick   }
481061da546Spatrick 
482061da546Spatrick private:
483061da546Spatrick   /// Input character until which we have constructed the respective output
484061da546Spatrick   /// already.
485*f6aab3d8Srobert   const char *Written = "";
486061da546Spatrick 
487061da546Spatrick   llvm::SmallString<128> Result;
488061da546Spatrick 
489061da546Spatrick   /// Whether we have performed any substitutions.
490*f6aab3d8Srobert   bool Substituted = false;
491061da546Spatrick 
currentParserPos() const492061da546Spatrick   const char *currentParserPos() const { return this->First; }
493061da546Spatrick 
appendUnchangedInput()494061da546Spatrick   void appendUnchangedInput() {
495061da546Spatrick     Result +=
496061da546Spatrick         llvm::StringRef(Written, std::distance(Written, currentParserPos()));
497061da546Spatrick     Written = currentParserPos();
498061da546Spatrick   }
499061da546Spatrick };
500061da546Spatrick 
501061da546Spatrick /// Given a mangled function `Mangled`, replace all the primitive function type
502061da546Spatrick /// arguments of `Search` with type `Replace`.
503061da546Spatrick class TypeSubstitutor : public ManglingSubstitutor<TypeSubstitutor> {
504061da546Spatrick   llvm::StringRef Search;
505061da546Spatrick   llvm::StringRef Replace;
506061da546Spatrick 
507061da546Spatrick public:
reset(llvm::StringRef Mangled,llvm::StringRef Search,llvm::StringRef Replace)508061da546Spatrick   void reset(llvm::StringRef Mangled, llvm::StringRef Search,
509061da546Spatrick              llvm::StringRef Replace) {
510061da546Spatrick     ManglingSubstitutor::reset(Mangled);
511061da546Spatrick     this->Search = Search;
512061da546Spatrick     this->Replace = Replace;
513061da546Spatrick   }
514061da546Spatrick 
parseType()515061da546Spatrick   llvm::itanium_demangle::Node *parseType() {
516061da546Spatrick     trySubstitute(Search, Replace);
517061da546Spatrick     return ManglingSubstitutor::parseType();
518061da546Spatrick   }
519061da546Spatrick };
520061da546Spatrick 
521061da546Spatrick class CtorDtorSubstitutor : public ManglingSubstitutor<CtorDtorSubstitutor> {
522061da546Spatrick public:
523061da546Spatrick   llvm::itanium_demangle::Node *
parseCtorDtorName(llvm::itanium_demangle::Node * & SoFar,NameState * State)524061da546Spatrick   parseCtorDtorName(llvm::itanium_demangle::Node *&SoFar, NameState *State) {
525061da546Spatrick     trySubstitute("C1", "C2");
526061da546Spatrick     trySubstitute("D1", "D2");
527061da546Spatrick     return ManglingSubstitutor::parseCtorDtorName(SoFar, State);
528061da546Spatrick   }
529061da546Spatrick };
530061da546Spatrick } // namespace
531061da546Spatrick 
GenerateAlternateFunctionManglings(const ConstString mangled_name) const532*f6aab3d8Srobert std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings(
533*f6aab3d8Srobert     const ConstString mangled_name) const {
534*f6aab3d8Srobert   std::vector<ConstString> alternates;
535*f6aab3d8Srobert 
536061da546Spatrick   /// Get a basic set of alternative manglings for the given symbol `name`, by
537061da546Spatrick   /// making a few basic possible substitutions on basic types, storage duration
538061da546Spatrick   /// and `const`ness for the given symbol. The output parameter `alternates`
539061da546Spatrick   /// is filled with a best-guess, non-exhaustive set of different manglings
540061da546Spatrick   /// for the given name.
541061da546Spatrick 
542061da546Spatrick   // Maybe we're looking for a const symbol but the debug info told us it was
543061da546Spatrick   // non-const...
544061da546Spatrick   if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&
545061da546Spatrick       strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
546061da546Spatrick     std::string fixed_scratch("_ZNK");
547061da546Spatrick     fixed_scratch.append(mangled_name.GetCString() + 3);
548*f6aab3d8Srobert     alternates.push_back(ConstString(fixed_scratch));
549061da546Spatrick   }
550061da546Spatrick 
551061da546Spatrick   // Maybe we're looking for a static symbol but we thought it was global...
552061da546Spatrick   if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&
553061da546Spatrick       strncmp(mangled_name.GetCString(), "_ZL", 3)) {
554061da546Spatrick     std::string fixed_scratch("_ZL");
555061da546Spatrick     fixed_scratch.append(mangled_name.GetCString() + 2);
556*f6aab3d8Srobert     alternates.push_back(ConstString(fixed_scratch));
557061da546Spatrick   }
558061da546Spatrick 
559061da546Spatrick   TypeSubstitutor TS;
560061da546Spatrick   // `char` is implementation defined as either `signed` or `unsigned`.  As a
561061da546Spatrick   // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
562061da546Spatrick   // char, 'h'-unsigned char.  If we're looking for symbols with a signed char
563061da546Spatrick   // parameter, try finding matches which have the general case 'c'.
564061da546Spatrick   if (ConstString char_fixup =
565061da546Spatrick           TS.substitute(mangled_name.GetStringRef(), "a", "c"))
566*f6aab3d8Srobert     alternates.push_back(char_fixup);
567061da546Spatrick 
568061da546Spatrick   // long long parameter mangling 'x', may actually just be a long 'l' argument
569061da546Spatrick   if (ConstString long_fixup =
570061da546Spatrick           TS.substitute(mangled_name.GetStringRef(), "x", "l"))
571*f6aab3d8Srobert     alternates.push_back(long_fixup);
572061da546Spatrick 
573061da546Spatrick   // unsigned long long parameter mangling 'y', may actually just be unsigned
574061da546Spatrick   // long 'm' argument
575061da546Spatrick   if (ConstString ulong_fixup =
576061da546Spatrick           TS.substitute(mangled_name.GetStringRef(), "y", "m"))
577*f6aab3d8Srobert     alternates.push_back(ulong_fixup);
578061da546Spatrick 
579061da546Spatrick   if (ConstString ctor_fixup =
580061da546Spatrick           CtorDtorSubstitutor().substitute(mangled_name.GetStringRef()))
581*f6aab3d8Srobert     alternates.push_back(ctor_fixup);
582061da546Spatrick 
583*f6aab3d8Srobert   return alternates;
584*f6aab3d8Srobert }
585*f6aab3d8Srobert 
FindBestAlternateFunctionMangledName(const Mangled mangled,const SymbolContext & sym_ctx) const586*f6aab3d8Srobert ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName(
587*f6aab3d8Srobert     const Mangled mangled, const SymbolContext &sym_ctx) const {
588*f6aab3d8Srobert   ConstString demangled = mangled.GetDemangledName();
589*f6aab3d8Srobert   if (!demangled)
590*f6aab3d8Srobert     return ConstString();
591*f6aab3d8Srobert 
592*f6aab3d8Srobert   CPlusPlusLanguage::MethodName cpp_name(demangled);
593*f6aab3d8Srobert   std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
594*f6aab3d8Srobert 
595*f6aab3d8Srobert   if (!scope_qualified_name.size())
596*f6aab3d8Srobert     return ConstString();
597*f6aab3d8Srobert 
598*f6aab3d8Srobert   if (!sym_ctx.module_sp)
599*f6aab3d8Srobert     return ConstString();
600*f6aab3d8Srobert 
601*f6aab3d8Srobert   lldb_private::SymbolFile *sym_file = sym_ctx.module_sp->GetSymbolFile();
602*f6aab3d8Srobert   if (!sym_file)
603*f6aab3d8Srobert     return ConstString();
604*f6aab3d8Srobert 
605*f6aab3d8Srobert   std::vector<ConstString> alternates;
606*f6aab3d8Srobert   sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
607*f6aab3d8Srobert 
608*f6aab3d8Srobert   std::vector<ConstString> param_and_qual_matches;
609*f6aab3d8Srobert   std::vector<ConstString> param_matches;
610*f6aab3d8Srobert   for (size_t i = 0; i < alternates.size(); i++) {
611*f6aab3d8Srobert     ConstString alternate_mangled_name = alternates[i];
612*f6aab3d8Srobert     Mangled mangled(alternate_mangled_name);
613*f6aab3d8Srobert     ConstString demangled = mangled.GetDemangledName();
614*f6aab3d8Srobert 
615*f6aab3d8Srobert     CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
616*f6aab3d8Srobert     if (!cpp_name.IsValid())
617*f6aab3d8Srobert       continue;
618*f6aab3d8Srobert 
619*f6aab3d8Srobert     if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) {
620*f6aab3d8Srobert       if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
621*f6aab3d8Srobert         param_and_qual_matches.push_back(alternate_mangled_name);
622*f6aab3d8Srobert       else
623*f6aab3d8Srobert         param_matches.push_back(alternate_mangled_name);
624*f6aab3d8Srobert     }
625*f6aab3d8Srobert   }
626*f6aab3d8Srobert 
627*f6aab3d8Srobert   if (param_and_qual_matches.size())
628*f6aab3d8Srobert     return param_and_qual_matches[0]; // It is assumed that there will be only
629*f6aab3d8Srobert                                       // one!
630*f6aab3d8Srobert   else if (param_matches.size())
631*f6aab3d8Srobert     return param_matches[0]; // Return one of them as a best match
632*f6aab3d8Srobert   else
633*f6aab3d8Srobert     return ConstString();
634061da546Spatrick }
635061da546Spatrick 
LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp)636061da546Spatrick static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
637061da546Spatrick   if (!cpp_category_sp)
638061da546Spatrick     return;
639061da546Spatrick 
640061da546Spatrick   TypeSummaryImpl::Flags stl_summary_flags;
641061da546Spatrick   stl_summary_flags.SetCascades(true)
642061da546Spatrick       .SetSkipPointers(false)
643061da546Spatrick       .SetSkipReferences(false)
644061da546Spatrick       .SetDontShowChildren(true)
645061da546Spatrick       .SetDontShowValue(true)
646061da546Spatrick       .SetShowMembersOneLiner(false)
647061da546Spatrick       .SetHideItemNames(false);
648061da546Spatrick 
649061da546Spatrick   AddCXXSummary(cpp_category_sp,
650061da546Spatrick                 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
651061da546Spatrick                 "std::string summary provider",
652061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::string$"), stl_summary_flags,
653061da546Spatrick                 true);
654061da546Spatrick   AddCXXSummary(cpp_category_sp,
655061da546Spatrick                 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
656061da546Spatrick                 "std::string summary provider",
657061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::basic_string<char, "
658061da546Spatrick                             "std::__[[:alnum:]]+::char_traits<char>, "
659061da546Spatrick                             "std::__[[:alnum:]]+::allocator<char> >$"),
660061da546Spatrick                 stl_summary_flags, true);
661061da546Spatrick   AddCXXSummary(cpp_category_sp,
662061da546Spatrick                 lldb_private::formatters::LibcxxStringSummaryProviderASCII,
663061da546Spatrick                 "std::string summary provider",
664061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::basic_string<unsigned char, "
665061da546Spatrick                             "std::__[[:alnum:]]+::char_traits<unsigned char>, "
666061da546Spatrick                             "std::__[[:alnum:]]+::allocator<unsigned char> >$"),
667061da546Spatrick                 stl_summary_flags, true);
668061da546Spatrick 
669061da546Spatrick   AddCXXSummary(cpp_category_sp,
670061da546Spatrick                 lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
671061da546Spatrick                 "std::u16string summary provider",
672*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::basic_string<char16_t, "
673061da546Spatrick                             "std::__[[:alnum:]]+::char_traits<char16_t>, "
674061da546Spatrick                             "std::__[[:alnum:]]+::allocator<char16_t> >$"),
675061da546Spatrick                 stl_summary_flags, true);
676061da546Spatrick 
677061da546Spatrick   AddCXXSummary(cpp_category_sp,
678061da546Spatrick                 lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
679061da546Spatrick                 "std::u32string summary provider",
680*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::basic_string<char32_t, "
681061da546Spatrick                             "std::__[[:alnum:]]+::char_traits<char32_t>, "
682061da546Spatrick                             "std::__[[:alnum:]]+::allocator<char32_t> >$"),
683061da546Spatrick                 stl_summary_flags, true);
684061da546Spatrick 
685*f6aab3d8Srobert   AddCXXSummary(
686*f6aab3d8Srobert       cpp_category_sp, lldb_private::formatters::LibcxxWStringSummaryProvider,
687061da546Spatrick       "std::wstring summary provider",
688*f6aab3d8Srobert       ConstString("^std::__[[:alnum:]]+::wstring$"), stl_summary_flags, true);
689061da546Spatrick   AddCXXSummary(cpp_category_sp,
690061da546Spatrick                 lldb_private::formatters::LibcxxWStringSummaryProvider,
691061da546Spatrick                 "std::wstring summary provider",
692061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::basic_string<wchar_t, "
693061da546Spatrick                             "std::__[[:alnum:]]+::char_traits<wchar_t>, "
694061da546Spatrick                             "std::__[[:alnum:]]+::allocator<wchar_t> >$"),
695061da546Spatrick                 stl_summary_flags, true);
696061da546Spatrick 
697*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
698*f6aab3d8Srobert                 lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
699*f6aab3d8Srobert                 "std::string_view summary provider",
700*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::string_view$"),
701*f6aab3d8Srobert                 stl_summary_flags, true);
702*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
703*f6aab3d8Srobert                 lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
704*f6aab3d8Srobert                 "std::string_view summary provider",
705*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::basic_string_view<char, "
706*f6aab3d8Srobert                             "std::__[[:alnum:]]+::char_traits<char> >$"),
707*f6aab3d8Srobert                 stl_summary_flags, true);
708*f6aab3d8Srobert   AddCXXSummary(
709*f6aab3d8Srobert       cpp_category_sp,
710*f6aab3d8Srobert       lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
711*f6aab3d8Srobert       "std::string_view summary provider",
712*f6aab3d8Srobert       ConstString("^std::__[[:alnum:]]+::basic_string_view<unsigned char, "
713*f6aab3d8Srobert                   "std::__[[:alnum:]]+::char_traits<unsigned char> >$"),
714*f6aab3d8Srobert       stl_summary_flags, true);
715*f6aab3d8Srobert 
716*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
717*f6aab3d8Srobert                 lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16,
718*f6aab3d8Srobert                 "std::u16string_view summary provider",
719*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::basic_string_view<char16_t, "
720*f6aab3d8Srobert                             "std::__[[:alnum:]]+::char_traits<char16_t> >$"),
721*f6aab3d8Srobert                 stl_summary_flags, true);
722*f6aab3d8Srobert 
723*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
724*f6aab3d8Srobert                 lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32,
725*f6aab3d8Srobert                 "std::u32string_view summary provider",
726*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::basic_string_view<char32_t, "
727*f6aab3d8Srobert                             "std::__[[:alnum:]]+::char_traits<char32_t> >$"),
728*f6aab3d8Srobert                 stl_summary_flags, true);
729*f6aab3d8Srobert 
730*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
731*f6aab3d8Srobert                 lldb_private::formatters::LibcxxWStringViewSummaryProvider,
732*f6aab3d8Srobert                 "std::wstring_view summary provider",
733*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::wstring_view$"),
734*f6aab3d8Srobert                 stl_summary_flags, true);
735*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
736*f6aab3d8Srobert                 lldb_private::formatters::LibcxxWStringViewSummaryProvider,
737*f6aab3d8Srobert                 "std::wstring_view summary provider",
738*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::basic_string_view<wchar_t, "
739*f6aab3d8Srobert                             "std::__[[:alnum:]]+::char_traits<wchar_t> >$"),
740*f6aab3d8Srobert                 stl_summary_flags, true);
741*f6aab3d8Srobert 
742061da546Spatrick   SyntheticChildren::Flags stl_synth_flags;
743061da546Spatrick   stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
744061da546Spatrick       false);
745061da546Spatrick   SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
746061da546Spatrick   stl_deref_flags.SetFrontEndWantsDereference();
747061da546Spatrick 
748061da546Spatrick   AddCXXSynthetic(
749061da546Spatrick       cpp_category_sp,
750061da546Spatrick       lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
751061da546Spatrick       "libc++ std::bitset synthetic children",
752061da546Spatrick       ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"), stl_deref_flags,
753061da546Spatrick       true);
754061da546Spatrick   AddCXXSynthetic(
755061da546Spatrick       cpp_category_sp,
756061da546Spatrick       lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
757061da546Spatrick       "libc++ std::vector synthetic children",
758061da546Spatrick       ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"), stl_deref_flags,
759061da546Spatrick       true);
760061da546Spatrick   AddCXXSynthetic(
761061da546Spatrick       cpp_category_sp,
762061da546Spatrick       lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
763061da546Spatrick       "libc++ std::forward_list synthetic children",
764061da546Spatrick       ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
765061da546Spatrick       stl_synth_flags, true);
766061da546Spatrick   AddCXXSynthetic(
767061da546Spatrick       cpp_category_sp,
768061da546Spatrick       lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
769061da546Spatrick       "libc++ std::list synthetic children",
770061da546Spatrick       // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
771061da546Spatrick       // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
772061da546Spatrick       ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
773061da546Spatrick                   "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
774061da546Spatrick       stl_deref_flags, true);
775061da546Spatrick   AddCXXSynthetic(
776061da546Spatrick       cpp_category_sp,
777061da546Spatrick       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
778061da546Spatrick       "libc++ std::map synthetic children",
779061da546Spatrick       ConstString("^std::__[[:alnum:]]+::map<.+> >(( )?&)?$"), stl_synth_flags,
780061da546Spatrick       true);
781061da546Spatrick   AddCXXSynthetic(
782061da546Spatrick       cpp_category_sp,
783061da546Spatrick       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
784061da546Spatrick       "libc++ std::set synthetic children",
785061da546Spatrick       ConstString("^std::__[[:alnum:]]+::set<.+> >(( )?&)?$"), stl_deref_flags,
786061da546Spatrick       true);
787061da546Spatrick   AddCXXSynthetic(
788061da546Spatrick       cpp_category_sp,
789061da546Spatrick       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
790061da546Spatrick       "libc++ std::multiset synthetic children",
791061da546Spatrick       ConstString("^std::__[[:alnum:]]+::multiset<.+> >(( )?&)?$"),
792061da546Spatrick       stl_deref_flags, true);
793061da546Spatrick   AddCXXSynthetic(
794061da546Spatrick       cpp_category_sp,
795061da546Spatrick       lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
796061da546Spatrick       "libc++ std::multimap synthetic children",
797061da546Spatrick       ConstString("^std::__[[:alnum:]]+::multimap<.+> >(( )?&)?$"),
798061da546Spatrick       stl_synth_flags, true);
799061da546Spatrick   AddCXXSynthetic(
800061da546Spatrick       cpp_category_sp,
801061da546Spatrick       lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator,
802061da546Spatrick       "libc++ std::unordered containers synthetic children",
803061da546Spatrick       ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"),
804061da546Spatrick       stl_synth_flags, true);
805061da546Spatrick   AddCXXSynthetic(
806061da546Spatrick       cpp_category_sp,
807061da546Spatrick       lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator,
808061da546Spatrick       "libc++ std::initializer_list synthetic children",
809061da546Spatrick       ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
810061da546Spatrick       true);
811061da546Spatrick   AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
812061da546Spatrick                   "libc++ std::queue synthetic children",
813061da546Spatrick                   ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"),
814061da546Spatrick                   stl_synth_flags, true);
815061da546Spatrick   AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
816061da546Spatrick                   "libc++ std::tuple synthetic children",
817061da546Spatrick                   ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
818061da546Spatrick                   stl_synth_flags, true);
819*f6aab3d8Srobert   AddCXXSynthetic(cpp_category_sp, LibcxxOptionalSyntheticFrontEndCreator,
820061da546Spatrick                   "libc++ std::optional synthetic children",
821061da546Spatrick                   ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
822061da546Spatrick                   stl_synth_flags, true);
823061da546Spatrick   AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,
824061da546Spatrick                   "libc++ std::variant synthetic children",
825061da546Spatrick                   ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"),
826061da546Spatrick                   stl_synth_flags, true);
827061da546Spatrick   AddCXXSynthetic(
828061da546Spatrick       cpp_category_sp,
829061da546Spatrick       lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
830061da546Spatrick       "libc++ std::atomic synthetic children",
831061da546Spatrick       ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true);
832*f6aab3d8Srobert   AddCXXSynthetic(
833*f6aab3d8Srobert       cpp_category_sp,
834*f6aab3d8Srobert       lldb_private::formatters::LibcxxStdSpanSyntheticFrontEndCreator,
835*f6aab3d8Srobert       "libc++ std::span synthetic children",
836*f6aab3d8Srobert       ConstString("^std::__[[:alnum:]]+::span<.+>(( )?&)?$"), stl_deref_flags,
837*f6aab3d8Srobert       true);
838*f6aab3d8Srobert   AddCXXSynthetic(
839*f6aab3d8Srobert       cpp_category_sp,
840*f6aab3d8Srobert       lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEndCreator,
841*f6aab3d8Srobert       "libc++ std::ranges::ref_view synthetic children",
842*f6aab3d8Srobert       ConstString("^std::__[[:alnum:]]+::ranges::ref_view<.+>(( )?&)?$"),
843*f6aab3d8Srobert       stl_deref_flags, true);
844061da546Spatrick 
845*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
846*f6aab3d8Srobert       "^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$", eFormatterMatchRegex,
847061da546Spatrick       SyntheticChildrenSP(new ScriptedSyntheticChildren(
848061da546Spatrick           stl_synth_flags,
849061da546Spatrick           "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
850061da546Spatrick 
851061da546Spatrick   AddCXXSynthetic(
852061da546Spatrick       cpp_category_sp,
853061da546Spatrick       lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
854061da546Spatrick       "shared_ptr synthetic children",
855061da546Spatrick       ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
856061da546Spatrick       stl_synth_flags, true);
857dda28197Spatrick 
858dda28197Spatrick   ConstString libcxx_std_unique_ptr_regex(
859dda28197Spatrick       "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$");
860dda28197Spatrick   AddCXXSynthetic(
861dda28197Spatrick       cpp_category_sp,
862dda28197Spatrick       lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator,
863dda28197Spatrick       "unique_ptr synthetic children", libcxx_std_unique_ptr_regex,
864dda28197Spatrick       stl_synth_flags, true);
865dda28197Spatrick 
866061da546Spatrick   AddCXXSynthetic(
867061da546Spatrick       cpp_category_sp,
868061da546Spatrick       lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
869061da546Spatrick       "weak_ptr synthetic children",
870061da546Spatrick       ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"),
871061da546Spatrick       stl_synth_flags, true);
872061da546Spatrick   AddCXXSummary(cpp_category_sp,
873061da546Spatrick                 lldb_private::formatters::LibcxxFunctionSummaryProvider,
874061da546Spatrick                 "libc++ std::function summary provider",
875061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::function<.+>$"),
876061da546Spatrick                 stl_summary_flags, true);
877061da546Spatrick 
878*f6aab3d8Srobert   ConstString libcxx_std_coroutine_handle_regex(
879*f6aab3d8Srobert       "^std::__[[:alnum:]]+::coroutine_handle<.+>(( )?&)?$");
880*f6aab3d8Srobert   AddCXXSynthetic(
881*f6aab3d8Srobert       cpp_category_sp,
882*f6aab3d8Srobert       lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator,
883*f6aab3d8Srobert       "coroutine_handle synthetic children", libcxx_std_coroutine_handle_regex,
884*f6aab3d8Srobert       stl_deref_flags, true);
885*f6aab3d8Srobert 
886061da546Spatrick   stl_summary_flags.SetDontShowChildren(false);
887061da546Spatrick   stl_summary_flags.SetSkipPointers(false);
888061da546Spatrick   AddCXXSummary(cpp_category_sp,
889061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
890061da546Spatrick                 "libc++ std::bitset summary provider",
891061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"),
892061da546Spatrick                 stl_summary_flags, true);
893061da546Spatrick   AddCXXSummary(cpp_category_sp,
894061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
895061da546Spatrick                 "libc++ std::vector summary provider",
896061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"),
897061da546Spatrick                 stl_summary_flags, true);
898061da546Spatrick   AddCXXSummary(cpp_category_sp,
899061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
900061da546Spatrick                 "libc++ std::list summary provider",
901061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
902061da546Spatrick                 stl_summary_flags, true);
903061da546Spatrick   AddCXXSummary(
904061da546Spatrick       cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
905061da546Spatrick       "libc++ std::list summary provider",
906061da546Spatrick       // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
907061da546Spatrick       // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
908061da546Spatrick       ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
909061da546Spatrick                   "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
910061da546Spatrick       stl_summary_flags, true);
911061da546Spatrick   AddCXXSummary(cpp_category_sp,
912061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
913061da546Spatrick                 "libc++ std::map summary provider",
914061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::map<.+>(( )?&)?$"),
915061da546Spatrick                 stl_summary_flags, true);
916061da546Spatrick   AddCXXSummary(cpp_category_sp,
917061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
918061da546Spatrick                 "libc++ std::deque summary provider",
919061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::deque<.+>(( )?&)?$"),
920061da546Spatrick                 stl_summary_flags, true);
921061da546Spatrick   AddCXXSummary(cpp_category_sp,
922061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
923061da546Spatrick                 "libc++ std::queue summary provider",
924061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"),
925061da546Spatrick                 stl_summary_flags, true);
926061da546Spatrick   AddCXXSummary(cpp_category_sp,
927061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
928061da546Spatrick                 "libc++ std::set summary provider",
929061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::set<.+>(( )?&)?$"),
930061da546Spatrick                 stl_summary_flags, true);
931061da546Spatrick   AddCXXSummary(cpp_category_sp,
932061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
933061da546Spatrick                 "libc++ std::multiset summary provider",
934061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::multiset<.+>(( )?&)?$"),
935061da546Spatrick                 stl_summary_flags, true);
936061da546Spatrick   AddCXXSummary(cpp_category_sp,
937061da546Spatrick                 lldb_private::formatters::LibcxxContainerSummaryProvider,
938061da546Spatrick                 "libc++ std::multimap summary provider",
939061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::multimap<.+>(( )?&)?$"),
940061da546Spatrick                 stl_summary_flags, true);
941061da546Spatrick   AddCXXSummary(
942061da546Spatrick       cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
943061da546Spatrick       "libc++ std::unordered containers summary provider",
944061da546Spatrick       ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"),
945061da546Spatrick       stl_summary_flags, true);
946061da546Spatrick   AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider,
947061da546Spatrick                 "libc++ std::tuple summary provider",
948061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
949061da546Spatrick                 stl_summary_flags, true);
950061da546Spatrick   AddCXXSummary(cpp_category_sp,
951*f6aab3d8Srobert                 lldb_private::formatters::LibCxxAtomicSummaryProvider,
952*f6aab3d8Srobert                 "libc++ std::atomic summary provider",
953*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::atomic<.+>$"),
954*f6aab3d8Srobert                 stl_summary_flags, true);
955*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
956*f6aab3d8Srobert                 lldb_private::formatters::GenericOptionalSummaryProvider,
957061da546Spatrick                 "libc++ std::optional summary provider",
958061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
959061da546Spatrick                 stl_summary_flags, true);
960061da546Spatrick   AddCXXSummary(cpp_category_sp,
961061da546Spatrick                 lldb_private::formatters::LibcxxVariantSummaryProvider,
962061da546Spatrick                 "libc++ std::variant summary provider",
963061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"),
964061da546Spatrick                 stl_summary_flags, true);
965*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
966*f6aab3d8Srobert                 lldb_private::formatters::LibcxxContainerSummaryProvider,
967*f6aab3d8Srobert                 "libc++ std::span summary provider",
968*f6aab3d8Srobert                 ConstString("^std::__[[:alnum:]]+::span<.+>(( )?&)?$"),
969*f6aab3d8Srobert                 stl_summary_flags, true);
970061da546Spatrick 
971061da546Spatrick   stl_summary_flags.SetSkipPointers(true);
972061da546Spatrick 
973061da546Spatrick   AddCXXSummary(cpp_category_sp,
974061da546Spatrick                 lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
975061da546Spatrick                 "libc++ std::shared_ptr summary provider",
976061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::shared_ptr<.+>(( )?&)?$"),
977061da546Spatrick                 stl_summary_flags, true);
978061da546Spatrick   AddCXXSummary(cpp_category_sp,
979061da546Spatrick                 lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
980061da546Spatrick                 "libc++ std::weak_ptr summary provider",
981061da546Spatrick                 ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"),
982061da546Spatrick                 stl_summary_flags, true);
983dda28197Spatrick   AddCXXSummary(cpp_category_sp,
984dda28197Spatrick                 lldb_private::formatters::LibcxxUniquePointerSummaryProvider,
985dda28197Spatrick                 "libc++ std::unique_ptr summary provider",
986dda28197Spatrick                 libcxx_std_unique_ptr_regex, stl_summary_flags, true);
987061da546Spatrick 
988*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
989*f6aab3d8Srobert                 lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,
990*f6aab3d8Srobert                 "libc++ std::coroutine_handle summary provider",
991*f6aab3d8Srobert                 libcxx_std_coroutine_handle_regex, stl_summary_flags, true);
992*f6aab3d8Srobert 
993061da546Spatrick   AddCXXSynthetic(
994061da546Spatrick       cpp_category_sp,
995061da546Spatrick       lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator,
996061da546Spatrick       "std::vector iterator synthetic children",
997061da546Spatrick       ConstString("^std::__[[:alnum:]]+::__wrap_iter<.+>$"), stl_synth_flags,
998061da546Spatrick       true);
999061da546Spatrick 
1000061da546Spatrick   AddCXXSynthetic(
1001061da546Spatrick       cpp_category_sp,
1002061da546Spatrick       lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,
1003061da546Spatrick       "std::map iterator synthetic children",
1004*f6aab3d8Srobert       ConstString("^std::__[[:alnum:]]+::__map_(const_)?iterator<.+>$"), stl_synth_flags,
1005061da546Spatrick       true);
1006*f6aab3d8Srobert 
1007*f6aab3d8Srobert   AddCXXSynthetic(
1008*f6aab3d8Srobert       cpp_category_sp,
1009*f6aab3d8Srobert       lldb_private::formatters::
1010*f6aab3d8Srobert           LibCxxUnorderedMapIteratorSyntheticFrontEndCreator,
1011*f6aab3d8Srobert       "std::unordered_map iterator synthetic children",
1012*f6aab3d8Srobert       ConstString("^std::__[[:alnum:]]+::__hash_map_(const_)?iterator<.+>$"),
1013*f6aab3d8Srobert       stl_synth_flags, true);
1014061da546Spatrick }
1015061da546Spatrick 
LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp)1016061da546Spatrick static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
1017061da546Spatrick   if (!cpp_category_sp)
1018061da546Spatrick     return;
1019061da546Spatrick 
1020061da546Spatrick   TypeSummaryImpl::Flags stl_summary_flags;
1021061da546Spatrick   stl_summary_flags.SetCascades(true)
1022061da546Spatrick       .SetSkipPointers(false)
1023061da546Spatrick       .SetSkipReferences(false)
1024061da546Spatrick       .SetDontShowChildren(true)
1025061da546Spatrick       .SetDontShowValue(true)
1026061da546Spatrick       .SetShowMembersOneLiner(false)
1027061da546Spatrick       .SetHideItemNames(false);
1028061da546Spatrick 
1029061da546Spatrick   lldb::TypeSummaryImplSP std_string_summary_sp(
1030061da546Spatrick       new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}"));
1031061da546Spatrick 
1032061da546Spatrick   lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(
1033061da546Spatrick       stl_summary_flags, LibStdcppStringSummaryProvider,
1034061da546Spatrick       "libstdc++ c++11 std::string summary provider"));
1035061da546Spatrick   lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(
1036061da546Spatrick       stl_summary_flags, LibStdcppWStringSummaryProvider,
1037061da546Spatrick       "libstdc++ c++11 std::wstring summary provider"));
1038061da546Spatrick 
1039*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("std::string", eFormatterMatchExact,
1040061da546Spatrick                                   std_string_summary_sp);
1041*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("std::basic_string<char>",
1042*f6aab3d8Srobert                                   eFormatterMatchRegex, std_string_summary_sp);
1043*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary(
1044*f6aab3d8Srobert       "std::basic_string<char,std::char_traits<char>,std::allocator<char> >",
1045*f6aab3d8Srobert       eFormatterMatchExact, std_string_summary_sp);
1046*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary(
1047*f6aab3d8Srobert       "std::basic_string<char, std::char_traits<char>, std::allocator<char> >",
1048*f6aab3d8Srobert       eFormatterMatchExact, std_string_summary_sp);
1049061da546Spatrick 
1050*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("std::__cxx11::string", eFormatterMatchExact,
1051061da546Spatrick                                   cxx11_string_summary_sp);
1052*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary(
1053*f6aab3d8Srobert       "std::__cxx11::basic_string<char, std::char_traits<char>, "
1054*f6aab3d8Srobert       "std::allocator<char> >",
1055*f6aab3d8Srobert       eFormatterMatchExact, cxx11_string_summary_sp);
1056*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("std::__cxx11::basic_string<unsigned char, "
1057*f6aab3d8Srobert                                   "std::char_traits<unsigned char>, "
1058*f6aab3d8Srobert                                   "std::allocator<unsigned char> >",
1059*f6aab3d8Srobert                                   eFormatterMatchExact,
1060061da546Spatrick                                   cxx11_string_summary_sp);
1061061da546Spatrick 
1062061da546Spatrick   // making sure we force-pick the summary for printing wstring (_M_p is a
1063061da546Spatrick   // wchar_t*)
1064061da546Spatrick   lldb::TypeSummaryImplSP std_wstring_summary_sp(
1065061da546Spatrick       new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}"));
1066061da546Spatrick 
1067*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("std::wstring", eFormatterMatchExact,
1068061da546Spatrick                                   std_wstring_summary_sp);
1069*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("std::basic_string<wchar_t>",
1070*f6aab3d8Srobert                                   eFormatterMatchExact, std_wstring_summary_sp);
1071*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("std::basic_string<wchar_t,std::char_traits<"
1072*f6aab3d8Srobert                                   "wchar_t>,std::allocator<wchar_t> >",
1073*f6aab3d8Srobert                                   eFormatterMatchExact, std_wstring_summary_sp);
1074*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary(
1075*f6aab3d8Srobert       "std::basic_string<wchar_t, std::char_traits<wchar_t>, "
1076*f6aab3d8Srobert       "std::allocator<wchar_t> >",
1077*f6aab3d8Srobert       eFormatterMatchExact, std_wstring_summary_sp);
1078061da546Spatrick 
1079*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("std::__cxx11::wstring", eFormatterMatchExact,
1080061da546Spatrick                                   cxx11_wstring_summary_sp);
1081*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary(
1082*f6aab3d8Srobert       "std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, "
1083*f6aab3d8Srobert       "std::allocator<wchar_t> >",
1084*f6aab3d8Srobert       eFormatterMatchExact, cxx11_wstring_summary_sp);
1085061da546Spatrick 
1086061da546Spatrick   SyntheticChildren::Flags stl_synth_flags;
1087061da546Spatrick   stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
1088061da546Spatrick       false);
1089*f6aab3d8Srobert   SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
1090*f6aab3d8Srobert   stl_deref_flags.SetFrontEndWantsDereference();
1091061da546Spatrick 
1092*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1093*f6aab3d8Srobert       "^std::vector<.+>(( )?&)?$", eFormatterMatchRegex,
1094061da546Spatrick       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1095061da546Spatrick           stl_synth_flags,
1096061da546Spatrick           "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
1097*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1098*f6aab3d8Srobert       "^std::map<.+> >(( )?&)?$", eFormatterMatchRegex,
1099061da546Spatrick       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1100061da546Spatrick           stl_synth_flags,
1101*f6aab3d8Srobert           "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
1102*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1103*f6aab3d8Srobert       "^std::deque<.+>(( )?&)?$", eFormatterMatchRegex,
1104061da546Spatrick       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1105*f6aab3d8Srobert           stl_deref_flags,
1106*f6aab3d8Srobert           "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider")));
1107*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1108*f6aab3d8Srobert       "^std::set<.+> >(( )?&)?$", eFormatterMatchRegex,
1109*f6aab3d8Srobert       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1110*f6aab3d8Srobert           stl_deref_flags,
1111*f6aab3d8Srobert           "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
1112*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1113*f6aab3d8Srobert       "^std::multimap<.+> >(( )?&)?$", eFormatterMatchRegex,
1114*f6aab3d8Srobert       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1115*f6aab3d8Srobert           stl_deref_flags,
1116*f6aab3d8Srobert           "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
1117*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1118*f6aab3d8Srobert       "^std::multiset<.+> >(( )?&)?$", eFormatterMatchRegex,
1119*f6aab3d8Srobert       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1120*f6aab3d8Srobert           stl_deref_flags,
1121*f6aab3d8Srobert           "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
1122*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1123*f6aab3d8Srobert       "^std::unordered_(multi)?(map|set)<.+> >$", eFormatterMatchRegex,
1124*f6aab3d8Srobert       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1125*f6aab3d8Srobert           stl_deref_flags,
1126*f6aab3d8Srobert           "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));
1127*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1128*f6aab3d8Srobert       "^std::(__cxx11::)?list<.+>(( )?&)?$", eFormatterMatchRegex,
1129*f6aab3d8Srobert       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1130*f6aab3d8Srobert           stl_deref_flags,
1131061da546Spatrick           "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
1132*f6aab3d8Srobert   cpp_category_sp->AddTypeSynthetic(
1133*f6aab3d8Srobert       "^std::(__cxx11::)?forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
1134*f6aab3d8Srobert       SyntheticChildrenSP(new ScriptedSyntheticChildren(
1135*f6aab3d8Srobert           stl_synth_flags,
1136*f6aab3d8Srobert           "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));
1137*f6aab3d8Srobert 
1138061da546Spatrick   stl_summary_flags.SetDontShowChildren(false);
1139*f6aab3d8Srobert   stl_summary_flags.SetSkipPointers(false);
1140*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::bitset<.+>(( )?&)?$",
1141*f6aab3d8Srobert                                   eFormatterMatchRegex,
1142*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1143*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1144*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::vector<.+>(( )?&)?$",
1145*f6aab3d8Srobert                                   eFormatterMatchRegex,
1146*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1147*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1148*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::map<.+> >(( )?&)?$",
1149*f6aab3d8Srobert                                   eFormatterMatchRegex,
1150*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1151*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1152*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::set<.+> >(( )?&)?$",
1153*f6aab3d8Srobert                                   eFormatterMatchRegex,
1154*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1155*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1156*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::deque<.+>(( )?&)?$",
1157*f6aab3d8Srobert                                   eFormatterMatchRegex,
1158*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1159*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1160*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::multimap<.+> >(( )?&)?$",
1161*f6aab3d8Srobert                                   eFormatterMatchRegex,
1162*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1163*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1164*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::multiset<.+> >(( )?&)?$",
1165*f6aab3d8Srobert                                   eFormatterMatchRegex,
1166*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1167*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1168*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::unordered_(multi)?(map|set)<.+> >$",
1169*f6aab3d8Srobert                                   eFormatterMatchRegex,
1170*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1171*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1172*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary("^std::(__cxx11::)?list<.+>(( )?&)?$",
1173*f6aab3d8Srobert                                   eFormatterMatchRegex,
1174*f6aab3d8Srobert                                   TypeSummaryImplSP(new StringSummaryFormat(
1175*f6aab3d8Srobert                                       stl_summary_flags, "size=${svar%#}")));
1176*f6aab3d8Srobert   cpp_category_sp->AddTypeSummary(
1177*f6aab3d8Srobert       "^std::(__cxx11::)?forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
1178*f6aab3d8Srobert       TypeSummaryImplSP(new ScriptSummaryFormat(
1179*f6aab3d8Srobert           stl_summary_flags,
1180*f6aab3d8Srobert           "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
1181061da546Spatrick 
1182061da546Spatrick   AddCXXSynthetic(
1183061da546Spatrick       cpp_category_sp,
1184061da546Spatrick       lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator,
1185061da546Spatrick       "std::vector iterator synthetic children",
1186061da546Spatrick       ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
1187061da546Spatrick 
1188061da546Spatrick   AddCXXSynthetic(
1189061da546Spatrick       cpp_category_sp,
1190061da546Spatrick       lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator,
1191061da546Spatrick       "std::map iterator synthetic children",
1192061da546Spatrick       ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
1193061da546Spatrick 
1194061da546Spatrick   AddCXXSynthetic(
1195061da546Spatrick       cpp_category_sp,
1196061da546Spatrick       lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,
1197061da546Spatrick       "std::unique_ptr synthetic children",
1198061da546Spatrick       ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
1199061da546Spatrick   AddCXXSynthetic(
1200061da546Spatrick       cpp_category_sp,
1201061da546Spatrick       lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
1202061da546Spatrick       "std::shared_ptr synthetic children",
1203061da546Spatrick       ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
1204061da546Spatrick   AddCXXSynthetic(
1205061da546Spatrick       cpp_category_sp,
1206061da546Spatrick       lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
1207061da546Spatrick       "std::weak_ptr synthetic children",
1208061da546Spatrick       ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
1209061da546Spatrick   AddCXXSynthetic(
1210061da546Spatrick       cpp_category_sp,
1211061da546Spatrick       lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator,
1212061da546Spatrick       "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"),
1213061da546Spatrick       stl_synth_flags, true);
1214061da546Spatrick 
1215*f6aab3d8Srobert   ConstString libstdcpp_std_coroutine_handle_regex(
1216*f6aab3d8Srobert       "^std::coroutine_handle<.+>(( )?&)?$");
1217*f6aab3d8Srobert   AddCXXSynthetic(
1218*f6aab3d8Srobert       cpp_category_sp,
1219*f6aab3d8Srobert       lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator,
1220*f6aab3d8Srobert       "std::coroutine_handle synthetic children",
1221*f6aab3d8Srobert       libstdcpp_std_coroutine_handle_regex, stl_deref_flags, true);
1222*f6aab3d8Srobert 
1223*f6aab3d8Srobert   AddCXXSynthetic(
1224*f6aab3d8Srobert       cpp_category_sp,
1225*f6aab3d8Srobert       lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator,
1226*f6aab3d8Srobert       "std::bitset synthetic child", ConstString("^std::bitset<.+>(( )?&)?$"),
1227*f6aab3d8Srobert       stl_deref_flags, true);
1228*f6aab3d8Srobert 
1229*f6aab3d8Srobert   AddCXXSynthetic(
1230*f6aab3d8Srobert       cpp_category_sp,
1231*f6aab3d8Srobert       lldb_private::formatters::LibStdcppOptionalSyntheticFrontEndCreator,
1232*f6aab3d8Srobert       "std::optional synthetic child",
1233*f6aab3d8Srobert       ConstString("^std::optional<.+>(( )?&)?$"), stl_deref_flags, true);
1234*f6aab3d8Srobert 
1235061da546Spatrick   AddCXXSummary(cpp_category_sp,
1236061da546Spatrick                 lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
1237061da546Spatrick                 "libstdc++ std::unique_ptr summary provider",
1238061da546Spatrick                 ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags,
1239061da546Spatrick                 true);
1240061da546Spatrick   AddCXXSummary(cpp_category_sp,
1241061da546Spatrick                 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
1242061da546Spatrick                 "libstdc++ std::shared_ptr summary provider",
1243061da546Spatrick                 ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags,
1244061da546Spatrick                 true);
1245061da546Spatrick   AddCXXSummary(cpp_category_sp,
1246061da546Spatrick                 lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
1247061da546Spatrick                 "libstdc++ std::weak_ptr summary provider",
1248061da546Spatrick                 ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags,
1249061da546Spatrick                 true);
1250*f6aab3d8Srobert   AddCXXSummary(cpp_category_sp,
1251*f6aab3d8Srobert                 lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,
1252*f6aab3d8Srobert                 "libstdc++ std::coroutine_handle summary provider",
1253*f6aab3d8Srobert                 libstdcpp_std_coroutine_handle_regex, stl_summary_flags, true);
1254*f6aab3d8Srobert   AddCXXSummary(
1255*f6aab3d8Srobert       cpp_category_sp, lldb_private::formatters::GenericOptionalSummaryProvider,
1256*f6aab3d8Srobert       "libstd++ std::optional summary provider",
1257*f6aab3d8Srobert       ConstString("^std::optional<.+>(( )?&)?$"), stl_summary_flags, true);
1258061da546Spatrick }
1259061da546Spatrick 
LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp)1260061da546Spatrick static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
1261061da546Spatrick   if (!cpp_category_sp)
1262061da546Spatrick     return;
1263061da546Spatrick 
1264061da546Spatrick   TypeSummaryImpl::Flags string_flags;
1265061da546Spatrick   string_flags.SetCascades(true)
1266061da546Spatrick       .SetSkipPointers(true)
1267061da546Spatrick       .SetSkipReferences(false)
1268061da546Spatrick       .SetDontShowChildren(true)
1269061da546Spatrick       .SetDontShowValue(false)
1270061da546Spatrick       .SetShowMembersOneLiner(false)
1271061da546Spatrick       .SetHideItemNames(false);
1272061da546Spatrick 
1273061da546Spatrick   TypeSummaryImpl::Flags string_array_flags;
1274061da546Spatrick   string_array_flags.SetCascades(true)
1275061da546Spatrick       .SetSkipPointers(true)
1276061da546Spatrick       .SetSkipReferences(false)
1277061da546Spatrick       .SetDontShowChildren(true)
1278061da546Spatrick       .SetDontShowValue(true)
1279061da546Spatrick       .SetShowMembersOneLiner(false)
1280061da546Spatrick       .SetHideItemNames(false);
1281061da546Spatrick 
1282061da546Spatrick   AddCXXSummary(
1283061da546Spatrick       cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider,
1284061da546Spatrick       "char8_t * summary provider", ConstString("char8_t *"), string_flags);
1285061da546Spatrick   AddCXXSummary(cpp_category_sp,
1286061da546Spatrick                 lldb_private::formatters::Char8StringSummaryProvider,
1287061da546Spatrick                 "char8_t [] summary provider",
1288*f6aab3d8Srobert                 ConstString("char8_t ?\\[[0-9]+\\]"), string_array_flags, true);
1289061da546Spatrick 
1290061da546Spatrick   AddCXXSummary(
1291061da546Spatrick       cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
1292061da546Spatrick       "char16_t * summary provider", ConstString("char16_t *"), string_flags);
1293061da546Spatrick   AddCXXSummary(cpp_category_sp,
1294061da546Spatrick                 lldb_private::formatters::Char16StringSummaryProvider,
1295061da546Spatrick                 "char16_t [] summary provider",
1296*f6aab3d8Srobert                 ConstString("char16_t ?\\[[0-9]+\\]"), string_array_flags, true);
1297061da546Spatrick 
1298061da546Spatrick   AddCXXSummary(
1299061da546Spatrick       cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider,
1300061da546Spatrick       "char32_t * summary provider", ConstString("char32_t *"), string_flags);
1301061da546Spatrick   AddCXXSummary(cpp_category_sp,
1302061da546Spatrick                 lldb_private::formatters::Char32StringSummaryProvider,
1303061da546Spatrick                 "char32_t [] summary provider",
1304*f6aab3d8Srobert                 ConstString("char32_t ?\\[[0-9]+\\]"), string_array_flags, true);
1305061da546Spatrick 
1306061da546Spatrick   AddCXXSummary(
1307061da546Spatrick       cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider,
1308061da546Spatrick       "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
1309061da546Spatrick   AddCXXSummary(cpp_category_sp,
1310061da546Spatrick                 lldb_private::formatters::WCharStringSummaryProvider,
1311061da546Spatrick                 "wchar_t * summary provider",
1312*f6aab3d8Srobert                 ConstString("wchar_t ?\\[[0-9]+\\]"), string_array_flags, true);
1313061da546Spatrick 
1314061da546Spatrick   AddCXXSummary(
1315061da546Spatrick       cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
1316061da546Spatrick       "unichar * summary provider", ConstString("unichar *"), string_flags);
1317061da546Spatrick 
1318061da546Spatrick   TypeSummaryImpl::Flags widechar_flags;
1319061da546Spatrick   widechar_flags.SetDontShowValue(true)
1320061da546Spatrick       .SetSkipPointers(true)
1321061da546Spatrick       .SetSkipReferences(false)
1322061da546Spatrick       .SetCascades(true)
1323061da546Spatrick       .SetDontShowChildren(true)
1324061da546Spatrick       .SetHideItemNames(true)
1325061da546Spatrick       .SetShowMembersOneLiner(false);
1326061da546Spatrick 
1327061da546Spatrick   AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,
1328061da546Spatrick                 "char8_t summary provider", ConstString("char8_t"),
1329061da546Spatrick                 widechar_flags);
1330061da546Spatrick   AddCXXSummary(
1331061da546Spatrick       cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
1332061da546Spatrick       "char16_t summary provider", ConstString("char16_t"), widechar_flags);
1333061da546Spatrick   AddCXXSummary(
1334061da546Spatrick       cpp_category_sp, lldb_private::formatters::Char32SummaryProvider,
1335061da546Spatrick       "char32_t summary provider", ConstString("char32_t"), widechar_flags);
1336061da546Spatrick   AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider,
1337061da546Spatrick                 "wchar_t summary provider", ConstString("wchar_t"),
1338061da546Spatrick                 widechar_flags);
1339061da546Spatrick 
1340061da546Spatrick   AddCXXSummary(
1341061da546Spatrick       cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
1342061da546Spatrick       "unichar summary provider", ConstString("unichar"), widechar_flags);
1343061da546Spatrick }
1344061da546Spatrick 
GetTypeScavenger()1345061da546Spatrick std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
1346061da546Spatrick   class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
1347061da546Spatrick   public:
1348061da546Spatrick     CompilerType AdjustForInclusion(CompilerType &candidate) override {
1349061da546Spatrick       LanguageType lang_type(candidate.GetMinimumLanguage());
1350061da546Spatrick       if (!Language::LanguageIsC(lang_type) &&
1351061da546Spatrick           !Language::LanguageIsCPlusPlus(lang_type))
1352061da546Spatrick         return CompilerType();
1353061da546Spatrick       if (candidate.IsTypedefType())
1354061da546Spatrick         return candidate.GetTypedefedType();
1355061da546Spatrick       return candidate;
1356061da546Spatrick     }
1357061da546Spatrick   };
1358061da546Spatrick 
1359061da546Spatrick   return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());
1360061da546Spatrick }
1361061da546Spatrick 
GetFormatters()1362061da546Spatrick lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
1363061da546Spatrick   static llvm::once_flag g_initialize;
1364061da546Spatrick   static TypeCategoryImplSP g_category;
1365061da546Spatrick 
1366061da546Spatrick   llvm::call_once(g_initialize, [this]() -> void {
1367*f6aab3d8Srobert     DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),
1368*f6aab3d8Srobert                                                g_category);
1369061da546Spatrick     if (g_category) {
1370061da546Spatrick       LoadLibStdcppFormatters(g_category);
1371061da546Spatrick       LoadLibCxxFormatters(g_category);
1372061da546Spatrick       LoadSystemFormatters(g_category);
1373061da546Spatrick     }
1374061da546Spatrick   });
1375061da546Spatrick   return g_category;
1376061da546Spatrick }
1377061da546Spatrick 
1378061da546Spatrick HardcodedFormatters::HardcodedSummaryFinder
GetHardcodedSummaries()1379061da546Spatrick CPlusPlusLanguage::GetHardcodedSummaries() {
1380061da546Spatrick   static llvm::once_flag g_initialize;
1381061da546Spatrick   static ConstString g_vectortypes("VectorTypes");
1382061da546Spatrick   static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
1383061da546Spatrick 
1384061da546Spatrick   llvm::call_once(g_initialize, []() -> void {
1385061da546Spatrick     g_formatters.push_back(
1386061da546Spatrick         [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1387061da546Spatrick            FormatManager &) -> TypeSummaryImpl::SharedPointer {
1388061da546Spatrick           static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1389061da546Spatrick               new CXXFunctionSummaryFormat(
1390061da546Spatrick                   TypeSummaryImpl::Flags(),
1391061da546Spatrick                   lldb_private::formatters::CXXFunctionPointerSummaryProvider,
1392061da546Spatrick                   "Function pointer summary provider"));
1393061da546Spatrick           if (valobj.GetCompilerType().IsFunctionPointerType()) {
1394061da546Spatrick             return formatter_sp;
1395061da546Spatrick           }
1396061da546Spatrick           return nullptr;
1397061da546Spatrick         });
1398061da546Spatrick     g_formatters.push_back(
1399061da546Spatrick         [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1400061da546Spatrick            FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
1401061da546Spatrick           static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1402061da546Spatrick               new CXXFunctionSummaryFormat(
1403061da546Spatrick                   TypeSummaryImpl::Flags()
1404061da546Spatrick                       .SetCascades(true)
1405061da546Spatrick                       .SetDontShowChildren(true)
1406061da546Spatrick                       .SetHideItemNames(true)
1407061da546Spatrick                       .SetShowMembersOneLiner(true)
1408061da546Spatrick                       .SetSkipPointers(true)
1409061da546Spatrick                       .SetSkipReferences(false),
1410061da546Spatrick                   lldb_private::formatters::VectorTypeSummaryProvider,
1411061da546Spatrick                   "vector_type pointer summary provider"));
1412be691f3bSpatrick           if (valobj.GetCompilerType().IsVectorType()) {
1413061da546Spatrick             if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
1414061da546Spatrick               return formatter_sp;
1415061da546Spatrick           }
1416061da546Spatrick           return nullptr;
1417061da546Spatrick         });
1418061da546Spatrick     g_formatters.push_back(
1419061da546Spatrick         [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1420061da546Spatrick            FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
1421061da546Spatrick           static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1422061da546Spatrick               new CXXFunctionSummaryFormat(
1423061da546Spatrick                   TypeSummaryImpl::Flags()
1424061da546Spatrick                       .SetCascades(true)
1425061da546Spatrick                       .SetDontShowChildren(true)
1426061da546Spatrick                       .SetHideItemNames(true)
1427061da546Spatrick                       .SetShowMembersOneLiner(true)
1428061da546Spatrick                       .SetSkipPointers(true)
1429061da546Spatrick                       .SetSkipReferences(false),
1430061da546Spatrick                   lldb_private::formatters::BlockPointerSummaryProvider,
1431061da546Spatrick                   "block pointer summary provider"));
1432be691f3bSpatrick           if (valobj.GetCompilerType().IsBlockPointerType()) {
1433061da546Spatrick             return formatter_sp;
1434061da546Spatrick           }
1435061da546Spatrick           return nullptr;
1436061da546Spatrick         });
1437061da546Spatrick   });
1438061da546Spatrick 
1439061da546Spatrick   return g_formatters;
1440061da546Spatrick }
1441061da546Spatrick 
1442061da546Spatrick HardcodedFormatters::HardcodedSyntheticFinder
GetHardcodedSynthetics()1443061da546Spatrick CPlusPlusLanguage::GetHardcodedSynthetics() {
1444061da546Spatrick   static llvm::once_flag g_initialize;
1445061da546Spatrick   static ConstString g_vectortypes("VectorTypes");
1446061da546Spatrick   static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
1447061da546Spatrick 
1448061da546Spatrick   llvm::call_once(g_initialize, []() -> void {
1449061da546Spatrick     g_formatters.push_back([](lldb_private::ValueObject &valobj,
1450*f6aab3d8Srobert                               lldb::DynamicValueType, FormatManager &fmt_mgr)
1451*f6aab3d8Srobert                                -> SyntheticChildren::SharedPointer {
1452061da546Spatrick       static CXXSyntheticChildren::SharedPointer formatter_sp(
1453061da546Spatrick           new CXXSyntheticChildren(
1454061da546Spatrick               SyntheticChildren::Flags()
1455061da546Spatrick                   .SetCascades(true)
1456061da546Spatrick                   .SetSkipPointers(true)
1457061da546Spatrick                   .SetSkipReferences(true)
1458061da546Spatrick                   .SetNonCacheable(true),
1459061da546Spatrick               "vector_type synthetic children",
1460061da546Spatrick               lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
1461be691f3bSpatrick       if (valobj.GetCompilerType().IsVectorType()) {
1462061da546Spatrick         if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
1463061da546Spatrick           return formatter_sp;
1464061da546Spatrick       }
1465061da546Spatrick       return nullptr;
1466061da546Spatrick     });
1467061da546Spatrick     g_formatters.push_back([](lldb_private::ValueObject &valobj,
1468*f6aab3d8Srobert                               lldb::DynamicValueType, FormatManager &fmt_mgr)
1469*f6aab3d8Srobert                                -> SyntheticChildren::SharedPointer {
1470061da546Spatrick       static CXXSyntheticChildren::SharedPointer formatter_sp(
1471061da546Spatrick           new CXXSyntheticChildren(
1472061da546Spatrick               SyntheticChildren::Flags()
1473061da546Spatrick                   .SetCascades(true)
1474061da546Spatrick                   .SetSkipPointers(true)
1475061da546Spatrick                   .SetSkipReferences(true)
1476061da546Spatrick                   .SetNonCacheable(true),
1477061da546Spatrick               "block pointer synthetic children",
1478061da546Spatrick               lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
1479be691f3bSpatrick       if (valobj.GetCompilerType().IsBlockPointerType()) {
1480061da546Spatrick         return formatter_sp;
1481061da546Spatrick       }
1482061da546Spatrick       return nullptr;
1483061da546Spatrick     });
1484061da546Spatrick   });
1485061da546Spatrick 
1486061da546Spatrick   return g_formatters;
1487061da546Spatrick }
1488061da546Spatrick 
IsNilReference(ValueObject & valobj)1489be691f3bSpatrick bool CPlusPlusLanguage::IsNilReference(ValueObject &valobj) {
1490be691f3bSpatrick   if (!Language::LanguageIsCPlusPlus(valobj.GetObjectRuntimeLanguage()) ||
1491be691f3bSpatrick       !valobj.IsPointerType())
1492be691f3bSpatrick     return false;
1493be691f3bSpatrick   bool canReadValue = true;
1494be691f3bSpatrick   bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
1495be691f3bSpatrick   return canReadValue && isZero;
1496be691f3bSpatrick }
1497be691f3bSpatrick 
IsSourceFile(llvm::StringRef file_path) const1498061da546Spatrick bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
1499061da546Spatrick   const auto suffixes = {".cpp", ".cxx", ".c++", ".cc",  ".c",
1500061da546Spatrick                          ".h",   ".hh",  ".hpp", ".hxx", ".h++"};
1501061da546Spatrick   for (auto suffix : suffixes) {
1502be691f3bSpatrick     if (file_path.endswith_insensitive(suffix))
1503061da546Spatrick       return true;
1504061da546Spatrick   }
1505061da546Spatrick 
1506061da546Spatrick   // Check if we're in a STL path (where the files usually have no extension
1507061da546Spatrick   // that we could check for.
1508061da546Spatrick   return file_path.contains("/usr/include/c++/");
1509061da546Spatrick }
1510*f6aab3d8Srobert 
GetFunctionDisplayName(const SymbolContext * sc,const ExecutionContext * exe_ctx,FunctionNameRepresentation representation,Stream & s)1511*f6aab3d8Srobert bool CPlusPlusLanguage::GetFunctionDisplayName(
1512*f6aab3d8Srobert     const SymbolContext *sc, const ExecutionContext *exe_ctx,
1513*f6aab3d8Srobert     FunctionNameRepresentation representation, Stream &s) {
1514*f6aab3d8Srobert   switch (representation) {
1515*f6aab3d8Srobert   case FunctionNameRepresentation::eNameWithArgs: {
1516*f6aab3d8Srobert     // Print the function name with arguments in it
1517*f6aab3d8Srobert     if (sc->function) {
1518*f6aab3d8Srobert       ExecutionContextScope *exe_scope =
1519*f6aab3d8Srobert           exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
1520*f6aab3d8Srobert       const char *cstr = sc->function->GetName().AsCString(nullptr);
1521*f6aab3d8Srobert       if (cstr) {
1522*f6aab3d8Srobert         const InlineFunctionInfo *inline_info = nullptr;
1523*f6aab3d8Srobert         VariableListSP variable_list_sp;
1524*f6aab3d8Srobert         bool get_function_vars = true;
1525*f6aab3d8Srobert         if (sc->block) {
1526*f6aab3d8Srobert           Block *inline_block = sc->block->GetContainingInlinedBlock();
1527*f6aab3d8Srobert 
1528*f6aab3d8Srobert           if (inline_block) {
1529*f6aab3d8Srobert             get_function_vars = false;
1530*f6aab3d8Srobert             inline_info = sc->block->GetInlinedFunctionInfo();
1531*f6aab3d8Srobert             if (inline_info)
1532*f6aab3d8Srobert               variable_list_sp = inline_block->GetBlockVariableList(true);
1533*f6aab3d8Srobert           }
1534*f6aab3d8Srobert         }
1535*f6aab3d8Srobert 
1536*f6aab3d8Srobert         if (get_function_vars) {
1537*f6aab3d8Srobert           variable_list_sp =
1538*f6aab3d8Srobert               sc->function->GetBlock(true).GetBlockVariableList(true);
1539*f6aab3d8Srobert         }
1540*f6aab3d8Srobert 
1541*f6aab3d8Srobert         if (inline_info) {
1542*f6aab3d8Srobert           s.PutCString(cstr);
1543*f6aab3d8Srobert           s.PutCString(" [inlined] ");
1544*f6aab3d8Srobert           cstr = inline_info->GetName().GetCString();
1545*f6aab3d8Srobert         }
1546*f6aab3d8Srobert 
1547*f6aab3d8Srobert         VariableList args;
1548*f6aab3d8Srobert         if (variable_list_sp)
1549*f6aab3d8Srobert           variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
1550*f6aab3d8Srobert                                                      args);
1551*f6aab3d8Srobert         if (args.GetSize() > 0) {
1552*f6aab3d8Srobert           if (!PrettyPrintFunctionNameWithArgs(s, cstr, exe_scope, args))
1553*f6aab3d8Srobert             return false;
1554*f6aab3d8Srobert         } else {
1555*f6aab3d8Srobert           s.PutCString(cstr);
1556*f6aab3d8Srobert         }
1557*f6aab3d8Srobert         return true;
1558*f6aab3d8Srobert       }
1559*f6aab3d8Srobert     } else if (sc->symbol) {
1560*f6aab3d8Srobert       const char *cstr = sc->symbol->GetName().AsCString(nullptr);
1561*f6aab3d8Srobert       if (cstr) {
1562*f6aab3d8Srobert         s.PutCString(cstr);
1563*f6aab3d8Srobert         return true;
1564*f6aab3d8Srobert       }
1565*f6aab3d8Srobert     }
1566*f6aab3d8Srobert   } break;
1567*f6aab3d8Srobert   default:
1568*f6aab3d8Srobert     return false;
1569*f6aab3d8Srobert   }
1570*f6aab3d8Srobert 
1571*f6aab3d8Srobert   return false;
1572*f6aab3d8Srobert }
1573