Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
39642 views
1
//===-- CPlusPlusLanguage.cpp ---------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "CPlusPlusLanguage.h"
10
11
#include <cctype>
12
#include <cstring>
13
14
#include <functional>
15
#include <memory>
16
#include <mutex>
17
#include <set>
18
19
#include "llvm/ADT/StringRef.h"
20
#include "llvm/Demangle/ItaniumDemangle.h"
21
22
#include "lldb/Core/Mangled.h"
23
#include "lldb/Core/Module.h"
24
#include "lldb/Core/PluginManager.h"
25
#include "lldb/Core/UniqueCStringMap.h"
26
#include "lldb/Core/ValueObjectVariable.h"
27
#include "lldb/DataFormatters/CXXFunctionPointer.h"
28
#include "lldb/DataFormatters/DataVisualization.h"
29
#include "lldb/DataFormatters/FormattersHelpers.h"
30
#include "lldb/DataFormatters/VectorType.h"
31
#include "lldb/Symbol/SymbolFile.h"
32
#include "lldb/Symbol/VariableList.h"
33
#include "lldb/Utility/ConstString.h"
34
#include "lldb/Utility/LLDBLog.h"
35
#include "lldb/Utility/Log.h"
36
#include "lldb/Utility/RegularExpression.h"
37
38
#include "BlockPointer.h"
39
#include "CPlusPlusNameParser.h"
40
#include "Coroutines.h"
41
#include "CxxStringTypes.h"
42
#include "Generic.h"
43
#include "LibCxx.h"
44
#include "LibCxxAtomic.h"
45
#include "LibCxxVariant.h"
46
#include "LibStdcpp.h"
47
#include "MSVCUndecoratedNameParser.h"
48
#include "lldb/lldb-enumerations.h"
49
50
using namespace lldb;
51
using namespace lldb_private;
52
using namespace lldb_private::formatters;
53
54
LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)
55
56
void CPlusPlusLanguage::Initialize() {
57
PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
58
CreateInstance);
59
}
60
61
void CPlusPlusLanguage::Terminate() {
62
PluginManager::UnregisterPlugin(CreateInstance);
63
}
64
65
bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
66
const char *mangled_name = mangled.GetMangledName().GetCString();
67
return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name);
68
}
69
70
ConstString CPlusPlusLanguage::GetDemangledFunctionNameWithoutArguments(
71
Mangled mangled) const {
72
const char *mangled_name_cstr = mangled.GetMangledName().GetCString();
73
ConstString demangled_name = mangled.GetDemangledName();
74
if (demangled_name && mangled_name_cstr && mangled_name_cstr[0]) {
75
if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
76
(mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
77
// typeinfo structure, and typeinfo
78
// mangled_name
79
mangled_name_cstr[2] != 'G' && // avoid guard variables
80
mangled_name_cstr[2] != 'Z')) // named local entities (if we
81
// eventually handle eSymbolTypeData,
82
// we will want this back)
83
{
84
CPlusPlusLanguage::MethodName cxx_method(demangled_name);
85
if (!cxx_method.GetBasename().empty()) {
86
std::string shortname;
87
if (!cxx_method.GetContext().empty())
88
shortname = cxx_method.GetContext().str() + "::";
89
shortname += cxx_method.GetBasename().str();
90
return ConstString(shortname);
91
}
92
}
93
}
94
if (demangled_name)
95
return demangled_name;
96
return mangled.GetMangledName();
97
}
98
99
// Static Functions
100
101
Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
102
// Use plugin for C++ but not for Objective-C++ (which has its own plugin).
103
if (Language::LanguageIsCPlusPlus(language) &&
104
language != eLanguageTypeObjC_plus_plus)
105
return new CPlusPlusLanguage();
106
return nullptr;
107
}
108
109
void CPlusPlusLanguage::MethodName::Clear() {
110
m_full.Clear();
111
m_basename = llvm::StringRef();
112
m_context = llvm::StringRef();
113
m_arguments = llvm::StringRef();
114
m_qualifiers = llvm::StringRef();
115
m_return_type = llvm::StringRef();
116
m_parsed = false;
117
m_parse_error = false;
118
}
119
120
static bool ReverseFindMatchingChars(const llvm::StringRef &s,
121
const llvm::StringRef &left_right_chars,
122
size_t &left_pos, size_t &right_pos,
123
size_t pos = llvm::StringRef::npos) {
124
assert(left_right_chars.size() == 2);
125
left_pos = llvm::StringRef::npos;
126
const char left_char = left_right_chars[0];
127
const char right_char = left_right_chars[1];
128
pos = s.find_last_of(left_right_chars, pos);
129
if (pos == llvm::StringRef::npos || s[pos] == left_char)
130
return false;
131
right_pos = pos;
132
uint32_t depth = 1;
133
while (pos > 0 && depth > 0) {
134
pos = s.find_last_of(left_right_chars, pos);
135
if (pos == llvm::StringRef::npos)
136
return false;
137
if (s[pos] == left_char) {
138
if (--depth == 0) {
139
left_pos = pos;
140
return left_pos < right_pos;
141
}
142
} else if (s[pos] == right_char) {
143
++depth;
144
}
145
}
146
return false;
147
}
148
149
static bool IsTrivialBasename(const llvm::StringRef &basename) {
150
// Check that the basename matches with the following regular expression
151
// "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation
152
// because it is significantly more efficient then using the general purpose
153
// regular expression library.
154
size_t idx = 0;
155
if (basename.starts_with('~'))
156
idx = 1;
157
158
if (basename.size() <= idx)
159
return false; // Empty string or "~"
160
161
if (!std::isalpha(basename[idx]) && basename[idx] != '_')
162
return false; // First character (after removing the possible '~'') isn't in
163
// [A-Za-z_]
164
165
// Read all characters matching [A-Za-z_0-9]
166
++idx;
167
while (idx < basename.size()) {
168
if (!std::isalnum(basename[idx]) && basename[idx] != '_')
169
break;
170
++idx;
171
}
172
173
// We processed all characters. It is a vaild basename.
174
return idx == basename.size();
175
}
176
177
/// Writes out the function name in 'full_name' to 'out_stream'
178
/// but replaces each argument type with the variable name
179
/// and the corresponding pretty-printed value
180
static bool PrettyPrintFunctionNameWithArgs(Stream &out_stream,
181
char const *full_name,
182
ExecutionContextScope *exe_scope,
183
VariableList const &args) {
184
CPlusPlusLanguage::MethodName cpp_method{ConstString(full_name)};
185
186
if (!cpp_method.IsValid())
187
return false;
188
189
llvm::StringRef return_type = cpp_method.GetReturnType();
190
if (!return_type.empty()) {
191
out_stream.PutCString(return_type);
192
out_stream.PutChar(' ');
193
}
194
195
out_stream.PutCString(cpp_method.GetScopeQualifiedName());
196
out_stream.PutChar('(');
197
198
FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope);
199
200
out_stream.PutChar(')');
201
202
llvm::StringRef qualifiers = cpp_method.GetQualifiers();
203
if (!qualifiers.empty()) {
204
out_stream.PutChar(' ');
205
out_stream.PutCString(qualifiers);
206
}
207
208
return true;
209
}
210
211
bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
212
// This method tries to parse simple method definitions which are presumably
213
// most comman in user programs. Definitions that can be parsed by this
214
// function don't have return types and templates in the name.
215
// A::B::C::fun(std::vector<T> &) const
216
size_t arg_start, arg_end;
217
llvm::StringRef full(m_full.GetCString());
218
llvm::StringRef parens("()", 2);
219
if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {
220
m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
221
if (arg_end + 1 < full.size())
222
m_qualifiers = full.substr(arg_end + 1).ltrim();
223
224
if (arg_start == 0)
225
return false;
226
size_t basename_end = arg_start;
227
size_t context_start = 0;
228
size_t context_end = full.rfind(':', basename_end);
229
if (context_end == llvm::StringRef::npos)
230
m_basename = full.substr(0, basename_end);
231
else {
232
if (context_start < context_end)
233
m_context = full.substr(context_start, context_end - 1 - context_start);
234
const size_t basename_begin = context_end + 1;
235
m_basename = full.substr(basename_begin, basename_end - basename_begin);
236
}
237
238
if (IsTrivialBasename(m_basename)) {
239
return true;
240
} else {
241
// The C++ basename doesn't match our regular expressions so this can't
242
// be a valid C++ method, clear everything out and indicate an error
243
m_context = llvm::StringRef();
244
m_basename = llvm::StringRef();
245
m_arguments = llvm::StringRef();
246
m_qualifiers = llvm::StringRef();
247
m_return_type = llvm::StringRef();
248
return false;
249
}
250
}
251
return false;
252
}
253
254
void CPlusPlusLanguage::MethodName::Parse() {
255
if (!m_parsed && m_full) {
256
if (TrySimplifiedParse()) {
257
m_parse_error = false;
258
} else {
259
CPlusPlusNameParser parser(m_full.GetStringRef());
260
if (auto function = parser.ParseAsFunctionDefinition()) {
261
m_basename = function->name.basename;
262
m_context = function->name.context;
263
m_arguments = function->arguments;
264
m_qualifiers = function->qualifiers;
265
m_return_type = function->return_type;
266
m_parse_error = false;
267
} else {
268
m_parse_error = true;
269
}
270
}
271
m_parsed = true;
272
}
273
}
274
275
llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() {
276
if (!m_parsed)
277
Parse();
278
return m_basename;
279
}
280
281
llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() {
282
if (!m_parsed)
283
Parse();
284
return m_context;
285
}
286
287
llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() {
288
if (!m_parsed)
289
Parse();
290
return m_arguments;
291
}
292
293
llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() {
294
if (!m_parsed)
295
Parse();
296
return m_qualifiers;
297
}
298
299
llvm::StringRef CPlusPlusLanguage::MethodName::GetReturnType() {
300
if (!m_parsed)
301
Parse();
302
return m_return_type;
303
}
304
305
std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
306
if (!m_parsed)
307
Parse();
308
if (m_context.empty())
309
return std::string(m_basename);
310
311
std::string res;
312
res += m_context;
313
res += "::";
314
res += m_basename;
315
return res;
316
}
317
318
llvm::StringRef
319
CPlusPlusLanguage::MethodName::GetBasenameNoTemplateParameters() {
320
llvm::StringRef basename = GetBasename();
321
size_t arg_start, arg_end;
322
llvm::StringRef parens("<>", 2);
323
if (ReverseFindMatchingChars(basename, parens, arg_start, arg_end))
324
return basename.substr(0, arg_start);
325
326
return basename;
327
}
328
329
bool CPlusPlusLanguage::MethodName::ContainsPath(llvm::StringRef path) {
330
if (!m_parsed)
331
Parse();
332
333
// If we can't parse the incoming name, then just check that it contains path.
334
if (m_parse_error)
335
return m_full.GetStringRef().contains(path);
336
337
llvm::StringRef identifier;
338
llvm::StringRef context;
339
std::string path_str = path.str();
340
bool success = CPlusPlusLanguage::ExtractContextAndIdentifier(
341
path_str.c_str(), context, identifier);
342
if (!success)
343
return m_full.GetStringRef().contains(path);
344
345
// Basename may include template arguments.
346
// E.g.,
347
// GetBaseName(): func<int>
348
// identifier : func
349
//
350
// ...but we still want to account for identifiers with template parameter
351
// lists, e.g., when users set breakpoints on template specializations.
352
//
353
// E.g.,
354
// GetBaseName(): func<uint32_t>
355
// identifier : func<int32_t*>
356
//
357
// Try to match the basename with or without template parameters.
358
if (GetBasename() != identifier &&
359
GetBasenameNoTemplateParameters() != identifier)
360
return false;
361
362
// Incoming path only had an identifier, so we match.
363
if (context.empty())
364
return true;
365
// Incoming path has context but this method does not, no match.
366
if (m_context.empty())
367
return false;
368
369
llvm::StringRef haystack = m_context;
370
if (!haystack.consume_back(context))
371
return false;
372
if (haystack.empty() || !isalnum(haystack.back()))
373
return true;
374
375
return false;
376
}
377
378
bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) {
379
// FIXME!! we should really run through all the known C++ Language plugins
380
// and ask each one if this is a C++ mangled name
381
382
Mangled::ManglingScheme scheme = Mangled::GetManglingScheme(name);
383
384
if (scheme == Mangled::eManglingSchemeNone)
385
return false;
386
387
return true;
388
}
389
390
bool CPlusPlusLanguage::DemangledNameContainsPath(llvm::StringRef path,
391
ConstString demangled) const {
392
MethodName demangled_name(demangled);
393
return demangled_name.ContainsPath(path);
394
}
395
396
bool CPlusPlusLanguage::ExtractContextAndIdentifier(
397
const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
398
if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name))
399
return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context,
400
identifier);
401
402
CPlusPlusNameParser parser(name);
403
if (auto full_name = parser.ParseAsFullName()) {
404
identifier = full_name->basename;
405
context = full_name->context;
406
return true;
407
}
408
return false;
409
}
410
411
namespace {
412
class NodeAllocator {
413
llvm::BumpPtrAllocator Alloc;
414
415
public:
416
void reset() { Alloc.Reset(); }
417
418
template <typename T, typename... Args> T *makeNode(Args &&... args) {
419
return new (Alloc.Allocate(sizeof(T), alignof(T)))
420
T(std::forward<Args>(args)...);
421
}
422
423
void *allocateNodeArray(size_t sz) {
424
return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,
425
alignof(llvm::itanium_demangle::Node *));
426
}
427
};
428
429
template <typename Derived>
430
class ManglingSubstitutor
431
: public llvm::itanium_demangle::AbstractManglingParser<Derived,
432
NodeAllocator> {
433
using Base =
434
llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
435
436
public:
437
ManglingSubstitutor() : Base(nullptr, nullptr) {}
438
439
template <typename... Ts>
440
ConstString substitute(llvm::StringRef Mangled, Ts &&... Vals) {
441
this->getDerived().reset(Mangled, std::forward<Ts>(Vals)...);
442
return substituteImpl(Mangled);
443
}
444
445
protected:
446
void reset(llvm::StringRef Mangled) {
447
Base::reset(Mangled.begin(), Mangled.end());
448
Written = Mangled.begin();
449
Result.clear();
450
Substituted = false;
451
}
452
453
ConstString substituteImpl(llvm::StringRef Mangled) {
454
Log *log = GetLog(LLDBLog::Language);
455
if (this->parse() == nullptr) {
456
LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled);
457
return ConstString();
458
}
459
if (!Substituted)
460
return ConstString();
461
462
// Append any trailing unmodified input.
463
appendUnchangedInput();
464
LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
465
return ConstString(Result);
466
}
467
468
void trySubstitute(llvm::StringRef From, llvm::StringRef To) {
469
if (!llvm::StringRef(currentParserPos(), this->numLeft()).starts_with(From))
470
return;
471
472
// We found a match. Append unmodified input up to this point.
473
appendUnchangedInput();
474
475
// And then perform the replacement.
476
Result += To;
477
Written += From.size();
478
Substituted = true;
479
}
480
481
private:
482
/// Input character until which we have constructed the respective output
483
/// already.
484
const char *Written = "";
485
486
llvm::SmallString<128> Result;
487
488
/// Whether we have performed any substitutions.
489
bool Substituted = false;
490
491
const char *currentParserPos() const { return this->First; }
492
493
void appendUnchangedInput() {
494
Result +=
495
llvm::StringRef(Written, std::distance(Written, currentParserPos()));
496
Written = currentParserPos();
497
}
498
};
499
500
/// Given a mangled function `Mangled`, replace all the primitive function type
501
/// arguments of `Search` with type `Replace`.
502
class TypeSubstitutor : public ManglingSubstitutor<TypeSubstitutor> {
503
llvm::StringRef Search;
504
llvm::StringRef Replace;
505
506
public:
507
void reset(llvm::StringRef Mangled, llvm::StringRef Search,
508
llvm::StringRef Replace) {
509
ManglingSubstitutor::reset(Mangled);
510
this->Search = Search;
511
this->Replace = Replace;
512
}
513
514
llvm::itanium_demangle::Node *parseType() {
515
trySubstitute(Search, Replace);
516
return ManglingSubstitutor::parseType();
517
}
518
};
519
520
class CtorDtorSubstitutor : public ManglingSubstitutor<CtorDtorSubstitutor> {
521
public:
522
llvm::itanium_demangle::Node *
523
parseCtorDtorName(llvm::itanium_demangle::Node *&SoFar, NameState *State) {
524
trySubstitute("C1", "C2");
525
trySubstitute("D1", "D2");
526
return ManglingSubstitutor::parseCtorDtorName(SoFar, State);
527
}
528
};
529
} // namespace
530
531
std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings(
532
const ConstString mangled_name) const {
533
std::vector<ConstString> alternates;
534
535
/// Get a basic set of alternative manglings for the given symbol `name`, by
536
/// making a few basic possible substitutions on basic types, storage duration
537
/// and `const`ness for the given symbol. The output parameter `alternates`
538
/// is filled with a best-guess, non-exhaustive set of different manglings
539
/// for the given name.
540
541
// Maybe we're looking for a const symbol but the debug info told us it was
542
// non-const...
543
if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&
544
strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
545
std::string fixed_scratch("_ZNK");
546
fixed_scratch.append(mangled_name.GetCString() + 3);
547
alternates.push_back(ConstString(fixed_scratch));
548
}
549
550
// Maybe we're looking for a static symbol but we thought it was global...
551
if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&
552
strncmp(mangled_name.GetCString(), "_ZL", 3)) {
553
std::string fixed_scratch("_ZL");
554
fixed_scratch.append(mangled_name.GetCString() + 2);
555
alternates.push_back(ConstString(fixed_scratch));
556
}
557
558
TypeSubstitutor TS;
559
// `char` is implementation defined as either `signed` or `unsigned`. As a
560
// result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
561
// char, 'h'-unsigned char. If we're looking for symbols with a signed char
562
// parameter, try finding matches which have the general case 'c'.
563
if (ConstString char_fixup =
564
TS.substitute(mangled_name.GetStringRef(), "a", "c"))
565
alternates.push_back(char_fixup);
566
567
// long long parameter mangling 'x', may actually just be a long 'l' argument
568
if (ConstString long_fixup =
569
TS.substitute(mangled_name.GetStringRef(), "x", "l"))
570
alternates.push_back(long_fixup);
571
572
// unsigned long long parameter mangling 'y', may actually just be unsigned
573
// long 'm' argument
574
if (ConstString ulong_fixup =
575
TS.substitute(mangled_name.GetStringRef(), "y", "m"))
576
alternates.push_back(ulong_fixup);
577
578
if (ConstString ctor_fixup =
579
CtorDtorSubstitutor().substitute(mangled_name.GetStringRef()))
580
alternates.push_back(ctor_fixup);
581
582
return alternates;
583
}
584
585
ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName(
586
const Mangled mangled, const SymbolContext &sym_ctx) const {
587
ConstString demangled = mangled.GetDemangledName();
588
if (!demangled)
589
return ConstString();
590
591
CPlusPlusLanguage::MethodName cpp_name(demangled);
592
std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
593
594
if (!scope_qualified_name.size())
595
return ConstString();
596
597
if (!sym_ctx.module_sp)
598
return ConstString();
599
600
lldb_private::SymbolFile *sym_file = sym_ctx.module_sp->GetSymbolFile();
601
if (!sym_file)
602
return ConstString();
603
604
std::vector<ConstString> alternates;
605
sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
606
607
std::vector<ConstString> param_and_qual_matches;
608
std::vector<ConstString> param_matches;
609
for (size_t i = 0; i < alternates.size(); i++) {
610
ConstString alternate_mangled_name = alternates[i];
611
Mangled mangled(alternate_mangled_name);
612
ConstString demangled = mangled.GetDemangledName();
613
614
CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
615
if (!cpp_name.IsValid())
616
continue;
617
618
if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) {
619
if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
620
param_and_qual_matches.push_back(alternate_mangled_name);
621
else
622
param_matches.push_back(alternate_mangled_name);
623
}
624
}
625
626
if (param_and_qual_matches.size())
627
return param_and_qual_matches[0]; // It is assumed that there will be only
628
// one!
629
else if (param_matches.size())
630
return param_matches[0]; // Return one of them as a best match
631
else
632
return ConstString();
633
}
634
635
static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
636
if (!cpp_category_sp)
637
return;
638
639
TypeSummaryImpl::Flags stl_summary_flags;
640
stl_summary_flags.SetCascades(true)
641
.SetSkipPointers(false)
642
.SetSkipReferences(false)
643
.SetDontShowChildren(true)
644
.SetDontShowValue(true)
645
.SetShowMembersOneLiner(false)
646
.SetHideItemNames(false);
647
648
AddCXXSummary(cpp_category_sp,
649
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
650
"std::string summary provider", "^std::__[[:alnum:]]+::string$",
651
stl_summary_flags, true);
652
AddCXXSummary(cpp_category_sp,
653
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
654
"std::string summary provider",
655
"^std::__[[:alnum:]]+::basic_string<char, "
656
"std::__[[:alnum:]]+::char_traits<char>, "
657
"std::__[[:alnum:]]+::allocator<char> >$",
658
stl_summary_flags, true);
659
AddCXXSummary(cpp_category_sp,
660
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
661
"std::string summary provider",
662
"^std::__[[:alnum:]]+::basic_string<unsigned char, "
663
"std::__[[:alnum:]]+::char_traits<unsigned char>, "
664
"std::__[[:alnum:]]+::allocator<unsigned char> >$",
665
stl_summary_flags, true);
666
667
AddCXXSummary(cpp_category_sp,
668
lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
669
"std::u16string summary provider",
670
"^std::__[[:alnum:]]+::basic_string<char16_t, "
671
"std::__[[:alnum:]]+::char_traits<char16_t>, "
672
"std::__[[:alnum:]]+::allocator<char16_t> >$",
673
stl_summary_flags, true);
674
675
AddCXXSummary(cpp_category_sp,
676
lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
677
"std::u32string summary provider",
678
"^std::__[[:alnum:]]+::basic_string<char32_t, "
679
"std::__[[:alnum:]]+::char_traits<char32_t>, "
680
"std::__[[:alnum:]]+::allocator<char32_t> >$",
681
stl_summary_flags, true);
682
683
AddCXXSummary(cpp_category_sp,
684
lldb_private::formatters::LibcxxWStringSummaryProvider,
685
"std::wstring summary provider",
686
"^std::__[[:alnum:]]+::wstring$", stl_summary_flags, true);
687
AddCXXSummary(cpp_category_sp,
688
lldb_private::formatters::LibcxxWStringSummaryProvider,
689
"std::wstring summary provider",
690
"^std::__[[:alnum:]]+::basic_string<wchar_t, "
691
"std::__[[:alnum:]]+::char_traits<wchar_t>, "
692
"std::__[[:alnum:]]+::allocator<wchar_t> >$",
693
stl_summary_flags, true);
694
695
AddCXXSummary(cpp_category_sp,
696
lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
697
"std::string_view summary provider",
698
"^std::__[[:alnum:]]+::string_view$", stl_summary_flags, true);
699
AddCXXSummary(cpp_category_sp,
700
lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
701
"std::string_view summary provider",
702
"^std::__[[:alnum:]]+::basic_string_view<char, "
703
"std::__[[:alnum:]]+::char_traits<char> >$",
704
stl_summary_flags, true);
705
AddCXXSummary(cpp_category_sp,
706
lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
707
"std::string_view summary provider",
708
"^std::__[[:alnum:]]+::basic_string_view<unsigned char, "
709
"std::__[[:alnum:]]+::char_traits<unsigned char> >$",
710
stl_summary_flags, true);
711
712
AddCXXSummary(cpp_category_sp,
713
lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16,
714
"std::u16string_view summary provider",
715
"^std::__[[:alnum:]]+::basic_string_view<char16_t, "
716
"std::__[[:alnum:]]+::char_traits<char16_t> >$",
717
stl_summary_flags, true);
718
719
AddCXXSummary(cpp_category_sp,
720
lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32,
721
"std::u32string_view summary provider",
722
"^std::__[[:alnum:]]+::basic_string_view<char32_t, "
723
"std::__[[:alnum:]]+::char_traits<char32_t> >$",
724
stl_summary_flags, true);
725
726
AddCXXSummary(cpp_category_sp,
727
lldb_private::formatters::LibcxxWStringViewSummaryProvider,
728
"std::wstring_view summary provider",
729
"^std::__[[:alnum:]]+::wstring_view$", stl_summary_flags, true);
730
AddCXXSummary(cpp_category_sp,
731
lldb_private::formatters::LibcxxWStringViewSummaryProvider,
732
"std::wstring_view summary provider",
733
"^std::__[[:alnum:]]+::basic_string_view<wchar_t, "
734
"std::__[[:alnum:]]+::char_traits<wchar_t> >$",
735
stl_summary_flags, true);
736
737
SyntheticChildren::Flags stl_synth_flags;
738
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
739
false);
740
SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
741
stl_deref_flags.SetFrontEndWantsDereference();
742
743
AddCXXSynthetic(
744
cpp_category_sp,
745
lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
746
"libc++ std::bitset synthetic children",
747
"^std::__[[:alnum:]]+::bitset<.+>$", stl_deref_flags, true);
748
AddCXXSynthetic(
749
cpp_category_sp,
750
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
751
"libc++ std::vector synthetic children",
752
"^std::__[[:alnum:]]+::vector<.+>$", stl_deref_flags, true);
753
AddCXXSynthetic(
754
cpp_category_sp,
755
lldb_private::formatters::LibcxxStdValarraySyntheticFrontEndCreator,
756
"libc++ std::valarray synthetic children",
757
"^std::__[[:alnum:]]+::valarray<.+>$", stl_deref_flags, true);
758
AddCXXSynthetic(
759
cpp_category_sp,
760
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator,
761
"libc++ std::slice_array synthetic children",
762
"^std::__[[:alnum:]]+::slice_array<.+>$", stl_deref_flags, true);
763
AddCXXSynthetic(
764
cpp_category_sp,
765
lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEndCreator,
766
"libc++ synthetic children for the valarray proxy arrays",
767
"^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$",
768
stl_deref_flags, true);
769
AddCXXSynthetic(
770
cpp_category_sp,
771
lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
772
"libc++ std::forward_list synthetic children",
773
"^std::__[[:alnum:]]+::forward_list<.+>$", stl_synth_flags, true);
774
AddCXXSynthetic(
775
cpp_category_sp,
776
lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
777
"libc++ std::list synthetic children",
778
// A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>$"
779
// so that it does not clash with: "^std::(__cxx11::)?list<.+>$"
780
"^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
781
"cxx11[[:alnum:]])[[:alnum:]]*::list<.+>$",
782
stl_deref_flags, true);
783
AddCXXSynthetic(
784
cpp_category_sp,
785
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
786
"libc++ std::map synthetic children", "^std::__[[:alnum:]]+::map<.+> >$",
787
stl_synth_flags, true);
788
AddCXXSynthetic(
789
cpp_category_sp,
790
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
791
"libc++ std::set synthetic children", "^std::__[[:alnum:]]+::set<.+> >$",
792
stl_deref_flags, true);
793
AddCXXSynthetic(
794
cpp_category_sp,
795
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
796
"libc++ std::multiset synthetic children",
797
"^std::__[[:alnum:]]+::multiset<.+> >$", stl_deref_flags, true);
798
AddCXXSynthetic(
799
cpp_category_sp,
800
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
801
"libc++ std::multimap synthetic children",
802
"^std::__[[:alnum:]]+::multimap<.+> >$", stl_synth_flags, true);
803
AddCXXSynthetic(
804
cpp_category_sp,
805
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator,
806
"libc++ std::unordered containers synthetic children",
807
"^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$",
808
stl_synth_flags, true);
809
AddCXXSynthetic(
810
cpp_category_sp,
811
lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator,
812
"libc++ std::initializer_list synthetic children",
813
"^std::initializer_list<.+>$", stl_synth_flags, true);
814
AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator,
815
"libc++ std::queue synthetic children",
816
"^std::__[[:alnum:]]+::queue<.+>$", stl_synth_flags, true);
817
AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator,
818
"libc++ std::tuple synthetic children",
819
"^std::__[[:alnum:]]+::tuple<.*>$", stl_synth_flags, true);
820
AddCXXSynthetic(cpp_category_sp, LibcxxOptionalSyntheticFrontEndCreator,
821
"libc++ std::optional synthetic children",
822
"^std::__[[:alnum:]]+::optional<.+>$", stl_synth_flags, true);
823
AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,
824
"libc++ std::variant synthetic children",
825
"^std::__[[:alnum:]]+::variant<.+>$", stl_synth_flags, true);
826
AddCXXSynthetic(
827
cpp_category_sp,
828
lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
829
"libc++ std::atomic synthetic children",
830
"^std::__[[:alnum:]]+::atomic<.+>$", stl_synth_flags, true);
831
AddCXXSynthetic(
832
cpp_category_sp,
833
lldb_private::formatters::LibcxxStdSpanSyntheticFrontEndCreator,
834
"libc++ std::span synthetic children", "^std::__[[:alnum:]]+::span<.+>$",
835
stl_deref_flags, true);
836
AddCXXSynthetic(
837
cpp_category_sp,
838
lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEndCreator,
839
"libc++ std::ranges::ref_view synthetic children",
840
"^std::__[[:alnum:]]+::ranges::ref_view<.+>$", stl_deref_flags, true);
841
842
cpp_category_sp->AddTypeSynthetic(
843
"^std::__[[:alnum:]]+::deque<.+>$", eFormatterMatchRegex,
844
SyntheticChildrenSP(new ScriptedSyntheticChildren(
845
stl_synth_flags,
846
"lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
847
848
AddCXXSynthetic(
849
cpp_category_sp,
850
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
851
"shared_ptr synthetic children", "^std::__[[:alnum:]]+::shared_ptr<.+>$",
852
stl_synth_flags, true);
853
854
static constexpr const char *const libcxx_std_unique_ptr_regex =
855
"^std::__[[:alnum:]]+::unique_ptr<.+>$";
856
AddCXXSynthetic(
857
cpp_category_sp,
858
lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator,
859
"unique_ptr synthetic children", libcxx_std_unique_ptr_regex,
860
stl_synth_flags, true);
861
862
AddCXXSynthetic(
863
cpp_category_sp,
864
lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator,
865
"weak_ptr synthetic children", "^std::__[[:alnum:]]+::weak_ptr<.+>$",
866
stl_synth_flags, true);
867
AddCXXSummary(cpp_category_sp,
868
lldb_private::formatters::LibcxxFunctionSummaryProvider,
869
"libc++ std::function summary provider",
870
"^std::__[[:alnum:]]+::function<.+>$", stl_summary_flags, true);
871
872
static constexpr const char *const libcxx_std_coroutine_handle_regex =
873
"^std::__[[:alnum:]]+::coroutine_handle<.+>$";
874
AddCXXSynthetic(
875
cpp_category_sp,
876
lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator,
877
"coroutine_handle synthetic children", libcxx_std_coroutine_handle_regex,
878
stl_deref_flags, true);
879
880
stl_summary_flags.SetDontShowChildren(false);
881
stl_summary_flags.SetSkipPointers(false);
882
AddCXXSummary(cpp_category_sp,
883
lldb_private::formatters::LibcxxContainerSummaryProvider,
884
"libc++ std::bitset summary provider",
885
"^std::__[[:alnum:]]+::bitset<.+>$", stl_summary_flags, true);
886
AddCXXSummary(cpp_category_sp,
887
lldb_private::formatters::LibcxxContainerSummaryProvider,
888
"libc++ std::vector summary provider",
889
"^std::__[[:alnum:]]+::vector<.+>$", stl_summary_flags, true);
890
AddCXXSummary(cpp_category_sp,
891
lldb_private::formatters::LibcxxContainerSummaryProvider,
892
"libc++ std::valarray summary provider",
893
"^std::__[[:alnum:]]+::valarray<.+>$", stl_summary_flags, true);
894
AddCXXSummary(cpp_category_sp,
895
lldb_private::formatters::LibcxxStdSliceArraySummaryProvider,
896
"libc++ std::slice_array summary provider",
897
"^std::__[[:alnum:]]+::slice_array<.+>$", stl_summary_flags,
898
true);
899
AddCXXSummary(cpp_category_sp,
900
lldb_private::formatters::LibcxxContainerSummaryProvider,
901
"libc++ summary provider for the valarray proxy arrays",
902
"^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$",
903
stl_summary_flags, true);
904
AddCXXSummary(
905
cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
906
"libc++ std::list summary provider",
907
"^std::__[[:alnum:]]+::forward_list<.+>$", stl_summary_flags, true);
908
AddCXXSummary(
909
cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
910
"libc++ std::list summary provider",
911
// A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>$"
912
// so that it does not clash with: "^std::(__cxx11::)?list<.+>$"
913
"^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
914
"cxx11[[:alnum:]])[[:alnum:]]*::list<.+>$",
915
stl_summary_flags, true);
916
AddCXXSummary(cpp_category_sp,
917
lldb_private::formatters::LibcxxContainerSummaryProvider,
918
"libc++ std::map summary provider",
919
"^std::__[[:alnum:]]+::map<.+>$", stl_summary_flags, true);
920
AddCXXSummary(cpp_category_sp,
921
lldb_private::formatters::LibcxxContainerSummaryProvider,
922
"libc++ std::deque summary provider",
923
"^std::__[[:alnum:]]+::deque<.+>$", stl_summary_flags, true);
924
AddCXXSummary(cpp_category_sp,
925
lldb_private::formatters::LibcxxContainerSummaryProvider,
926
"libc++ std::queue summary provider",
927
"^std::__[[:alnum:]]+::queue<.+>$", stl_summary_flags, true);
928
AddCXXSummary(cpp_category_sp,
929
lldb_private::formatters::LibcxxContainerSummaryProvider,
930
"libc++ std::set summary provider",
931
"^std::__[[:alnum:]]+::set<.+>$", stl_summary_flags, true);
932
AddCXXSummary(cpp_category_sp,
933
lldb_private::formatters::LibcxxContainerSummaryProvider,
934
"libc++ std::multiset summary provider",
935
"^std::__[[:alnum:]]+::multiset<.+>$", stl_summary_flags, true);
936
AddCXXSummary(cpp_category_sp,
937
lldb_private::formatters::LibcxxContainerSummaryProvider,
938
"libc++ std::multimap summary provider",
939
"^std::__[[:alnum:]]+::multimap<.+>$", stl_summary_flags, true);
940
AddCXXSummary(cpp_category_sp,
941
lldb_private::formatters::LibcxxContainerSummaryProvider,
942
"libc++ std::unordered containers summary provider",
943
"^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$",
944
stl_summary_flags, true);
945
AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider,
946
"libc++ std::tuple summary provider",
947
"^std::__[[:alnum:]]+::tuple<.*>$", stl_summary_flags, true);
948
AddCXXSummary(cpp_category_sp,
949
lldb_private::formatters::LibCxxAtomicSummaryProvider,
950
"libc++ std::atomic summary provider",
951
"^std::__[[:alnum:]]+::atomic<.+>$", stl_summary_flags, true);
952
AddCXXSummary(cpp_category_sp,
953
lldb_private::formatters::GenericOptionalSummaryProvider,
954
"libc++ std::optional summary provider",
955
"^std::__[[:alnum:]]+::optional<.+>$", stl_summary_flags, true);
956
AddCXXSummary(cpp_category_sp,
957
lldb_private::formatters::LibcxxVariantSummaryProvider,
958
"libc++ std::variant summary provider",
959
"^std::__[[:alnum:]]+::variant<.+>$", stl_summary_flags, true);
960
AddCXXSummary(cpp_category_sp,
961
lldb_private::formatters::LibcxxContainerSummaryProvider,
962
"libc++ std::span summary provider",
963
"^std::__[[:alnum:]]+::span<.+>$", stl_summary_flags, true);
964
965
stl_summary_flags.SetSkipPointers(true);
966
967
AddCXXSummary(cpp_category_sp,
968
lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
969
"libc++ std::shared_ptr summary provider",
970
"^std::__[[:alnum:]]+::shared_ptr<.+>$", stl_summary_flags,
971
true);
972
AddCXXSummary(cpp_category_sp,
973
lldb_private::formatters::LibcxxSmartPointerSummaryProvider,
974
"libc++ std::weak_ptr summary provider",
975
"^std::__[[:alnum:]]+::weak_ptr<.+>$", stl_summary_flags, true);
976
AddCXXSummary(cpp_category_sp,
977
lldb_private::formatters::LibcxxUniquePointerSummaryProvider,
978
"libc++ std::unique_ptr summary provider",
979
libcxx_std_unique_ptr_regex, stl_summary_flags, true);
980
981
AddCXXSummary(cpp_category_sp,
982
lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,
983
"libc++ std::coroutine_handle summary provider",
984
libcxx_std_coroutine_handle_regex, stl_summary_flags, true);
985
986
AddCXXSynthetic(
987
cpp_category_sp,
988
lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator,
989
"std::vector iterator synthetic children",
990
"^std::__[[:alnum:]]+::__wrap_iter<.+>$", stl_synth_flags, true);
991
992
AddCXXSynthetic(
993
cpp_category_sp,
994
lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator,
995
"std::map iterator synthetic children",
996
"^std::__[[:alnum:]]+::__map_(const_)?iterator<.+>$", stl_synth_flags,
997
true);
998
999
AddCXXSynthetic(cpp_category_sp,
1000
lldb_private::formatters::
1001
LibCxxUnorderedMapIteratorSyntheticFrontEndCreator,
1002
"std::unordered_map iterator synthetic children",
1003
"^std::__[[:alnum:]]+::__hash_map_(const_)?iterator<.+>$",
1004
stl_synth_flags, true);
1005
// Chrono duration typedefs
1006
cpp_category_sp->AddTypeSummary(
1007
"^std::__[[:alnum:]]+::chrono::nanoseconds", eFormatterMatchRegex,
1008
TypeSummaryImplSP(new StringSummaryFormat(
1009
eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ns")));
1010
cpp_category_sp->AddTypeSummary(
1011
"^std::__[[:alnum:]]+::chrono::microseconds", eFormatterMatchRegex,
1012
TypeSummaryImplSP(new StringSummaryFormat(
1013
eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} µs")));
1014
cpp_category_sp->AddTypeSummary(
1015
"^std::__[[:alnum:]]+::chrono::milliseconds", eFormatterMatchRegex,
1016
TypeSummaryImplSP(new StringSummaryFormat(
1017
eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ms")));
1018
cpp_category_sp->AddTypeSummary(
1019
"^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,
1020
TypeSummaryImplSP(new StringSummaryFormat(
1021
eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));
1022
cpp_category_sp->AddTypeSummary(
1023
"^std::__[[:alnum:]]+::chrono::minutes", eFormatterMatchRegex,
1024
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1025
eTypeOptionHideValue,
1026
"${var.__rep_} min")));
1027
cpp_category_sp->AddTypeSummary(
1028
"^std::__[[:alnum:]]+::chrono::hours", eFormatterMatchRegex,
1029
TypeSummaryImplSP(new StringSummaryFormat(
1030
eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} h")));
1031
1032
cpp_category_sp->AddTypeSummary(
1033
"^std::__[[:alnum:]]+::chrono::days", eFormatterMatchRegex,
1034
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1035
eTypeOptionHideValue,
1036
"${var.__rep_} days")));
1037
cpp_category_sp->AddTypeSummary(
1038
"^std::__[[:alnum:]]+::chrono::weeks", eFormatterMatchRegex,
1039
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1040
eTypeOptionHideValue,
1041
"${var.__rep_} weeks")));
1042
cpp_category_sp->AddTypeSummary(
1043
"^std::__[[:alnum:]]+::chrono::months", eFormatterMatchRegex,
1044
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1045
eTypeOptionHideValue,
1046
"${var.__rep_} months")));
1047
cpp_category_sp->AddTypeSummary(
1048
"^std::__[[:alnum:]]+::chrono::years", eFormatterMatchRegex,
1049
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1050
eTypeOptionHideValue,
1051
"${var.__rep_} years")));
1052
cpp_category_sp->AddTypeSummary(
1053
"^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,
1054
TypeSummaryImplSP(new StringSummaryFormat(
1055
eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));
1056
1057
// Chrono time point types
1058
1059
AddCXXSummary(cpp_category_sp,
1060
lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider,
1061
"libc++ std::chrono::sys_seconds summary provider",
1062
"^std::__[[:alnum:]]+::chrono::time_point<"
1063
"std::__[[:alnum:]]+::chrono::system_clock, "
1064
"std::__[[:alnum:]]+::chrono::duration<.*, "
1065
"std::__[[:alnum:]]+::ratio<1, 1> "
1066
"> >$",
1067
eTypeOptionHideChildren | eTypeOptionHideValue |
1068
eTypeOptionCascade,
1069
true);
1070
AddCXXSummary(cpp_category_sp,
1071
lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider,
1072
"libc++ std::chrono::sys_seconds summary provider",
1073
"^std::__[[:alnum:]]+::chrono::time_point<"
1074
"std::__[[:alnum:]]+::chrono::system_clock, "
1075
"std::__[[:alnum:]]+::chrono::duration<int, "
1076
"std::__[[:alnum:]]+::ratio<86400, 1> "
1077
"> >$",
1078
eTypeOptionHideChildren | eTypeOptionHideValue |
1079
eTypeOptionCascade,
1080
true);
1081
1082
AddCXXSummary(
1083
cpp_category_sp,
1084
lldb_private::formatters::LibcxxChronoLocalSecondsSummaryProvider,
1085
"libc++ std::chrono::local_seconds summary provider",
1086
"^std::__[[:alnum:]]+::chrono::time_point<"
1087
"std::__[[:alnum:]]+::chrono::local_t, "
1088
"std::__[[:alnum:]]+::chrono::duration<.*, "
1089
"std::__[[:alnum:]]+::ratio<1, 1> "
1090
"> >$",
1091
eTypeOptionHideChildren | eTypeOptionHideValue | eTypeOptionCascade,
1092
true);
1093
AddCXXSummary(cpp_category_sp,
1094
lldb_private::formatters::LibcxxChronoLocalDaysSummaryProvider,
1095
"libc++ std::chrono::local_seconds summary provider",
1096
"^std::__[[:alnum:]]+::chrono::time_point<"
1097
"std::__[[:alnum:]]+::chrono::local_t, "
1098
"std::__[[:alnum:]]+::chrono::duration<int, "
1099
"std::__[[:alnum:]]+::ratio<86400, 1> "
1100
"> >$",
1101
eTypeOptionHideChildren | eTypeOptionHideValue |
1102
eTypeOptionCascade,
1103
true);
1104
1105
// Chrono calendar types
1106
1107
cpp_category_sp->AddTypeSummary(
1108
"^std::__[[:alnum:]]+::chrono::day$", eFormatterMatchRegex,
1109
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1110
eTypeOptionHideValue,
1111
"day=${var.__d_%u}")));
1112
1113
AddCXXSummary(cpp_category_sp,
1114
lldb_private::formatters::LibcxxChronoMonthSummaryProvider,
1115
"libc++ std::chrono::month summary provider",
1116
"^std::__[[:alnum:]]+::chrono::month$",
1117
eTypeOptionHideChildren | eTypeOptionHideValue, true);
1118
1119
cpp_category_sp->AddTypeSummary(
1120
"^std::__[[:alnum:]]+::chrono::year$", eFormatterMatchRegex,
1121
TypeSummaryImplSP(new StringSummaryFormat(
1122
eTypeOptionHideChildren | eTypeOptionHideValue, "year=${var.__y_}")));
1123
1124
AddCXXSummary(cpp_category_sp,
1125
lldb_private::formatters::LibcxxChronoWeekdaySummaryProvider,
1126
"libc++ std::chrono::weekday summary provider",
1127
"^std::__[[:alnum:]]+::chrono::weekday$",
1128
eTypeOptionHideChildren | eTypeOptionHideValue, true);
1129
1130
cpp_category_sp->AddTypeSummary(
1131
"^std::__[[:alnum:]]+::chrono::weekday_indexed$", eFormatterMatchRegex,
1132
TypeSummaryImplSP(new StringSummaryFormat(
1133
eTypeOptionHideChildren | eTypeOptionHideValue,
1134
"${var.__wd_} index=${var.__idx_%u}")));
1135
1136
cpp_category_sp->AddTypeSummary(
1137
"^std::__[[:alnum:]]+::chrono::weekday_last$", eFormatterMatchRegex,
1138
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1139
eTypeOptionHideValue,
1140
"${var.__wd_} index=last")));
1141
cpp_category_sp->AddTypeSummary(
1142
"^std::__[[:alnum:]]+::chrono::month_day$", eFormatterMatchRegex,
1143
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1144
eTypeOptionHideValue,
1145
"${var.__m_} ${var.__d_}")));
1146
cpp_category_sp->AddTypeSummary(
1147
"^std::__[[:alnum:]]+::chrono::month_day_last$", eFormatterMatchRegex,
1148
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1149
eTypeOptionHideValue,
1150
"${var.__m_} day=last")));
1151
1152
cpp_category_sp->AddTypeSummary(
1153
"^std::__[[:alnum:]]+::chrono::month_weekday$", eFormatterMatchRegex,
1154
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1155
eTypeOptionHideValue,
1156
"${var.__m_} ${var.__wdi_}")));
1157
1158
cpp_category_sp->AddTypeSummary(
1159
"^std::__[[:alnum:]]+::chrono::month_weekday_last$", eFormatterMatchRegex,
1160
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1161
eTypeOptionHideValue,
1162
"${var.__m_} ${var.__wdl_}")));
1163
1164
cpp_category_sp->AddTypeSummary(
1165
"^std::__[[:alnum:]]+::chrono::year_month$", eFormatterMatchRegex,
1166
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1167
eTypeOptionHideValue,
1168
"${var.__y_} ${var.__m_}")));
1169
1170
AddCXXSummary(
1171
cpp_category_sp,
1172
lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider,
1173
"libc++ std::chrono::year_month_day summary provider",
1174
"^std::__[[:alnum:]]+::chrono::year_month_day$",
1175
eTypeOptionHideChildren | eTypeOptionHideValue, true);
1176
1177
cpp_category_sp->AddTypeSummary(
1178
"^std::__[[:alnum:]]+::chrono::year_month_day_last$",
1179
eFormatterMatchRegex,
1180
TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
1181
eTypeOptionHideValue,
1182
"${var.__y_} ${var.__mdl_}")));
1183
1184
cpp_category_sp->AddTypeSummary(
1185
"^std::__[[:alnum:]]+::chrono::year_month_weekday$", eFormatterMatchRegex,
1186
TypeSummaryImplSP(new StringSummaryFormat(
1187
eTypeOptionHideChildren | eTypeOptionHideValue,
1188
"${var.__y_} ${var.__m_} ${var.__wdi_}")));
1189
1190
cpp_category_sp->AddTypeSummary(
1191
"^std::__[[:alnum:]]+::chrono::year_month_weekday_last$",
1192
eFormatterMatchRegex,
1193
TypeSummaryImplSP(new StringSummaryFormat(
1194
eTypeOptionHideChildren | eTypeOptionHideValue,
1195
"${var.__y_} ${var.__m_} ${var.__wdl_}")));
1196
}
1197
1198
static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
1199
if (!cpp_category_sp)
1200
return;
1201
1202
TypeSummaryImpl::Flags stl_summary_flags;
1203
stl_summary_flags.SetCascades(true)
1204
.SetSkipPointers(false)
1205
.SetSkipReferences(false)
1206
.SetDontShowChildren(true)
1207
.SetDontShowValue(true)
1208
.SetShowMembersOneLiner(false)
1209
.SetHideItemNames(false);
1210
1211
lldb::TypeSummaryImplSP std_string_summary_sp(
1212
new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}"));
1213
1214
lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(
1215
stl_summary_flags, LibStdcppStringSummaryProvider,
1216
"libstdc++ c++11 std::string summary provider"));
1217
lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(
1218
stl_summary_flags, LibStdcppWStringSummaryProvider,
1219
"libstdc++ c++11 std::wstring summary provider"));
1220
1221
cpp_category_sp->AddTypeSummary("std::string", eFormatterMatchExact,
1222
std_string_summary_sp);
1223
cpp_category_sp->AddTypeSummary("std::basic_string<char>",
1224
eFormatterMatchExact, std_string_summary_sp);
1225
cpp_category_sp->AddTypeSummary(
1226
"std::basic_string<char,std::char_traits<char>,std::allocator<char> >",
1227
eFormatterMatchExact, std_string_summary_sp);
1228
cpp_category_sp->AddTypeSummary(
1229
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >",
1230
eFormatterMatchExact, std_string_summary_sp);
1231
1232
cpp_category_sp->AddTypeSummary("std::__cxx11::string", eFormatterMatchExact,
1233
cxx11_string_summary_sp);
1234
cpp_category_sp->AddTypeSummary(
1235
"std::__cxx11::basic_string<char, std::char_traits<char>, "
1236
"std::allocator<char> >",
1237
eFormatterMatchExact, cxx11_string_summary_sp);
1238
cpp_category_sp->AddTypeSummary("std::__cxx11::basic_string<unsigned char, "
1239
"std::char_traits<unsigned char>, "
1240
"std::allocator<unsigned char> >",
1241
eFormatterMatchExact,
1242
cxx11_string_summary_sp);
1243
1244
// making sure we force-pick the summary for printing wstring (_M_p is a
1245
// wchar_t*)
1246
lldb::TypeSummaryImplSP std_wstring_summary_sp(
1247
new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}"));
1248
1249
cpp_category_sp->AddTypeSummary("std::wstring", eFormatterMatchExact,
1250
std_wstring_summary_sp);
1251
cpp_category_sp->AddTypeSummary("std::basic_string<wchar_t>",
1252
eFormatterMatchExact, std_wstring_summary_sp);
1253
cpp_category_sp->AddTypeSummary("std::basic_string<wchar_t,std::char_traits<"
1254
"wchar_t>,std::allocator<wchar_t> >",
1255
eFormatterMatchExact, std_wstring_summary_sp);
1256
cpp_category_sp->AddTypeSummary(
1257
"std::basic_string<wchar_t, std::char_traits<wchar_t>, "
1258
"std::allocator<wchar_t> >",
1259
eFormatterMatchExact, std_wstring_summary_sp);
1260
1261
cpp_category_sp->AddTypeSummary("std::__cxx11::wstring", eFormatterMatchExact,
1262
cxx11_wstring_summary_sp);
1263
cpp_category_sp->AddTypeSummary(
1264
"std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, "
1265
"std::allocator<wchar_t> >",
1266
eFormatterMatchExact, cxx11_wstring_summary_sp);
1267
1268
SyntheticChildren::Flags stl_synth_flags;
1269
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
1270
false);
1271
SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
1272
stl_deref_flags.SetFrontEndWantsDereference();
1273
1274
cpp_category_sp->AddTypeSynthetic(
1275
"^std::vector<.+>(( )?&)?$", eFormatterMatchRegex,
1276
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1277
stl_synth_flags,
1278
"lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
1279
cpp_category_sp->AddTypeSynthetic(
1280
"^std::map<.+> >(( )?&)?$", eFormatterMatchRegex,
1281
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1282
stl_synth_flags,
1283
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
1284
cpp_category_sp->AddTypeSynthetic(
1285
"^std::deque<.+>(( )?&)?$", eFormatterMatchRegex,
1286
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1287
stl_deref_flags,
1288
"lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider")));
1289
cpp_category_sp->AddTypeSynthetic(
1290
"^std::set<.+> >(( )?&)?$", eFormatterMatchRegex,
1291
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1292
stl_deref_flags,
1293
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
1294
cpp_category_sp->AddTypeSynthetic(
1295
"^std::multimap<.+> >(( )?&)?$", eFormatterMatchRegex,
1296
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1297
stl_deref_flags,
1298
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
1299
cpp_category_sp->AddTypeSynthetic(
1300
"^std::multiset<.+> >(( )?&)?$", eFormatterMatchRegex,
1301
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1302
stl_deref_flags,
1303
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
1304
cpp_category_sp->AddTypeSynthetic(
1305
"^std::unordered_(multi)?(map|set)<.+> >$", eFormatterMatchRegex,
1306
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1307
stl_deref_flags,
1308
"lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));
1309
cpp_category_sp->AddTypeSynthetic(
1310
"^std::(__cxx11::)?list<.+>(( )?&)?$", eFormatterMatchRegex,
1311
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1312
stl_deref_flags,
1313
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
1314
cpp_category_sp->AddTypeSynthetic(
1315
"^std::(__cxx11::)?forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
1316
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1317
stl_synth_flags,
1318
"lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));
1319
cpp_category_sp->AddTypeSynthetic(
1320
"^std::variant<.+>$", eFormatterMatchRegex,
1321
SyntheticChildrenSP(new ScriptedSyntheticChildren(
1322
stl_synth_flags,
1323
"lldb.formatters.cpp.gnu_libstdcpp.VariantSynthProvider")));
1324
1325
stl_summary_flags.SetDontShowChildren(false);
1326
stl_summary_flags.SetSkipPointers(false);
1327
cpp_category_sp->AddTypeSummary("^std::bitset<.+>(( )?&)?$",
1328
eFormatterMatchRegex,
1329
TypeSummaryImplSP(new StringSummaryFormat(
1330
stl_summary_flags, "size=${svar%#}")));
1331
cpp_category_sp->AddTypeSummary("^std::vector<.+>(( )?&)?$",
1332
eFormatterMatchRegex,
1333
TypeSummaryImplSP(new StringSummaryFormat(
1334
stl_summary_flags, "size=${svar%#}")));
1335
cpp_category_sp->AddTypeSummary("^std::map<.+> >(( )?&)?$",
1336
eFormatterMatchRegex,
1337
TypeSummaryImplSP(new StringSummaryFormat(
1338
stl_summary_flags, "size=${svar%#}")));
1339
cpp_category_sp->AddTypeSummary("^std::set<.+> >(( )?&)?$",
1340
eFormatterMatchRegex,
1341
TypeSummaryImplSP(new StringSummaryFormat(
1342
stl_summary_flags, "size=${svar%#}")));
1343
cpp_category_sp->AddTypeSummary("^std::deque<.+>(( )?&)?$",
1344
eFormatterMatchRegex,
1345
TypeSummaryImplSP(new StringSummaryFormat(
1346
stl_summary_flags, "size=${svar%#}")));
1347
cpp_category_sp->AddTypeSummary("^std::multimap<.+> >(( )?&)?$",
1348
eFormatterMatchRegex,
1349
TypeSummaryImplSP(new StringSummaryFormat(
1350
stl_summary_flags, "size=${svar%#}")));
1351
cpp_category_sp->AddTypeSummary("^std::multiset<.+> >(( )?&)?$",
1352
eFormatterMatchRegex,
1353
TypeSummaryImplSP(new StringSummaryFormat(
1354
stl_summary_flags, "size=${svar%#}")));
1355
cpp_category_sp->AddTypeSummary("^std::unordered_(multi)?(map|set)<.+> >$",
1356
eFormatterMatchRegex,
1357
TypeSummaryImplSP(new StringSummaryFormat(
1358
stl_summary_flags, "size=${svar%#}")));
1359
cpp_category_sp->AddTypeSummary("^std::(__cxx11::)?list<.+>(( )?&)?$",
1360
eFormatterMatchRegex,
1361
TypeSummaryImplSP(new StringSummaryFormat(
1362
stl_summary_flags, "size=${svar%#}")));
1363
cpp_category_sp->AddTypeSummary(
1364
"^std::(__cxx11::)?forward_list<.+>(( )?&)?$", eFormatterMatchRegex,
1365
TypeSummaryImplSP(new ScriptSummaryFormat(
1366
stl_summary_flags,
1367
"lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
1368
cpp_category_sp->AddTypeSummary(
1369
"^std::variant<.+>$", eFormatterMatchRegex,
1370
TypeSummaryImplSP(new ScriptSummaryFormat(
1371
stl_summary_flags,
1372
"lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider")));
1373
1374
AddCXXSynthetic(
1375
cpp_category_sp,
1376
lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator,
1377
"std::vector iterator synthetic children",
1378
"^__gnu_cxx::__normal_iterator<.+>$", stl_synth_flags, true);
1379
1380
AddCXXSynthetic(
1381
cpp_category_sp,
1382
lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator,
1383
"std::map iterator synthetic children", "^std::_Rb_tree_iterator<.+>$",
1384
stl_synth_flags, true);
1385
1386
AddCXXSynthetic(
1387
cpp_category_sp,
1388
lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator,
1389
"std::unique_ptr synthetic children", "^std::unique_ptr<.+>(( )?&)?$",
1390
stl_synth_flags, true);
1391
AddCXXSynthetic(
1392
cpp_category_sp,
1393
lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
1394
"std::shared_ptr synthetic children", "^std::shared_ptr<.+>(( )?&)?$",
1395
stl_synth_flags, true);
1396
AddCXXSynthetic(
1397
cpp_category_sp,
1398
lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
1399
"std::weak_ptr synthetic children", "^std::weak_ptr<.+>(( )?&)?$",
1400
stl_synth_flags, true);
1401
AddCXXSynthetic(
1402
cpp_category_sp,
1403
lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator,
1404
"std::tuple synthetic children", "^std::tuple<.+>(( )?&)?$",
1405
stl_synth_flags, true);
1406
1407
static constexpr const char *const libstdcpp_std_coroutine_handle_regex =
1408
"^std::coroutine_handle<.+>(( )?&)?$";
1409
AddCXXSynthetic(
1410
cpp_category_sp,
1411
lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator,
1412
"std::coroutine_handle synthetic children",
1413
libstdcpp_std_coroutine_handle_regex, stl_deref_flags, true);
1414
1415
AddCXXSynthetic(
1416
cpp_category_sp,
1417
lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator,
1418
"std::bitset synthetic child", "^std::bitset<.+>(( )?&)?$",
1419
stl_deref_flags, true);
1420
1421
AddCXXSynthetic(
1422
cpp_category_sp,
1423
lldb_private::formatters::LibStdcppOptionalSyntheticFrontEndCreator,
1424
"std::optional synthetic child", "^std::optional<.+>(( )?&)?$",
1425
stl_deref_flags, true);
1426
1427
AddCXXSummary(cpp_category_sp,
1428
lldb_private::formatters::LibStdcppUniquePointerSummaryProvider,
1429
"libstdc++ std::unique_ptr summary provider",
1430
"^std::unique_ptr<.+>(( )?&)?$", stl_summary_flags, true);
1431
AddCXXSummary(cpp_category_sp,
1432
lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
1433
"libstdc++ std::shared_ptr summary provider",
1434
"^std::shared_ptr<.+>(( )?&)?$", stl_summary_flags, true);
1435
AddCXXSummary(cpp_category_sp,
1436
lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
1437
"libstdc++ std::weak_ptr summary provider",
1438
"^std::weak_ptr<.+>(( )?&)?$", stl_summary_flags, true);
1439
AddCXXSummary(cpp_category_sp,
1440
lldb_private::formatters::StdlibCoroutineHandleSummaryProvider,
1441
"libstdc++ std::coroutine_handle summary provider",
1442
libstdcpp_std_coroutine_handle_regex, stl_summary_flags, true);
1443
AddCXXSummary(cpp_category_sp,
1444
lldb_private::formatters::GenericOptionalSummaryProvider,
1445
"libstd++ std::optional summary provider",
1446
"^std::optional<.+>(( )?&)?$", stl_summary_flags, true);
1447
}
1448
1449
static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
1450
if (!cpp_category_sp)
1451
return;
1452
1453
TypeSummaryImpl::Flags string_flags;
1454
string_flags.SetCascades(true)
1455
.SetSkipPointers(true)
1456
.SetSkipReferences(false)
1457
.SetDontShowChildren(true)
1458
.SetDontShowValue(false)
1459
.SetShowMembersOneLiner(false)
1460
.SetHideItemNames(false);
1461
1462
TypeSummaryImpl::Flags string_array_flags;
1463
string_array_flags.SetCascades(true)
1464
.SetSkipPointers(true)
1465
.SetSkipReferences(false)
1466
.SetDontShowChildren(true)
1467
.SetDontShowValue(true)
1468
.SetShowMembersOneLiner(false)
1469
.SetHideItemNames(false);
1470
1471
AddCXXSummary(cpp_category_sp,
1472
lldb_private::formatters::Char8StringSummaryProvider,
1473
"char8_t * summary provider", "char8_t *", string_flags);
1474
AddCXXSummary(cpp_category_sp,
1475
lldb_private::formatters::Char8StringSummaryProvider,
1476
"char8_t [] summary provider", "char8_t ?\\[[0-9]+\\]",
1477
string_array_flags, true);
1478
1479
AddCXXSummary(cpp_category_sp,
1480
lldb_private::formatters::Char16StringSummaryProvider,
1481
"char16_t * summary provider", "char16_t *", string_flags);
1482
AddCXXSummary(cpp_category_sp,
1483
lldb_private::formatters::Char16StringSummaryProvider,
1484
"char16_t [] summary provider", "char16_t ?\\[[0-9]+\\]",
1485
string_array_flags, true);
1486
1487
AddCXXSummary(cpp_category_sp,
1488
lldb_private::formatters::Char32StringSummaryProvider,
1489
"char32_t * summary provider", "char32_t *", string_flags);
1490
AddCXXSummary(cpp_category_sp,
1491
lldb_private::formatters::Char32StringSummaryProvider,
1492
"char32_t [] summary provider", "char32_t ?\\[[0-9]+\\]",
1493
string_array_flags, true);
1494
1495
AddCXXSummary(cpp_category_sp,
1496
lldb_private::formatters::WCharStringSummaryProvider,
1497
"wchar_t * summary provider", "wchar_t *", string_flags);
1498
AddCXXSummary(cpp_category_sp,
1499
lldb_private::formatters::WCharStringSummaryProvider,
1500
"wchar_t * summary provider", "wchar_t ?\\[[0-9]+\\]",
1501
string_array_flags, true);
1502
1503
AddCXXSummary(cpp_category_sp,
1504
lldb_private::formatters::Char16StringSummaryProvider,
1505
"unichar * summary provider", "unichar *", string_flags);
1506
1507
TypeSummaryImpl::Flags widechar_flags;
1508
widechar_flags.SetDontShowValue(true)
1509
.SetSkipPointers(true)
1510
.SetSkipReferences(false)
1511
.SetCascades(true)
1512
.SetDontShowChildren(true)
1513
.SetHideItemNames(true)
1514
.SetShowMembersOneLiner(false);
1515
1516
AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,
1517
"char8_t summary provider", "char8_t", widechar_flags);
1518
AddCXXSummary(cpp_category_sp,
1519
lldb_private::formatters::Char16SummaryProvider,
1520
"char16_t summary provider", "char16_t", widechar_flags);
1521
AddCXXSummary(cpp_category_sp,
1522
lldb_private::formatters::Char32SummaryProvider,
1523
"char32_t summary provider", "char32_t", widechar_flags);
1524
AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider,
1525
"wchar_t summary provider", "wchar_t", widechar_flags);
1526
1527
AddCXXSummary(cpp_category_sp,
1528
lldb_private::formatters::Char16SummaryProvider,
1529
"unichar summary provider", "unichar", widechar_flags);
1530
}
1531
1532
std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
1533
class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
1534
public:
1535
CompilerType AdjustForInclusion(CompilerType &candidate) override {
1536
LanguageType lang_type(candidate.GetMinimumLanguage());
1537
if (!Language::LanguageIsC(lang_type) &&
1538
!Language::LanguageIsCPlusPlus(lang_type))
1539
return CompilerType();
1540
if (candidate.IsTypedefType())
1541
return candidate.GetTypedefedType();
1542
return candidate;
1543
}
1544
};
1545
1546
return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());
1547
}
1548
1549
lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
1550
static llvm::once_flag g_initialize;
1551
static TypeCategoryImplSP g_category;
1552
1553
llvm::call_once(g_initialize, [this]() -> void {
1554
DataVisualization::Categories::GetCategory(ConstString(GetPluginName()),
1555
g_category);
1556
if (g_category) {
1557
LoadLibStdcppFormatters(g_category);
1558
LoadLibCxxFormatters(g_category);
1559
LoadSystemFormatters(g_category);
1560
}
1561
});
1562
return g_category;
1563
}
1564
1565
HardcodedFormatters::HardcodedSummaryFinder
1566
CPlusPlusLanguage::GetHardcodedSummaries() {
1567
static llvm::once_flag g_initialize;
1568
static ConstString g_vectortypes("VectorTypes");
1569
static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
1570
1571
llvm::call_once(g_initialize, []() -> void {
1572
g_formatters.push_back(
1573
[](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1574
FormatManager &) -> TypeSummaryImpl::SharedPointer {
1575
static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1576
new CXXFunctionSummaryFormat(
1577
TypeSummaryImpl::Flags(),
1578
lldb_private::formatters::CXXFunctionPointerSummaryProvider,
1579
"Function pointer summary provider"));
1580
if (CompilerType CT = valobj.GetCompilerType();
1581
CT.IsFunctionPointerType() || CT.IsMemberFunctionPointerType() ||
1582
valobj.GetValueType() == lldb::eValueTypeVTableEntry) {
1583
return formatter_sp;
1584
}
1585
return nullptr;
1586
});
1587
g_formatters.push_back(
1588
[](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1589
FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
1590
static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1591
new CXXFunctionSummaryFormat(
1592
TypeSummaryImpl::Flags()
1593
.SetCascades(true)
1594
.SetDontShowChildren(true)
1595
.SetHideItemNames(true)
1596
.SetShowMembersOneLiner(true)
1597
.SetSkipPointers(true)
1598
.SetSkipReferences(false),
1599
lldb_private::formatters::VectorTypeSummaryProvider,
1600
"vector_type pointer summary provider"));
1601
if (valobj.GetCompilerType().IsVectorType()) {
1602
if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
1603
return formatter_sp;
1604
}
1605
return nullptr;
1606
});
1607
g_formatters.push_back(
1608
[](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
1609
FormatManager &fmt_mgr) -> TypeSummaryImpl::SharedPointer {
1610
static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
1611
new CXXFunctionSummaryFormat(
1612
TypeSummaryImpl::Flags()
1613
.SetCascades(true)
1614
.SetDontShowChildren(true)
1615
.SetHideItemNames(true)
1616
.SetShowMembersOneLiner(true)
1617
.SetSkipPointers(true)
1618
.SetSkipReferences(false),
1619
lldb_private::formatters::BlockPointerSummaryProvider,
1620
"block pointer summary provider"));
1621
if (valobj.GetCompilerType().IsBlockPointerType()) {
1622
return formatter_sp;
1623
}
1624
return nullptr;
1625
});
1626
});
1627
1628
return g_formatters;
1629
}
1630
1631
HardcodedFormatters::HardcodedSyntheticFinder
1632
CPlusPlusLanguage::GetHardcodedSynthetics() {
1633
static llvm::once_flag g_initialize;
1634
static ConstString g_vectortypes("VectorTypes");
1635
static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
1636
1637
llvm::call_once(g_initialize, []() -> void {
1638
g_formatters.push_back([](lldb_private::ValueObject &valobj,
1639
lldb::DynamicValueType, FormatManager &fmt_mgr)
1640
-> SyntheticChildren::SharedPointer {
1641
static CXXSyntheticChildren::SharedPointer formatter_sp(
1642
new CXXSyntheticChildren(
1643
SyntheticChildren::Flags()
1644
.SetCascades(true)
1645
.SetSkipPointers(true)
1646
.SetSkipReferences(true)
1647
.SetNonCacheable(true),
1648
"vector_type synthetic children",
1649
lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
1650
if (valobj.GetCompilerType().IsVectorType()) {
1651
if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
1652
return formatter_sp;
1653
}
1654
return nullptr;
1655
});
1656
g_formatters.push_back([](lldb_private::ValueObject &valobj,
1657
lldb::DynamicValueType, FormatManager &fmt_mgr)
1658
-> SyntheticChildren::SharedPointer {
1659
static CXXSyntheticChildren::SharedPointer formatter_sp(
1660
new CXXSyntheticChildren(
1661
SyntheticChildren::Flags()
1662
.SetCascades(true)
1663
.SetSkipPointers(true)
1664
.SetSkipReferences(true)
1665
.SetNonCacheable(true),
1666
"block pointer synthetic children",
1667
lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
1668
if (valobj.GetCompilerType().IsBlockPointerType()) {
1669
return formatter_sp;
1670
}
1671
return nullptr;
1672
});
1673
});
1674
1675
return g_formatters;
1676
}
1677
1678
bool CPlusPlusLanguage::IsNilReference(ValueObject &valobj) {
1679
if (!Language::LanguageIsCPlusPlus(valobj.GetObjectRuntimeLanguage()) ||
1680
!valobj.IsPointerType())
1681
return false;
1682
bool canReadValue = true;
1683
bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
1684
return canReadValue && isZero;
1685
}
1686
1687
bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
1688
const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c",
1689
".h", ".hh", ".hpp", ".hxx", ".h++"};
1690
for (auto suffix : suffixes) {
1691
if (file_path.ends_with_insensitive(suffix))
1692
return true;
1693
}
1694
1695
// Check if we're in a STL path (where the files usually have no extension
1696
// that we could check for.
1697
return file_path.contains("/usr/include/c++/");
1698
}
1699
1700
bool CPlusPlusLanguage::GetFunctionDisplayName(
1701
const SymbolContext *sc, const ExecutionContext *exe_ctx,
1702
FunctionNameRepresentation representation, Stream &s) {
1703
switch (representation) {
1704
case FunctionNameRepresentation::eNameWithArgs: {
1705
// Print the function name with arguments in it
1706
if (sc->function) {
1707
ExecutionContextScope *exe_scope =
1708
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
1709
const char *cstr = sc->function->GetName().AsCString(nullptr);
1710
if (cstr) {
1711
const InlineFunctionInfo *inline_info = nullptr;
1712
VariableListSP variable_list_sp;
1713
bool get_function_vars = true;
1714
if (sc->block) {
1715
Block *inline_block = sc->block->GetContainingInlinedBlock();
1716
1717
if (inline_block) {
1718
get_function_vars = false;
1719
inline_info = inline_block->GetInlinedFunctionInfo();
1720
if (inline_info)
1721
variable_list_sp = inline_block->GetBlockVariableList(true);
1722
}
1723
}
1724
1725
if (get_function_vars) {
1726
variable_list_sp =
1727
sc->function->GetBlock(true).GetBlockVariableList(true);
1728
}
1729
1730
if (inline_info) {
1731
s.PutCString(cstr);
1732
s.PutCString(" [inlined] ");
1733
cstr = inline_info->GetName().GetCString();
1734
}
1735
1736
VariableList args;
1737
if (variable_list_sp)
1738
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
1739
args);
1740
if (args.GetSize() > 0) {
1741
if (!PrettyPrintFunctionNameWithArgs(s, cstr, exe_scope, args))
1742
return false;
1743
} else {
1744
s.PutCString(cstr);
1745
}
1746
return true;
1747
}
1748
} else if (sc->symbol) {
1749
const char *cstr = sc->symbol->GetName().AsCString(nullptr);
1750
if (cstr) {
1751
s.PutCString(cstr);
1752
return true;
1753
}
1754
}
1755
} break;
1756
default:
1757
return false;
1758
}
1759
1760
return false;
1761
}
1762
1763