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(name: GetPluginNameStatic(), description: "C++ Language" , |
58 | create_callback: CreateInstance); |
59 | } |
60 | |
61 | void CPlusPlusLanguage::Terminate() { |
62 | PluginManager::UnregisterPlugin(create_callback: CreateInstance); |
63 | } |
64 | |
65 | bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { |
66 | const char *mangled_name = mangled.GetMangledName().GetCString(); |
67 | return mangled_name && CPlusPlusLanguage::IsCPPMangledName(name: 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(Chars: left_right_chars, From: 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(Chars: left_right_chars, From: 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.size() > 0 && basename[0] == '~') |
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(cstr: return_type); |
192 | out_stream.PutChar(ch: ' '); |
193 | } |
194 | |
195 | out_stream.PutCString(cstr: cpp_method.GetScopeQualifiedName()); |
196 | out_stream.PutChar(ch: '('); |
197 | |
198 | FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope); |
199 | |
200 | out_stream.PutChar(ch: ')'); |
201 | |
202 | llvm::StringRef qualifiers = cpp_method.GetQualifiers(); |
203 | if (!qualifiers.empty()) { |
204 | out_stream.PutChar(ch: ' '); |
205 | out_stream.PutCString(cstr: 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(s: full, left_right_chars: parens, left_pos&: arg_start, right_pos&: arg_end)) { |
220 | m_arguments = full.substr(Start: arg_start, N: arg_end - arg_start + 1); |
221 | if (arg_end + 1 < full.size()) |
222 | m_qualifiers = full.substr(Start: 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(C: ':', From: basename_end); |
229 | if (context_end == llvm::StringRef::npos) |
230 | m_basename = full.substr(Start: 0, N: basename_end); |
231 | else { |
232 | if (context_start < context_end) |
233 | m_context = full.substr(Start: context_start, N: context_end - 1 - context_start); |
234 | const size_t basename_begin = context_end + 1; |
235 | m_basename = full.substr(Start: basename_begin, N: basename_end - basename_begin); |
236 | } |
237 | |
238 | if (IsTrivialBasename(basename: 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(s: basename, left_right_chars: parens, left_pos&: arg_start, right_pos&: arg_end)) |
324 | return basename.substr(Start: 0, N: 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(Other: path); |
336 | |
337 | llvm::StringRef identifier; |
338 | llvm::StringRef context; |
339 | std::string path_str = path.str(); |
340 | bool success = CPlusPlusLanguage::ExtractContextAndIdentifier( |
341 | name: path_str.c_str(), context, identifier); |
342 | if (!success) |
343 | return m_full.GetStringRef().contains(Other: 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(Suffix: 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(Size: sizeof(T), Alignment: alignof(T))) |
420 | T(std::forward<Args>(args)...); |
421 | } |
422 | |
423 | void *allocateNodeArray(size_t sz) { |
424 | return Alloc.Allocate(Size: sizeof(llvm::itanium_demangle::Node *) * sz, |
425 | Alignment: 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(mask: 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(Prefix: 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(From: Search, To: 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(From: "C1" , To: "C2" ); |
525 | trySubstitute(From: "D1" , To: "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(s1: mangled_name.GetCString(), s2: "_ZN" , n: 3) && |
544 | strncmp(s1: mangled_name.GetCString(), s2: "_ZNK" , n: 4)) { |
545 | std::string fixed_scratch("_ZNK" ); |
546 | fixed_scratch.append(s: mangled_name.GetCString() + 3); |
547 | alternates.push_back(x: ConstString(fixed_scratch)); |
548 | } |
549 | |
550 | // Maybe we're looking for a static symbol but we thought it was global... |
551 | if (!strncmp(s1: mangled_name.GetCString(), s2: "_Z" , n: 2) && |
552 | strncmp(s1: mangled_name.GetCString(), s2: "_ZL" , n: 3)) { |
553 | std::string fixed_scratch("_ZL" ); |
554 | fixed_scratch.append(s: mangled_name.GetCString() + 2); |
555 | alternates.push_back(x: 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: mangled_name.GetStringRef(), Vals: "a" , Vals: "c" )) |
565 | alternates.push_back(x: 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: mangled_name.GetStringRef(), Vals: "x" , Vals: "l" )) |
570 | alternates.push_back(x: 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: mangled_name.GetStringRef(), Vals: "y" , Vals: "m" )) |
576 | alternates.push_back(x: ulong_fixup); |
577 | |
578 | if (ConstString ctor_fixup = |
579 | CtorDtorSubstitutor().substitute(Mangled: mangled_name.GetStringRef())) |
580 | alternates.push_back(x: 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, mangled_names&: 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(x: alternate_mangled_name); |
621 | else |
622 | param_matches.push_back(x: 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 (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(category_sp: cpp_category_sp, |
649 | funct: lldb_private::formatters::LibcxxStringSummaryProviderASCII, |
650 | description: "std::string summary provider" , type_name: "^std::__[[:alnum:]]+::string$" , |
651 | flags: stl_summary_flags, regex: true); |
652 | AddCXXSummary(category_sp: cpp_category_sp, |
653 | funct: lldb_private::formatters::LibcxxStringSummaryProviderASCII, |
654 | description: "std::string summary provider" , |
655 | type_name: "^std::__[[:alnum:]]+::basic_string<char, " |
656 | "std::__[[:alnum:]]+::char_traits<char>, " |
657 | "std::__[[:alnum:]]+::allocator<char> >$" , |
658 | flags: stl_summary_flags, regex: true); |
659 | AddCXXSummary(category_sp: cpp_category_sp, |
660 | funct: lldb_private::formatters::LibcxxStringSummaryProviderASCII, |
661 | description: "std::string summary provider" , |
662 | type_name: "^std::__[[:alnum:]]+::basic_string<unsigned char, " |
663 | "std::__[[:alnum:]]+::char_traits<unsigned char>, " |
664 | "std::__[[:alnum:]]+::allocator<unsigned char> >$" , |
665 | flags: stl_summary_flags, regex: true); |
666 | |
667 | AddCXXSummary(category_sp: cpp_category_sp, |
668 | funct: lldb_private::formatters::LibcxxStringSummaryProviderUTF16, |
669 | description: "std::u16string summary provider" , |
670 | type_name: "^std::__[[:alnum:]]+::basic_string<char16_t, " |
671 | "std::__[[:alnum:]]+::char_traits<char16_t>, " |
672 | "std::__[[:alnum:]]+::allocator<char16_t> >$" , |
673 | flags: stl_summary_flags, regex: true); |
674 | |
675 | AddCXXSummary(category_sp: cpp_category_sp, |
676 | funct: lldb_private::formatters::LibcxxStringSummaryProviderUTF32, |
677 | description: "std::u32string summary provider" , |
678 | type_name: "^std::__[[:alnum:]]+::basic_string<char32_t, " |
679 | "std::__[[:alnum:]]+::char_traits<char32_t>, " |
680 | "std::__[[:alnum:]]+::allocator<char32_t> >$" , |
681 | flags: stl_summary_flags, regex: true); |
682 | |
683 | AddCXXSummary(category_sp: cpp_category_sp, |
684 | funct: lldb_private::formatters::LibcxxWStringSummaryProvider, |
685 | description: "std::wstring summary provider" , |
686 | type_name: "^std::__[[:alnum:]]+::wstring$" , flags: stl_summary_flags, regex: true); |
687 | AddCXXSummary(category_sp: cpp_category_sp, |
688 | funct: lldb_private::formatters::LibcxxWStringSummaryProvider, |
689 | description: "std::wstring summary provider" , |
690 | type_name: "^std::__[[:alnum:]]+::basic_string<wchar_t, " |
691 | "std::__[[:alnum:]]+::char_traits<wchar_t>, " |
692 | "std::__[[:alnum:]]+::allocator<wchar_t> >$" , |
693 | flags: stl_summary_flags, regex: true); |
694 | |
695 | AddCXXSummary(category_sp: cpp_category_sp, |
696 | funct: lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, |
697 | description: "std::string_view summary provider" , |
698 | type_name: "^std::__[[:alnum:]]+::string_view$" , flags: stl_summary_flags, regex: true); |
699 | AddCXXSummary(category_sp: cpp_category_sp, |
700 | funct: lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, |
701 | description: "std::string_view summary provider" , |
702 | type_name: "^std::__[[:alnum:]]+::basic_string_view<char, " |
703 | "std::__[[:alnum:]]+::char_traits<char> >$" , |
704 | flags: stl_summary_flags, regex: true); |
705 | AddCXXSummary(category_sp: cpp_category_sp, |
706 | funct: lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, |
707 | description: "std::string_view summary provider" , |
708 | type_name: "^std::__[[:alnum:]]+::basic_string_view<unsigned char, " |
709 | "std::__[[:alnum:]]+::char_traits<unsigned char> >$" , |
710 | flags: stl_summary_flags, regex: true); |
711 | |
712 | AddCXXSummary(category_sp: cpp_category_sp, |
713 | funct: lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16, |
714 | description: "std::u16string_view summary provider" , |
715 | type_name: "^std::__[[:alnum:]]+::basic_string_view<char16_t, " |
716 | "std::__[[:alnum:]]+::char_traits<char16_t> >$" , |
717 | flags: stl_summary_flags, regex: true); |
718 | |
719 | AddCXXSummary(category_sp: cpp_category_sp, |
720 | funct: lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32, |
721 | description: "std::u32string_view summary provider" , |
722 | type_name: "^std::__[[:alnum:]]+::basic_string_view<char32_t, " |
723 | "std::__[[:alnum:]]+::char_traits<char32_t> >$" , |
724 | flags: stl_summary_flags, regex: true); |
725 | |
726 | AddCXXSummary(category_sp: cpp_category_sp, |
727 | funct: lldb_private::formatters::LibcxxWStringViewSummaryProvider, |
728 | description: "std::wstring_view summary provider" , |
729 | type_name: "^std::__[[:alnum:]]+::wstring_view$" , flags: stl_summary_flags, regex: true); |
730 | AddCXXSummary(category_sp: cpp_category_sp, |
731 | funct: lldb_private::formatters::LibcxxWStringViewSummaryProvider, |
732 | description: "std::wstring_view summary provider" , |
733 | type_name: "^std::__[[:alnum:]]+::basic_string_view<wchar_t, " |
734 | "std::__[[:alnum:]]+::char_traits<wchar_t> >$" , |
735 | flags: stl_summary_flags, regex: 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 | category_sp: cpp_category_sp, |
745 | generator: lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator, |
746 | description: "libc++ std::bitset synthetic children" , |
747 | type_name: "^std::__[[:alnum:]]+::bitset<.+>$" , flags: stl_deref_flags, regex: true); |
748 | AddCXXSynthetic( |
749 | category_sp: cpp_category_sp, |
750 | generator: lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, |
751 | description: "libc++ std::vector synthetic children" , |
752 | type_name: "^std::__[[:alnum:]]+::vector<.+>$" , flags: stl_deref_flags, regex: true); |
753 | AddCXXSynthetic( |
754 | category_sp: cpp_category_sp, |
755 | generator: lldb_private::formatters::LibcxxStdValarraySyntheticFrontEndCreator, |
756 | description: "libc++ std::valarray synthetic children" , |
757 | type_name: "^std::__[[:alnum:]]+::valarray<.+>$" , flags: stl_deref_flags, regex: true); |
758 | AddCXXSynthetic( |
759 | category_sp: cpp_category_sp, |
760 | generator: lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator, |
761 | description: "libc++ std::slice_array synthetic children" , |
762 | type_name: "^std::__[[:alnum:]]+::slice_array<.+>$" , flags: stl_deref_flags, regex: true); |
763 | AddCXXSynthetic( |
764 | category_sp: cpp_category_sp, |
765 | generator: lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEndCreator, |
766 | description: "libc++ synthetic children for the valarray proxy arrays" , |
767 | type_name: "^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$" , |
768 | flags: stl_deref_flags, regex: true); |
769 | AddCXXSynthetic( |
770 | category_sp: cpp_category_sp, |
771 | generator: lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator, |
772 | description: "libc++ std::forward_list synthetic children" , |
773 | type_name: "^std::__[[:alnum:]]+::forward_list<.+>$" , flags: stl_synth_flags, regex: true); |
774 | AddCXXSynthetic( |
775 | category_sp: cpp_category_sp, |
776 | generator: lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, |
777 | description: "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 | type_name: "^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|" |
781 | "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>$" , |
782 | flags: stl_deref_flags, regex: true); |
783 | AddCXXSynthetic( |
784 | category_sp: cpp_category_sp, |
785 | generator: lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, |
786 | description: "libc++ std::map synthetic children" , type_name: "^std::__[[:alnum:]]+::map<.+> >$" , |
787 | flags: stl_synth_flags, regex: true); |
788 | AddCXXSynthetic( |
789 | category_sp: cpp_category_sp, |
790 | generator: lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, |
791 | description: "libc++ std::set synthetic children" , type_name: "^std::__[[:alnum:]]+::set<.+> >$" , |
792 | flags: stl_deref_flags, regex: true); |
793 | AddCXXSynthetic( |
794 | category_sp: cpp_category_sp, |
795 | generator: lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, |
796 | description: "libc++ std::multiset synthetic children" , |
797 | type_name: "^std::__[[:alnum:]]+::multiset<.+> >$" , flags: stl_deref_flags, regex: true); |
798 | AddCXXSynthetic( |
799 | category_sp: cpp_category_sp, |
800 | generator: lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, |
801 | description: "libc++ std::multimap synthetic children" , |
802 | type_name: "^std::__[[:alnum:]]+::multimap<.+> >$" , flags: stl_synth_flags, regex: true); |
803 | AddCXXSynthetic( |
804 | category_sp: cpp_category_sp, |
805 | generator: lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, |
806 | description: "libc++ std::unordered containers synthetic children" , |
807 | type_name: "^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$" , |
808 | flags: stl_synth_flags, regex: true); |
809 | AddCXXSynthetic( |
810 | category_sp: cpp_category_sp, |
811 | generator: lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator, |
812 | description: "libc++ std::initializer_list synthetic children" , |
813 | type_name: "^std::initializer_list<.+>$" , flags: stl_synth_flags, regex: true); |
814 | AddCXXSynthetic(category_sp: cpp_category_sp, generator: LibcxxQueueFrontEndCreator, |
815 | description: "libc++ std::queue synthetic children" , |
816 | type_name: "^std::__[[:alnum:]]+::queue<.+>$" , flags: stl_synth_flags, regex: true); |
817 | AddCXXSynthetic(category_sp: cpp_category_sp, generator: LibcxxTupleFrontEndCreator, |
818 | description: "libc++ std::tuple synthetic children" , |
819 | type_name: "^std::__[[:alnum:]]+::tuple<.*>$" , flags: stl_synth_flags, regex: true); |
820 | AddCXXSynthetic(category_sp: cpp_category_sp, generator: LibcxxOptionalSyntheticFrontEndCreator, |
821 | description: "libc++ std::optional synthetic children" , |
822 | type_name: "^std::__[[:alnum:]]+::optional<.+>$" , flags: stl_synth_flags, regex: true); |
823 | AddCXXSynthetic(category_sp: cpp_category_sp, generator: LibcxxVariantFrontEndCreator, |
824 | description: "libc++ std::variant synthetic children" , |
825 | type_name: "^std::__[[:alnum:]]+::variant<.+>$" , flags: stl_synth_flags, regex: true); |
826 | AddCXXSynthetic( |
827 | category_sp: cpp_category_sp, |
828 | generator: lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, |
829 | description: "libc++ std::atomic synthetic children" , |
830 | type_name: "^std::__[[:alnum:]]+::atomic<.+>$" , flags: stl_synth_flags, regex: true); |
831 | AddCXXSynthetic( |
832 | category_sp: cpp_category_sp, |
833 | generator: lldb_private::formatters::LibcxxStdSpanSyntheticFrontEndCreator, |
834 | description: "libc++ std::span synthetic children" , type_name: "^std::__[[:alnum:]]+::span<.+>$" , |
835 | flags: stl_deref_flags, regex: true); |
836 | AddCXXSynthetic( |
837 | category_sp: cpp_category_sp, |
838 | generator: lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEndCreator, |
839 | description: "libc++ std::ranges::ref_view synthetic children" , |
840 | type_name: "^std::__[[:alnum:]]+::ranges::ref_view<.+>$" , flags: stl_deref_flags, regex: true); |
841 | |
842 | cpp_category_sp->AddTypeSynthetic( |
843 | name: "^std::__[[:alnum:]]+::deque<.+>$" , match_type: eFormatterMatchRegex, |
844 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
845 | stl_synth_flags, |
846 | "lldb.formatters.cpp.libcxx.stddeque_SynthProvider" ))); |
847 | |
848 | AddCXXSynthetic( |
849 | category_sp: cpp_category_sp, |
850 | generator: lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, |
851 | description: "shared_ptr synthetic children" , type_name: "^std::__[[:alnum:]]+::shared_ptr<.+>$" , |
852 | flags: stl_synth_flags, regex: true); |
853 | |
854 | static constexpr const char *const libcxx_std_unique_ptr_regex = |
855 | "^std::__[[:alnum:]]+::unique_ptr<.+>$" ; |
856 | AddCXXSynthetic( |
857 | category_sp: cpp_category_sp, |
858 | generator: lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator, |
859 | description: "unique_ptr synthetic children" , type_name: libcxx_std_unique_ptr_regex, |
860 | flags: stl_synth_flags, regex: true); |
861 | |
862 | AddCXXSynthetic( |
863 | category_sp: cpp_category_sp, |
864 | generator: lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, |
865 | description: "weak_ptr synthetic children" , type_name: "^std::__[[:alnum:]]+::weak_ptr<.+>$" , |
866 | flags: stl_synth_flags, regex: true); |
867 | AddCXXSummary(category_sp: cpp_category_sp, |
868 | funct: lldb_private::formatters::LibcxxFunctionSummaryProvider, |
869 | description: "libc++ std::function summary provider" , |
870 | type_name: "^std::__[[:alnum:]]+::function<.+>$" , flags: stl_summary_flags, regex: true); |
871 | |
872 | static constexpr const char *const libcxx_std_coroutine_handle_regex = |
873 | "^std::__[[:alnum:]]+::coroutine_handle<.+>$" ; |
874 | AddCXXSynthetic( |
875 | category_sp: cpp_category_sp, |
876 | generator: lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator, |
877 | description: "coroutine_handle synthetic children" , type_name: libcxx_std_coroutine_handle_regex, |
878 | flags: stl_deref_flags, regex: true); |
879 | |
880 | stl_summary_flags.SetDontShowChildren(false); |
881 | stl_summary_flags.SetSkipPointers(false); |
882 | AddCXXSummary(category_sp: cpp_category_sp, |
883 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
884 | description: "libc++ std::bitset summary provider" , |
885 | type_name: "^std::__[[:alnum:]]+::bitset<.+>$" , flags: stl_summary_flags, regex: true); |
886 | AddCXXSummary(category_sp: cpp_category_sp, |
887 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
888 | description: "libc++ std::vector summary provider" , |
889 | type_name: "^std::__[[:alnum:]]+::vector<.+>$" , flags: stl_summary_flags, regex: true); |
890 | AddCXXSummary(category_sp: cpp_category_sp, |
891 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
892 | description: "libc++ std::valarray summary provider" , |
893 | type_name: "^std::__[[:alnum:]]+::valarray<.+>$" , flags: stl_summary_flags, regex: true); |
894 | AddCXXSummary(category_sp: cpp_category_sp, |
895 | funct: lldb_private::formatters::LibcxxStdSliceArraySummaryProvider, |
896 | description: "libc++ std::slice_array summary provider" , |
897 | type_name: "^std::__[[:alnum:]]+::slice_array<.+>$" , flags: stl_summary_flags, |
898 | regex: true); |
899 | AddCXXSummary(category_sp: cpp_category_sp, |
900 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
901 | description: "libc++ summary provider for the valarray proxy arrays" , |
902 | type_name: "^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$" , |
903 | flags: stl_summary_flags, regex: true); |
904 | AddCXXSummary( |
905 | category_sp: cpp_category_sp, funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
906 | description: "libc++ std::list summary provider" , |
907 | type_name: "^std::__[[:alnum:]]+::forward_list<.+>$" , flags: stl_summary_flags, regex: true); |
908 | AddCXXSummary( |
909 | category_sp: cpp_category_sp, funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
910 | description: "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 | type_name: "^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|" |
914 | "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>$" , |
915 | flags: stl_summary_flags, regex: true); |
916 | AddCXXSummary(category_sp: cpp_category_sp, |
917 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
918 | description: "libc++ std::map summary provider" , |
919 | type_name: "^std::__[[:alnum:]]+::map<.+>$" , flags: stl_summary_flags, regex: true); |
920 | AddCXXSummary(category_sp: cpp_category_sp, |
921 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
922 | description: "libc++ std::deque summary provider" , |
923 | type_name: "^std::__[[:alnum:]]+::deque<.+>$" , flags: stl_summary_flags, regex: true); |
924 | AddCXXSummary(category_sp: cpp_category_sp, |
925 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
926 | description: "libc++ std::queue summary provider" , |
927 | type_name: "^std::__[[:alnum:]]+::queue<.+>$" , flags: stl_summary_flags, regex: true); |
928 | AddCXXSummary(category_sp: cpp_category_sp, |
929 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
930 | description: "libc++ std::set summary provider" , |
931 | type_name: "^std::__[[:alnum:]]+::set<.+>$" , flags: stl_summary_flags, regex: true); |
932 | AddCXXSummary(category_sp: cpp_category_sp, |
933 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
934 | description: "libc++ std::multiset summary provider" , |
935 | type_name: "^std::__[[:alnum:]]+::multiset<.+>$" , flags: stl_summary_flags, regex: true); |
936 | AddCXXSummary(category_sp: cpp_category_sp, |
937 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
938 | description: "libc++ std::multimap summary provider" , |
939 | type_name: "^std::__[[:alnum:]]+::multimap<.+>$" , flags: stl_summary_flags, regex: true); |
940 | AddCXXSummary(category_sp: cpp_category_sp, |
941 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
942 | description: "libc++ std::unordered containers summary provider" , |
943 | type_name: "^std::__[[:alnum:]]+::unordered_(multi)?(map|set)<.+> >$" , |
944 | flags: stl_summary_flags, regex: true); |
945 | AddCXXSummary(category_sp: cpp_category_sp, funct: LibcxxContainerSummaryProvider, |
946 | description: "libc++ std::tuple summary provider" , |
947 | type_name: "^std::__[[:alnum:]]+::tuple<.*>$" , flags: stl_summary_flags, regex: true); |
948 | AddCXXSummary(category_sp: cpp_category_sp, |
949 | funct: lldb_private::formatters::LibCxxAtomicSummaryProvider, |
950 | description: "libc++ std::atomic summary provider" , |
951 | type_name: "^std::__[[:alnum:]]+::atomic<.+>$" , flags: stl_summary_flags, regex: true); |
952 | AddCXXSummary(category_sp: cpp_category_sp, |
953 | funct: lldb_private::formatters::GenericOptionalSummaryProvider, |
954 | description: "libc++ std::optional summary provider" , |
955 | type_name: "^std::__[[:alnum:]]+::optional<.+>$" , flags: stl_summary_flags, regex: true); |
956 | AddCXXSummary(category_sp: cpp_category_sp, |
957 | funct: lldb_private::formatters::LibcxxVariantSummaryProvider, |
958 | description: "libc++ std::variant summary provider" , |
959 | type_name: "^std::__[[:alnum:]]+::variant<.+>$" , flags: stl_summary_flags, regex: true); |
960 | AddCXXSummary(category_sp: cpp_category_sp, |
961 | funct: lldb_private::formatters::LibcxxContainerSummaryProvider, |
962 | description: "libc++ std::span summary provider" , |
963 | type_name: "^std::__[[:alnum:]]+::span<.+>$" , flags: stl_summary_flags, regex: true); |
964 | |
965 | stl_summary_flags.SetSkipPointers(true); |
966 | |
967 | AddCXXSummary(category_sp: cpp_category_sp, |
968 | funct: lldb_private::formatters::LibcxxSmartPointerSummaryProvider, |
969 | description: "libc++ std::shared_ptr summary provider" , |
970 | type_name: "^std::__[[:alnum:]]+::shared_ptr<.+>$" , flags: stl_summary_flags, |
971 | regex: true); |
972 | AddCXXSummary(category_sp: cpp_category_sp, |
973 | funct: lldb_private::formatters::LibcxxSmartPointerSummaryProvider, |
974 | description: "libc++ std::weak_ptr summary provider" , |
975 | type_name: "^std::__[[:alnum:]]+::weak_ptr<.+>$" , flags: stl_summary_flags, regex: true); |
976 | AddCXXSummary(category_sp: cpp_category_sp, |
977 | funct: lldb_private::formatters::LibcxxUniquePointerSummaryProvider, |
978 | description: "libc++ std::unique_ptr summary provider" , |
979 | type_name: libcxx_std_unique_ptr_regex, flags: stl_summary_flags, regex: true); |
980 | |
981 | AddCXXSummary(category_sp: cpp_category_sp, |
982 | funct: lldb_private::formatters::StdlibCoroutineHandleSummaryProvider, |
983 | description: "libc++ std::coroutine_handle summary provider" , |
984 | type_name: libcxx_std_coroutine_handle_regex, flags: stl_summary_flags, regex: true); |
985 | |
986 | AddCXXSynthetic( |
987 | category_sp: cpp_category_sp, |
988 | generator: lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, |
989 | description: "std::vector iterator synthetic children" , |
990 | type_name: "^std::__[[:alnum:]]+::__wrap_iter<.+>$" , flags: stl_synth_flags, regex: true); |
991 | |
992 | AddCXXSynthetic( |
993 | category_sp: cpp_category_sp, |
994 | generator: lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, |
995 | description: "std::map iterator synthetic children" , |
996 | type_name: "^std::__[[:alnum:]]+::__map_(const_)?iterator<.+>$" , flags: stl_synth_flags, |
997 | regex: true); |
998 | |
999 | AddCXXSynthetic(category_sp: cpp_category_sp, |
1000 | generator: lldb_private::formatters:: |
1001 | LibCxxUnorderedMapIteratorSyntheticFrontEndCreator, |
1002 | description: "std::unordered_map iterator synthetic children" , |
1003 | type_name: "^std::__[[:alnum:]]+::__hash_map_(const_)?iterator<.+>$" , |
1004 | flags: stl_synth_flags, regex: true); |
1005 | // Chrono duration typedefs |
1006 | cpp_category_sp->AddTypeSummary( |
1007 | name: "^std::__[[:alnum:]]+::chrono::nanoseconds" , match_type: eFormatterMatchRegex, |
1008 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1009 | eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ns" ))); |
1010 | cpp_category_sp->AddTypeSummary( |
1011 | name: "^std::__[[:alnum:]]+::chrono::microseconds" , match_type: eFormatterMatchRegex, |
1012 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1013 | eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} µs" ))); |
1014 | cpp_category_sp->AddTypeSummary( |
1015 | name: "^std::__[[:alnum:]]+::chrono::milliseconds" , match_type: eFormatterMatchRegex, |
1016 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1017 | eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} ms" ))); |
1018 | cpp_category_sp->AddTypeSummary( |
1019 | name: "^std::__[[:alnum:]]+::chrono::seconds" , match_type: eFormatterMatchRegex, |
1020 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1021 | eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s" ))); |
1022 | cpp_category_sp->AddTypeSummary( |
1023 | name: "^std::__[[:alnum:]]+::chrono::minutes" , match_type: eFormatterMatchRegex, |
1024 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1025 | eTypeOptionHideValue, |
1026 | "${var.__rep_} min" ))); |
1027 | cpp_category_sp->AddTypeSummary( |
1028 | name: "^std::__[[:alnum:]]+::chrono::hours" , match_type: eFormatterMatchRegex, |
1029 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1030 | eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} h" ))); |
1031 | |
1032 | cpp_category_sp->AddTypeSummary( |
1033 | name: "^std::__[[:alnum:]]+::chrono::days" , match_type: eFormatterMatchRegex, |
1034 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1035 | eTypeOptionHideValue, |
1036 | "${var.__rep_} days" ))); |
1037 | cpp_category_sp->AddTypeSummary( |
1038 | name: "^std::__[[:alnum:]]+::chrono::weeks" , match_type: eFormatterMatchRegex, |
1039 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1040 | eTypeOptionHideValue, |
1041 | "${var.__rep_} weeks" ))); |
1042 | cpp_category_sp->AddTypeSummary( |
1043 | name: "^std::__[[:alnum:]]+::chrono::months" , match_type: eFormatterMatchRegex, |
1044 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1045 | eTypeOptionHideValue, |
1046 | "${var.__rep_} months" ))); |
1047 | cpp_category_sp->AddTypeSummary( |
1048 | name: "^std::__[[:alnum:]]+::chrono::years" , match_type: eFormatterMatchRegex, |
1049 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1050 | eTypeOptionHideValue, |
1051 | "${var.__rep_} years" ))); |
1052 | cpp_category_sp->AddTypeSummary( |
1053 | name: "^std::__[[:alnum:]]+::chrono::seconds" , match_type: eFormatterMatchRegex, |
1054 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1055 | eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s" ))); |
1056 | |
1057 | // Chrono time point types |
1058 | |
1059 | AddCXXSummary(category_sp: cpp_category_sp, |
1060 | funct: lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider, |
1061 | description: "libc++ std::chrono::sys_seconds summary provider" , |
1062 | type_name: "^std::__[[:alnum:]]+::chrono::time_point<" |
1063 | "std::__[[:alnum:]]+::chrono::system_clock, " |
1064 | "std::__[[:alnum:]]+::chrono::duration<.*, " |
1065 | "std::__[[:alnum:]]+::ratio<1, 1> " |
1066 | "> >$" , |
1067 | flags: eTypeOptionHideChildren | eTypeOptionHideValue | |
1068 | eTypeOptionCascade, |
1069 | regex: true); |
1070 | AddCXXSummary(category_sp: cpp_category_sp, |
1071 | funct: lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider, |
1072 | description: "libc++ std::chrono::sys_seconds summary provider" , |
1073 | type_name: "^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 | flags: eTypeOptionHideChildren | eTypeOptionHideValue | |
1079 | eTypeOptionCascade, |
1080 | regex: true); |
1081 | |
1082 | AddCXXSummary( |
1083 | category_sp: cpp_category_sp, |
1084 | funct: lldb_private::formatters::LibcxxChronoLocalSecondsSummaryProvider, |
1085 | description: "libc++ std::chrono::local_seconds summary provider" , |
1086 | type_name: "^std::__[[:alnum:]]+::chrono::time_point<" |
1087 | "std::__[[:alnum:]]+::chrono::local_t, " |
1088 | "std::__[[:alnum:]]+::chrono::duration<.*, " |
1089 | "std::__[[:alnum:]]+::ratio<1, 1> " |
1090 | "> >$" , |
1091 | flags: eTypeOptionHideChildren | eTypeOptionHideValue | eTypeOptionCascade, |
1092 | regex: true); |
1093 | AddCXXSummary(category_sp: cpp_category_sp, |
1094 | funct: lldb_private::formatters::LibcxxChronoLocalDaysSummaryProvider, |
1095 | description: "libc++ std::chrono::local_seconds summary provider" , |
1096 | type_name: "^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 | flags: eTypeOptionHideChildren | eTypeOptionHideValue | |
1102 | eTypeOptionCascade, |
1103 | regex: true); |
1104 | |
1105 | // Chrono calendar types |
1106 | |
1107 | cpp_category_sp->AddTypeSummary( |
1108 | name: "^std::__[[:alnum:]]+::chrono::day$" , match_type: eFormatterMatchRegex, |
1109 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1110 | eTypeOptionHideValue, |
1111 | "day=${var.__d_%u}" ))); |
1112 | |
1113 | AddCXXSummary(category_sp: cpp_category_sp, |
1114 | funct: lldb_private::formatters::LibcxxChronoMonthSummaryProvider, |
1115 | description: "libc++ std::chrono::month summary provider" , |
1116 | type_name: "^std::__[[:alnum:]]+::chrono::month$" , |
1117 | flags: eTypeOptionHideChildren | eTypeOptionHideValue, regex: true); |
1118 | |
1119 | cpp_category_sp->AddTypeSummary( |
1120 | name: "^std::__[[:alnum:]]+::chrono::year$" , match_type: eFormatterMatchRegex, |
1121 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1122 | eTypeOptionHideChildren | eTypeOptionHideValue, "year=${var.__y_}" ))); |
1123 | |
1124 | AddCXXSummary(category_sp: cpp_category_sp, |
1125 | funct: lldb_private::formatters::LibcxxChronoWeekdaySummaryProvider, |
1126 | description: "libc++ std::chrono::weekday summary provider" , |
1127 | type_name: "^std::__[[:alnum:]]+::chrono::weekday$" , |
1128 | flags: eTypeOptionHideChildren | eTypeOptionHideValue, regex: true); |
1129 | |
1130 | cpp_category_sp->AddTypeSummary( |
1131 | name: "^std::__[[:alnum:]]+::chrono::weekday_indexed$" , match_type: eFormatterMatchRegex, |
1132 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1133 | eTypeOptionHideChildren | eTypeOptionHideValue, |
1134 | "${var.__wd_} index=${var.__idx_%u}" ))); |
1135 | |
1136 | cpp_category_sp->AddTypeSummary( |
1137 | name: "^std::__[[:alnum:]]+::chrono::weekday_last$" , match_type: eFormatterMatchRegex, |
1138 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1139 | eTypeOptionHideValue, |
1140 | "${var.__wd_} index=last" ))); |
1141 | cpp_category_sp->AddTypeSummary( |
1142 | name: "^std::__[[:alnum:]]+::chrono::month_day$" , match_type: eFormatterMatchRegex, |
1143 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1144 | eTypeOptionHideValue, |
1145 | "${var.__m_} ${var.__d_}" ))); |
1146 | cpp_category_sp->AddTypeSummary( |
1147 | name: "^std::__[[:alnum:]]+::chrono::month_day_last$" , match_type: eFormatterMatchRegex, |
1148 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1149 | eTypeOptionHideValue, |
1150 | "${var.__m_} day=last" ))); |
1151 | |
1152 | cpp_category_sp->AddTypeSummary( |
1153 | name: "^std::__[[:alnum:]]+::chrono::month_weekday$" , match_type: eFormatterMatchRegex, |
1154 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1155 | eTypeOptionHideValue, |
1156 | "${var.__m_} ${var.__wdi_}" ))); |
1157 | |
1158 | cpp_category_sp->AddTypeSummary( |
1159 | name: "^std::__[[:alnum:]]+::chrono::month_weekday_last$" , match_type: eFormatterMatchRegex, |
1160 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1161 | eTypeOptionHideValue, |
1162 | "${var.__m_} ${var.__wdl_}" ))); |
1163 | |
1164 | cpp_category_sp->AddTypeSummary( |
1165 | name: "^std::__[[:alnum:]]+::chrono::year_month$" , match_type: eFormatterMatchRegex, |
1166 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1167 | eTypeOptionHideValue, |
1168 | "${var.__y_} ${var.__m_}" ))); |
1169 | |
1170 | AddCXXSummary( |
1171 | category_sp: cpp_category_sp, |
1172 | funct: lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider, |
1173 | description: "libc++ std::chrono::year_month_day summary provider" , |
1174 | type_name: "^std::__[[:alnum:]]+::chrono::year_month_day$" , |
1175 | flags: eTypeOptionHideChildren | eTypeOptionHideValue, regex: true); |
1176 | |
1177 | cpp_category_sp->AddTypeSummary( |
1178 | name: "^std::__[[:alnum:]]+::chrono::year_month_day_last$" , |
1179 | match_type: eFormatterMatchRegex, |
1180 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren | |
1181 | eTypeOptionHideValue, |
1182 | "${var.__y_} ${var.__mdl_}" ))); |
1183 | |
1184 | cpp_category_sp->AddTypeSummary( |
1185 | name: "^std::__[[:alnum:]]+::chrono::year_month_weekday$" , match_type: eFormatterMatchRegex, |
1186 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1187 | eTypeOptionHideChildren | eTypeOptionHideValue, |
1188 | "${var.__y_} ${var.__m_} ${var.__wdi_}" ))); |
1189 | |
1190 | cpp_category_sp->AddTypeSummary( |
1191 | name: "^std::__[[:alnum:]]+::chrono::year_month_weekday_last$" , |
1192 | match_type: eFormatterMatchRegex, |
1193 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1194 | eTypeOptionHideChildren | eTypeOptionHideValue, |
1195 | "${var.__y_} ${var.__m_} ${var.__wdl_}" ))); |
1196 | } |
1197 | |
1198 | static void (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(name: "std::string" , match_type: eFormatterMatchExact, |
1222 | summary_sp: std_string_summary_sp); |
1223 | cpp_category_sp->AddTypeSummary(name: "std::basic_string<char>" , |
1224 | match_type: eFormatterMatchExact, summary_sp: std_string_summary_sp); |
1225 | cpp_category_sp->AddTypeSummary( |
1226 | name: "std::basic_string<char,std::char_traits<char>,std::allocator<char> >" , |
1227 | match_type: eFormatterMatchExact, summary_sp: std_string_summary_sp); |
1228 | cpp_category_sp->AddTypeSummary( |
1229 | name: "std::basic_string<char, std::char_traits<char>, std::allocator<char> >" , |
1230 | match_type: eFormatterMatchExact, summary_sp: std_string_summary_sp); |
1231 | |
1232 | cpp_category_sp->AddTypeSummary(name: "std::__cxx11::string" , match_type: eFormatterMatchExact, |
1233 | summary_sp: cxx11_string_summary_sp); |
1234 | cpp_category_sp->AddTypeSummary( |
1235 | name: "std::__cxx11::basic_string<char, std::char_traits<char>, " |
1236 | "std::allocator<char> >" , |
1237 | match_type: eFormatterMatchExact, summary_sp: cxx11_string_summary_sp); |
1238 | cpp_category_sp->AddTypeSummary(name: "std::__cxx11::basic_string<unsigned char, " |
1239 | "std::char_traits<unsigned char>, " |
1240 | "std::allocator<unsigned char> >" , |
1241 | match_type: eFormatterMatchExact, |
1242 | summary_sp: 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(name: "std::wstring" , match_type: eFormatterMatchExact, |
1250 | summary_sp: std_wstring_summary_sp); |
1251 | cpp_category_sp->AddTypeSummary(name: "std::basic_string<wchar_t>" , |
1252 | match_type: eFormatterMatchExact, summary_sp: std_wstring_summary_sp); |
1253 | cpp_category_sp->AddTypeSummary(name: "std::basic_string<wchar_t,std::char_traits<" |
1254 | "wchar_t>,std::allocator<wchar_t> >" , |
1255 | match_type: eFormatterMatchExact, summary_sp: std_wstring_summary_sp); |
1256 | cpp_category_sp->AddTypeSummary( |
1257 | name: "std::basic_string<wchar_t, std::char_traits<wchar_t>, " |
1258 | "std::allocator<wchar_t> >" , |
1259 | match_type: eFormatterMatchExact, summary_sp: std_wstring_summary_sp); |
1260 | |
1261 | cpp_category_sp->AddTypeSummary(name: "std::__cxx11::wstring" , match_type: eFormatterMatchExact, |
1262 | summary_sp: cxx11_wstring_summary_sp); |
1263 | cpp_category_sp->AddTypeSummary( |
1264 | name: "std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, " |
1265 | "std::allocator<wchar_t> >" , |
1266 | match_type: eFormatterMatchExact, summary_sp: 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 | name: "^std::vector<.+>(( )?&)?$" , match_type: eFormatterMatchRegex, |
1276 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1277 | stl_synth_flags, |
1278 | "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider" ))); |
1279 | cpp_category_sp->AddTypeSynthetic( |
1280 | name: "^std::map<.+> >(( )?&)?$" , match_type: eFormatterMatchRegex, |
1281 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1282 | stl_synth_flags, |
1283 | "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider" ))); |
1284 | cpp_category_sp->AddTypeSynthetic( |
1285 | name: "^std::deque<.+>(( )?&)?$" , match_type: eFormatterMatchRegex, |
1286 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1287 | stl_deref_flags, |
1288 | "lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider" ))); |
1289 | cpp_category_sp->AddTypeSynthetic( |
1290 | name: "^std::set<.+> >(( )?&)?$" , match_type: eFormatterMatchRegex, |
1291 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1292 | stl_deref_flags, |
1293 | "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider" ))); |
1294 | cpp_category_sp->AddTypeSynthetic( |
1295 | name: "^std::multimap<.+> >(( )?&)?$" , match_type: eFormatterMatchRegex, |
1296 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1297 | stl_deref_flags, |
1298 | "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider" ))); |
1299 | cpp_category_sp->AddTypeSynthetic( |
1300 | name: "^std::multiset<.+> >(( )?&)?$" , match_type: eFormatterMatchRegex, |
1301 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1302 | stl_deref_flags, |
1303 | "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider" ))); |
1304 | cpp_category_sp->AddTypeSynthetic( |
1305 | name: "^std::unordered_(multi)?(map|set)<.+> >$" , match_type: eFormatterMatchRegex, |
1306 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1307 | stl_deref_flags, |
1308 | "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider" ))); |
1309 | cpp_category_sp->AddTypeSynthetic( |
1310 | name: "^std::(__cxx11::)?list<.+>(( )?&)?$" , match_type: eFormatterMatchRegex, |
1311 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1312 | stl_deref_flags, |
1313 | "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider" ))); |
1314 | cpp_category_sp->AddTypeSynthetic( |
1315 | name: "^std::(__cxx11::)?forward_list<.+>(( )?&)?$" , match_type: eFormatterMatchRegex, |
1316 | synth_sp: SyntheticChildrenSP(new ScriptedSyntheticChildren( |
1317 | stl_synth_flags, |
1318 | "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider" ))); |
1319 | cpp_category_sp->AddTypeSynthetic( |
1320 | name: "^std::variant<.+>$" , match_type: eFormatterMatchRegex, |
1321 | synth_sp: 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(name: "^std::bitset<.+>(( )?&)?$" , |
1328 | match_type: eFormatterMatchRegex, |
1329 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1330 | stl_summary_flags, "size=${svar%#}" ))); |
1331 | cpp_category_sp->AddTypeSummary(name: "^std::vector<.+>(( )?&)?$" , |
1332 | match_type: eFormatterMatchRegex, |
1333 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1334 | stl_summary_flags, "size=${svar%#}" ))); |
1335 | cpp_category_sp->AddTypeSummary(name: "^std::map<.+> >(( )?&)?$" , |
1336 | match_type: eFormatterMatchRegex, |
1337 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1338 | stl_summary_flags, "size=${svar%#}" ))); |
1339 | cpp_category_sp->AddTypeSummary(name: "^std::set<.+> >(( )?&)?$" , |
1340 | match_type: eFormatterMatchRegex, |
1341 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1342 | stl_summary_flags, "size=${svar%#}" ))); |
1343 | cpp_category_sp->AddTypeSummary(name: "^std::deque<.+>(( )?&)?$" , |
1344 | match_type: eFormatterMatchRegex, |
1345 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1346 | stl_summary_flags, "size=${svar%#}" ))); |
1347 | cpp_category_sp->AddTypeSummary(name: "^std::multimap<.+> >(( )?&)?$" , |
1348 | match_type: eFormatterMatchRegex, |
1349 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1350 | stl_summary_flags, "size=${svar%#}" ))); |
1351 | cpp_category_sp->AddTypeSummary(name: "^std::multiset<.+> >(( )?&)?$" , |
1352 | match_type: eFormatterMatchRegex, |
1353 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1354 | stl_summary_flags, "size=${svar%#}" ))); |
1355 | cpp_category_sp->AddTypeSummary(name: "^std::unordered_(multi)?(map|set)<.+> >$" , |
1356 | match_type: eFormatterMatchRegex, |
1357 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1358 | stl_summary_flags, "size=${svar%#}" ))); |
1359 | cpp_category_sp->AddTypeSummary(name: "^std::(__cxx11::)?list<.+>(( )?&)?$" , |
1360 | match_type: eFormatterMatchRegex, |
1361 | summary_sp: TypeSummaryImplSP(new StringSummaryFormat( |
1362 | stl_summary_flags, "size=${svar%#}" ))); |
1363 | cpp_category_sp->AddTypeSummary( |
1364 | name: "^std::(__cxx11::)?forward_list<.+>(( )?&)?$" , match_type: eFormatterMatchRegex, |
1365 | summary_sp: TypeSummaryImplSP(new ScriptSummaryFormat( |
1366 | stl_summary_flags, |
1367 | "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider" ))); |
1368 | cpp_category_sp->AddTypeSummary( |
1369 | name: "^std::variant<.+>$" , match_type: eFormatterMatchRegex, |
1370 | summary_sp: TypeSummaryImplSP(new ScriptSummaryFormat( |
1371 | stl_summary_flags, |
1372 | "lldb.formatters.cpp.gnu_libstdcpp.VariantSummaryProvider" ))); |
1373 | |
1374 | AddCXXSynthetic( |
1375 | category_sp: cpp_category_sp, |
1376 | generator: lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, |
1377 | description: "std::vector iterator synthetic children" , |
1378 | type_name: "^__gnu_cxx::__normal_iterator<.+>$" , flags: stl_synth_flags, regex: true); |
1379 | |
1380 | AddCXXSynthetic( |
1381 | category_sp: cpp_category_sp, |
1382 | generator: lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, |
1383 | description: "std::map iterator synthetic children" , type_name: "^std::_Rb_tree_iterator<.+>$" , |
1384 | flags: stl_synth_flags, regex: true); |
1385 | |
1386 | AddCXXSynthetic( |
1387 | category_sp: cpp_category_sp, |
1388 | generator: lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator, |
1389 | description: "std::unique_ptr synthetic children" , type_name: "^std::unique_ptr<.+>(( )?&)?$" , |
1390 | flags: stl_synth_flags, regex: true); |
1391 | AddCXXSynthetic( |
1392 | category_sp: cpp_category_sp, |
1393 | generator: lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, |
1394 | description: "std::shared_ptr synthetic children" , type_name: "^std::shared_ptr<.+>(( )?&)?$" , |
1395 | flags: stl_synth_flags, regex: true); |
1396 | AddCXXSynthetic( |
1397 | category_sp: cpp_category_sp, |
1398 | generator: lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, |
1399 | description: "std::weak_ptr synthetic children" , type_name: "^std::weak_ptr<.+>(( )?&)?$" , |
1400 | flags: stl_synth_flags, regex: true); |
1401 | AddCXXSynthetic( |
1402 | category_sp: cpp_category_sp, |
1403 | generator: lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator, |
1404 | description: "std::tuple synthetic children" , type_name: "^std::tuple<.+>(( )?&)?$" , |
1405 | flags: stl_synth_flags, regex: true); |
1406 | |
1407 | static constexpr const char *const libstdcpp_std_coroutine_handle_regex = |
1408 | "^std::coroutine_handle<.+>(( )?&)?$" ; |
1409 | AddCXXSynthetic( |
1410 | category_sp: cpp_category_sp, |
1411 | generator: lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator, |
1412 | description: "std::coroutine_handle synthetic children" , |
1413 | type_name: libstdcpp_std_coroutine_handle_regex, flags: stl_deref_flags, regex: true); |
1414 | |
1415 | AddCXXSynthetic( |
1416 | category_sp: cpp_category_sp, |
1417 | generator: lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator, |
1418 | description: "std::bitset synthetic child" , type_name: "^std::bitset<.+>(( )?&)?$" , |
1419 | flags: stl_deref_flags, regex: true); |
1420 | |
1421 | AddCXXSynthetic( |
1422 | category_sp: cpp_category_sp, |
1423 | generator: lldb_private::formatters::LibStdcppOptionalSyntheticFrontEndCreator, |
1424 | description: "std::optional synthetic child" , type_name: "^std::optional<.+>(( )?&)?$" , |
1425 | flags: stl_deref_flags, regex: true); |
1426 | |
1427 | AddCXXSummary(category_sp: cpp_category_sp, |
1428 | funct: lldb_private::formatters::LibStdcppUniquePointerSummaryProvider, |
1429 | description: "libstdc++ std::unique_ptr summary provider" , |
1430 | type_name: "^std::unique_ptr<.+>(( )?&)?$" , flags: stl_summary_flags, regex: true); |
1431 | AddCXXSummary(category_sp: cpp_category_sp, |
1432 | funct: lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, |
1433 | description: "libstdc++ std::shared_ptr summary provider" , |
1434 | type_name: "^std::shared_ptr<.+>(( )?&)?$" , flags: stl_summary_flags, regex: true); |
1435 | AddCXXSummary(category_sp: cpp_category_sp, |
1436 | funct: lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, |
1437 | description: "libstdc++ std::weak_ptr summary provider" , |
1438 | type_name: "^std::weak_ptr<.+>(( )?&)?$" , flags: stl_summary_flags, regex: true); |
1439 | AddCXXSummary(category_sp: cpp_category_sp, |
1440 | funct: lldb_private::formatters::StdlibCoroutineHandleSummaryProvider, |
1441 | description: "libstdc++ std::coroutine_handle summary provider" , |
1442 | type_name: libstdcpp_std_coroutine_handle_regex, flags: stl_summary_flags, regex: true); |
1443 | AddCXXSummary(category_sp: cpp_category_sp, |
1444 | funct: lldb_private::formatters::GenericOptionalSummaryProvider, |
1445 | description: "libstd++ std::optional summary provider" , |
1446 | type_name: "^std::optional<.+>(( )?&)?$" , flags: stl_summary_flags, regex: true); |
1447 | } |
1448 | |
1449 | static void (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(category_sp: cpp_category_sp, |
1472 | funct: lldb_private::formatters::Char8StringSummaryProvider, |
1473 | description: "char8_t * summary provider" , type_name: "char8_t *" , flags: string_flags); |
1474 | AddCXXSummary(category_sp: cpp_category_sp, |
1475 | funct: lldb_private::formatters::Char8StringSummaryProvider, |
1476 | description: "char8_t [] summary provider" , type_name: "char8_t ?\\[[0-9]+\\]" , |
1477 | flags: string_array_flags, regex: true); |
1478 | |
1479 | AddCXXSummary(category_sp: cpp_category_sp, |
1480 | funct: lldb_private::formatters::Char16StringSummaryProvider, |
1481 | description: "char16_t * summary provider" , type_name: "char16_t *" , flags: string_flags); |
1482 | AddCXXSummary(category_sp: cpp_category_sp, |
1483 | funct: lldb_private::formatters::Char16StringSummaryProvider, |
1484 | description: "char16_t [] summary provider" , type_name: "char16_t ?\\[[0-9]+\\]" , |
1485 | flags: string_array_flags, regex: true); |
1486 | |
1487 | AddCXXSummary(category_sp: cpp_category_sp, |
1488 | funct: lldb_private::formatters::Char32StringSummaryProvider, |
1489 | description: "char32_t * summary provider" , type_name: "char32_t *" , flags: string_flags); |
1490 | AddCXXSummary(category_sp: cpp_category_sp, |
1491 | funct: lldb_private::formatters::Char32StringSummaryProvider, |
1492 | description: "char32_t [] summary provider" , type_name: "char32_t ?\\[[0-9]+\\]" , |
1493 | flags: string_array_flags, regex: true); |
1494 | |
1495 | AddCXXSummary(category_sp: cpp_category_sp, |
1496 | funct: lldb_private::formatters::WCharStringSummaryProvider, |
1497 | description: "wchar_t * summary provider" , type_name: "wchar_t *" , flags: string_flags); |
1498 | AddCXXSummary(category_sp: cpp_category_sp, |
1499 | funct: lldb_private::formatters::WCharStringSummaryProvider, |
1500 | description: "wchar_t * summary provider" , type_name: "wchar_t ?\\[[0-9]+\\]" , |
1501 | flags: string_array_flags, regex: true); |
1502 | |
1503 | AddCXXSummary(category_sp: cpp_category_sp, |
1504 | funct: lldb_private::formatters::Char16StringSummaryProvider, |
1505 | description: "unichar * summary provider" , type_name: "unichar *" , flags: 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(category_sp: cpp_category_sp, funct: lldb_private::formatters::Char8SummaryProvider, |
1517 | description: "char8_t summary provider" , type_name: "char8_t" , flags: widechar_flags); |
1518 | AddCXXSummary(category_sp: cpp_category_sp, |
1519 | funct: lldb_private::formatters::Char16SummaryProvider, |
1520 | description: "char16_t summary provider" , type_name: "char16_t" , flags: widechar_flags); |
1521 | AddCXXSummary(category_sp: cpp_category_sp, |
1522 | funct: lldb_private::formatters::Char32SummaryProvider, |
1523 | description: "char32_t summary provider" , type_name: "char32_t" , flags: widechar_flags); |
1524 | AddCXXSummary(category_sp: cpp_category_sp, funct: lldb_private::formatters::WCharSummaryProvider, |
1525 | description: "wchar_t summary provider" , type_name: "wchar_t" , flags: widechar_flags); |
1526 | |
1527 | AddCXXSummary(category_sp: cpp_category_sp, |
1528 | funct: lldb_private::formatters::Char16SummaryProvider, |
1529 | description: "unichar summary provider" , type_name: "unichar" , flags: 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(language: lang_type) && |
1538 | !Language::LanguageIsCPlusPlus(language: 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(flag&: g_initialize, F: [this]() -> void { |
1554 | DataVisualization::Categories::GetCategory(category: ConstString(GetPluginName()), |
1555 | entry&: g_category); |
1556 | if (g_category) { |
1557 | LoadLibStdcppFormatters(cpp_category_sp: g_category); |
1558 | LoadLibCxxFormatters(cpp_category_sp: g_category); |
1559 | LoadSystemFormatters(cpp_category_sp: 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(flag&: g_initialize, F: []() -> void { |
1572 | g_formatters.push_back( |
1573 | x: [](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 | x: [](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(category_name: g_vectortypes)->IsEnabled()) |
1603 | return formatter_sp; |
1604 | } |
1605 | return nullptr; |
1606 | }); |
1607 | g_formatters.push_back( |
1608 | x: [](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(flag&: g_initialize, F: []() -> void { |
1638 | g_formatters.push_back(x: [](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(category_name: g_vectortypes)->IsEnabled()) |
1652 | return formatter_sp; |
1653 | } |
1654 | return nullptr; |
1655 | }); |
1656 | g_formatters.push_back(x: [](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(language: valobj.GetObjectRuntimeLanguage()) || |
1680 | !valobj.IsPointerType()) |
1681 | return false; |
1682 | bool canReadValue = true; |
1683 | bool isZero = valobj.GetValueAsUnsigned(fail_value: 0, success: &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: 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(Other: "/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(value_if_empty: 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(can_create: true); |
1722 | } |
1723 | } |
1724 | |
1725 | if (get_function_vars) { |
1726 | variable_list_sp = |
1727 | sc->function->GetBlock(can_create: true).GetBlockVariableList(can_create: true); |
1728 | } |
1729 | |
1730 | if (inline_info) { |
1731 | s.PutCString(cstr); |
1732 | s.PutCString(cstr: " [inlined] " ); |
1733 | cstr = inline_info->GetName().GetCString(); |
1734 | } |
1735 | |
1736 | VariableList args; |
1737 | if (variable_list_sp) |
1738 | variable_list_sp->AppendVariablesWithScope(type: eValueTypeVariableArgument, |
1739 | var_list&: args); |
1740 | if (args.GetSize() > 0) { |
1741 | if (!PrettyPrintFunctionNameWithArgs(out_stream&: s, full_name: 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(value_if_empty: 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 | |