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