LLDB  mainline
CPlusPlusLanguage.cpp
Go to the documentation of this file.
1 //===-- CPlusPlusLanguage.cpp -----------------------------------*- C++ -*-===//
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 
29 #include "lldb/Utility/Log.h"
31 
32 #include "BlockPointer.h"
33 #include "CPlusPlusNameParser.h"
34 #include "CxxStringTypes.h"
35 #include "LibCxx.h"
36 #include "LibCxxAtomic.h"
37 #include "LibCxxVariant.h"
38 #include "LibStdcpp.h"
40 
41 using namespace lldb;
42 using namespace lldb_private;
43 using namespace lldb_private::formatters;
44 
45 void CPlusPlusLanguage::Initialize() {
46  PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
47  CreateInstance);
48 }
49 
50 void CPlusPlusLanguage::Terminate() {
51  PluginManager::UnregisterPlugin(CreateInstance);
52 }
53 
54 lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() {
55  static ConstString g_name("cplusplus");
56  return g_name;
57 }
58 
59 // PluginInterface protocol
60 
61 lldb_private::ConstString CPlusPlusLanguage::GetPluginName() {
62  return GetPluginNameStatic();
63 }
64 
65 uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; }
66 
67 // Static Functions
68 
69 Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
70  if (Language::LanguageIsCPlusPlus(language))
71  return new CPlusPlusLanguage();
72  return nullptr;
73 }
74 
75 void CPlusPlusLanguage::MethodName::Clear() {
76  m_full.Clear();
77  m_basename = llvm::StringRef();
78  m_context = llvm::StringRef();
79  m_arguments = llvm::StringRef();
80  m_qualifiers = llvm::StringRef();
81  m_parsed = false;
82  m_parse_error = false;
83 }
84 
85 static bool ReverseFindMatchingChars(const llvm::StringRef &s,
86  const llvm::StringRef &left_right_chars,
87  size_t &left_pos, size_t &right_pos,
88  size_t pos = llvm::StringRef::npos) {
89  assert(left_right_chars.size() == 2);
90  left_pos = llvm::StringRef::npos;
91  const char left_char = left_right_chars[0];
92  const char right_char = left_right_chars[1];
93  pos = s.find_last_of(left_right_chars, pos);
94  if (pos == llvm::StringRef::npos || s[pos] == left_char)
95  return false;
96  right_pos = pos;
97  uint32_t depth = 1;
98  while (pos > 0 && depth > 0) {
99  pos = s.find_last_of(left_right_chars, pos);
100  if (pos == llvm::StringRef::npos)
101  return false;
102  if (s[pos] == left_char) {
103  if (--depth == 0) {
104  left_pos = pos;
105  return left_pos < right_pos;
106  }
107  } else if (s[pos] == right_char) {
108  ++depth;
109  }
110  }
111  return false;
112 }
113 
114 static bool IsTrivialBasename(const llvm::StringRef &basename) {
115  // Check that the basename matches with the following regular expression
116  // "^~?([A-Za-z_][A-Za-z_0-9]*)$" We are using a hand written implementation
117  // because it is significantly more efficient then using the general purpose
118  // regular expression library.
119  size_t idx = 0;
120  if (basename.size() > 0 && basename[0] == '~')
121  idx = 1;
122 
123  if (basename.size() <= idx)
124  return false; // Empty string or "~"
125 
126  if (!std::isalpha(basename[idx]) && basename[idx] != '_')
127  return false; // First charater (after removing the possible '~'') isn't in
128  // [A-Za-z_]
129 
130  // Read all characters matching [A-Za-z_0-9]
131  ++idx;
132  while (idx < basename.size()) {
133  if (!std::isalnum(basename[idx]) && basename[idx] != '_')
134  break;
135  ++idx;
136  }
137 
138  // We processed all characters. It is a vaild basename.
139  return idx == basename.size();
140 }
141 
142 bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
143  // This method tries to parse simple method definitions which are presumably
144  // most comman in user programs. Definitions that can be parsed by this
145  // function don't have return types and templates in the name.
146  // A::B::C::fun(std::vector<T> &) const
147  size_t arg_start, arg_end;
148  llvm::StringRef full(m_full.GetCString());
149  llvm::StringRef parens("()", 2);
150  if (ReverseFindMatchingChars(full, parens, arg_start, arg_end)) {
151  m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
152  if (arg_end + 1 < full.size())
153  m_qualifiers = full.substr(arg_end + 1).ltrim();
154 
155  if (arg_start == 0)
156  return false;
157  size_t basename_end = arg_start;
158  size_t context_start = 0;
159  size_t context_end = full.rfind(':', basename_end);
160  if (context_end == llvm::StringRef::npos)
161  m_basename = full.substr(0, basename_end);
162  else {
163  if (context_start < context_end)
164  m_context = full.substr(context_start, context_end - 1 - context_start);
165  const size_t basename_begin = context_end + 1;
166  m_basename = full.substr(basename_begin, basename_end - basename_begin);
167  }
168 
169  if (IsTrivialBasename(m_basename)) {
170  return true;
171  } else {
172  // The C++ basename doesn't match our regular expressions so this can't
173  // be a valid C++ method, clear everything out and indicate an error
174  m_context = llvm::StringRef();
175  m_basename = llvm::StringRef();
176  m_arguments = llvm::StringRef();
177  m_qualifiers = llvm::StringRef();
178  return false;
179  }
180  }
181  return false;
182 }
183 
185  if (!m_parsed && m_full) {
186  if (TrySimplifiedParse()) {
187  m_parse_error = false;
188  } else {
189  CPlusPlusNameParser parser(m_full.GetStringRef());
190  if (auto function = parser.ParseAsFunctionDefinition()) {
191  m_basename = function.getValue().name.basename;
192  m_context = function.getValue().name.context;
193  m_arguments = function.getValue().arguments;
194  m_qualifiers = function.getValue().qualifiers;
195  m_parse_error = false;
196  } else {
197  m_parse_error = true;
198  }
199  }
200  m_parsed = true;
201  }
202 }
203 
204 llvm::StringRef CPlusPlusLanguage::MethodName::GetBasename() {
205  if (!m_parsed)
206  Parse();
207  return m_basename;
208 }
209 
210 llvm::StringRef CPlusPlusLanguage::MethodName::GetContext() {
211  if (!m_parsed)
212  Parse();
213  return m_context;
214 }
215 
216 llvm::StringRef CPlusPlusLanguage::MethodName::GetArguments() {
217  if (!m_parsed)
218  Parse();
219  return m_arguments;
220 }
221 
222 llvm::StringRef CPlusPlusLanguage::MethodName::GetQualifiers() {
223  if (!m_parsed)
224  Parse();
225  return m_qualifiers;
226 }
227 
228 std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
229  if (!m_parsed)
230  Parse();
231  if (m_context.empty())
232  return m_basename;
233 
234  std::string res;
235  res += m_context;
236  res += "::";
237  res += m_basename;
238  return res;
239 }
240 
241 bool CPlusPlusLanguage::IsCPPMangledName(const char *name) {
242  // FIXME!! we should really run through all the known C++ Language plugins
243  // and ask each one if this is a C++ mangled name
244 
245  if (name == nullptr)
246  return false;
247 
248  // MSVC style mangling
249  if (name[0] == '?')
250  return true;
251 
252  return (name[0] != '\0' && name[0] == '_' && name[1] == 'Z');
253 }
254 
255 bool CPlusPlusLanguage::ExtractContextAndIdentifier(
256  const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
259  identifier);
260 
261  CPlusPlusNameParser parser(name);
262  if (auto full_name = parser.ParseAsFullName()) {
263  identifier = full_name.getValue().basename;
264  context = full_name.getValue().context;
265  return true;
266  }
267  return false;
268 }
269 
270 namespace {
271 class NodeAllocator {
272  llvm::BumpPtrAllocator Alloc;
273 
274 public:
275  void reset() { Alloc.Reset(); }
276 
277  template <typename T, typename... Args> T *makeNode(Args &&... args) {
278  return new (Alloc.Allocate(sizeof(T), alignof(T)))
279  T(std::forward<Args>(args)...);
280  }
281 
282  void *allocateNodeArray(size_t sz) {
283  return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,
284  alignof(llvm::itanium_demangle::Node *));
285  }
286 };
287 
288 /// Given a mangled function `Mangled`, replace all the primitive function type
289 /// arguments of `Search` with type `Replace`.
290 class TypeSubstitutor
291  : public llvm::itanium_demangle::AbstractManglingParser<TypeSubstitutor,
292  NodeAllocator> {
293  /// Input character until which we have constructed the respective output
294  /// already
295  const char *Written;
296 
297  llvm::StringRef Search;
298  llvm::StringRef Replace;
299  llvm::SmallString<128> Result;
300 
301  /// Whether we have performed any substitutions.
302  bool Substituted;
303 
304  void reset(llvm::StringRef Mangled, llvm::StringRef Search,
305  llvm::StringRef Replace) {
306  AbstractManglingParser::reset(Mangled.begin(), Mangled.end());
307  Written = Mangled.begin();
308  this->Search = Search;
309  this->Replace = Replace;
310  Result.clear();
311  Substituted = false;
312  }
313 
314  void appendUnchangedInput() {
315  Result += llvm::StringRef(Written, First - Written);
316  Written = First;
317  }
318 
319 public:
320  TypeSubstitutor() : AbstractManglingParser(nullptr, nullptr) {}
321 
322  ConstString substitute(llvm::StringRef Mangled, llvm::StringRef From,
323  llvm::StringRef To) {
325 
326  reset(Mangled, From, To);
327  if (parse() == nullptr) {
328  LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled);
329  return ConstString();
330  }
331  if (!Substituted)
332  return ConstString();
333 
334  // Append any trailing unmodified input.
335  appendUnchangedInput();
336  LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
337  return ConstString(Result);
338  }
339 
340  llvm::itanium_demangle::Node *parseType() {
341  if (llvm::StringRef(First, numLeft()).startswith(Search)) {
342  // We found a match. Append unmodified input up to this point.
343  appendUnchangedInput();
344 
345  // And then perform the replacement.
346  Result += Replace;
347  Written += Search.size();
348  Substituted = true;
349  }
350  return AbstractManglingParser::parseType();
351  }
352 };
353 }
354 
355 uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
356  const ConstString mangled_name, std::set<ConstString> &alternates) {
357  const auto start_size = alternates.size();
358  /// Get a basic set of alternative manglings for the given symbol `name`, by
359  /// making a few basic possible substitutions on basic types, storage duration
360  /// and `const`ness for the given symbol. The output parameter `alternates`
361  /// is filled with a best-guess, non-exhaustive set of different manglings
362  /// for the given name.
363 
364  // Maybe we're looking for a const symbol but the debug info told us it was
365  // non-const...
366  if (!strncmp(mangled_name.GetCString(), "_ZN", 3) &&
367  strncmp(mangled_name.GetCString(), "_ZNK", 4)) {
368  std::string fixed_scratch("_ZNK");
369  fixed_scratch.append(mangled_name.GetCString() + 3);
370  alternates.insert(ConstString(fixed_scratch));
371  }
372 
373  // Maybe we're looking for a static symbol but we thought it was global...
374  if (!strncmp(mangled_name.GetCString(), "_Z", 2) &&
375  strncmp(mangled_name.GetCString(), "_ZL", 3)) {
376  std::string fixed_scratch("_ZL");
377  fixed_scratch.append(mangled_name.GetCString() + 2);
378  alternates.insert(ConstString(fixed_scratch));
379  }
380 
381  TypeSubstitutor TS;
382  // `char` is implementation defined as either `signed` or `unsigned`. As a
383  // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
384  // char, 'h'-unsigned char. If we're looking for symbols with a signed char
385  // parameter, try finding matches which have the general case 'c'.
386  if (ConstString char_fixup =
387  TS.substitute(mangled_name.GetStringRef(), "a", "c"))
388  alternates.insert(char_fixup);
389 
390  // long long parameter mangling 'x', may actually just be a long 'l' argument
391  if (ConstString long_fixup =
392  TS.substitute(mangled_name.GetStringRef(), "x", "l"))
393  alternates.insert(long_fixup);
394 
395  // unsigned long long parameter mangling 'y', may actually just be unsigned
396  // long 'm' argument
397  if (ConstString ulong_fixup =
398  TS.substitute(mangled_name.GetStringRef(), "y", "m"))
399  alternates.insert(ulong_fixup);
400 
401  return alternates.size() - start_size;
402 }
403 
404 static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
405  if (!cpp_category_sp)
406  return;
407 
408  TypeSummaryImpl::Flags stl_summary_flags;
409  stl_summary_flags.SetCascades(true)
410  .SetSkipPointers(false)
411  .SetSkipReferences(false)
412  .SetDontShowChildren(true)
413  .SetDontShowValue(true)
414  .SetShowMembersOneLiner(false)
415  .SetHideItemNames(false);
416 
417  AddCXXSummary(cpp_category_sp,
419  "std::string summary provider",
420  ConstString("^std::__[[:alnum:]]+::string$"), stl_summary_flags,
421  true);
422  AddCXXSummary(cpp_category_sp,
424  "std::string summary provider",
425  ConstString("^std::__[[:alnum:]]+::basic_string<char, "
426  "std::__[[:alnum:]]+::char_traits<char>, "
427  "std::__[[:alnum:]]+::allocator<char> >$"),
428  stl_summary_flags, true);
429 
430  AddCXXSummary(cpp_category_sp,
432  "std::u16string summary provider",
433  ConstString(
434  "^std::__[[:alnum:]]+::basic_string<char16_t, "
435  "std::__[[:alnum:]]+::char_traits<char16_t>, "
436  "std::__[[:alnum:]]+::allocator<char16_t> >$"),
437  stl_summary_flags, true);
438 
439  AddCXXSummary(cpp_category_sp,
441  "std::u32string summary provider",
442  ConstString(
443  "^std::__[[:alnum:]]+::basic_string<char32_t, "
444  "std::__[[:alnum:]]+::char_traits<char32_t>, "
445  "std::__[[:alnum:]]+::allocator<char32_t> >$"),
446  stl_summary_flags, true);
447 
448  AddCXXSummary(cpp_category_sp,
450  "std::wstring summary provider",
451  ConstString("^std::__[[:alnum:]]+::wstring$"),
452  stl_summary_flags, true);
453  AddCXXSummary(cpp_category_sp,
455  "std::wstring summary provider",
456  ConstString("^std::__[[:alnum:]]+::basic_string<wchar_t, "
457  "std::__[[:alnum:]]+::char_traits<wchar_t>, "
458  "std::__[[:alnum:]]+::allocator<wchar_t> >$"),
459  stl_summary_flags, true);
460 
461  SyntheticChildren::Flags stl_synth_flags;
462  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
463  false);
464  SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
465  stl_deref_flags.SetFrontEndWantsDereference();
466 
468  cpp_category_sp,
470  "libc++ std::bitset synthetic children",
471  ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"), stl_deref_flags,
472  true);
474  cpp_category_sp,
476  "libc++ std::vector synthetic children",
477  ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"), stl_deref_flags,
478  true);
480  cpp_category_sp,
482  "libc++ std::forward_list synthetic children",
483  ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
484  stl_synth_flags, true);
486  cpp_category_sp,
488  "libc++ std::list synthetic children",
489  ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"), stl_deref_flags,
490  true);
492  cpp_category_sp,
494  "libc++ std::map synthetic children",
495  ConstString("^std::__[[:alnum:]]+::map<.+> >(( )?&)?$"), stl_synth_flags,
496  true);
498  cpp_category_sp,
500  "libc++ std::set synthetic children",
501  ConstString("^std::__[[:alnum:]]+::set<.+> >(( )?&)?$"), stl_deref_flags,
502  true);
504  cpp_category_sp,
506  "libc++ std::multiset synthetic children",
507  ConstString("^std::__[[:alnum:]]+::multiset<.+> >(( )?&)?$"),
508  stl_deref_flags, true);
510  cpp_category_sp,
512  "libc++ std::multimap synthetic children",
513  ConstString("^std::__[[:alnum:]]+::multimap<.+> >(( )?&)?$"),
514  stl_synth_flags, true);
516  cpp_category_sp,
518  "libc++ std::unordered containers synthetic children",
519  ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"),
520  stl_synth_flags, true);
522  cpp_category_sp,
524  "libc++ std::initializer_list synthetic children",
525  ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags,
526  true);
528  "libc++ std::queue synthetic children",
529  ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"),
530  stl_synth_flags, true);
532  "libc++ std::tuple synthetic children",
533  ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
534  stl_synth_flags, true);
536  "libc++ std::optional synthetic children",
537  ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
538  stl_synth_flags, true);
540  "libc++ std::variant synthetic children",
541  ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"),
542  stl_synth_flags, true);
544  cpp_category_sp,
546  "libc++ std::atomic synthetic children",
547  ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true);
548 
549  cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
550  RegularExpressionSP(new RegularExpression(
551  llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$"))),
552  SyntheticChildrenSP(new ScriptedSyntheticChildren(
553  stl_synth_flags,
554  "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
555 
557  cpp_category_sp,
559  "shared_ptr synthetic children",
560  ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"),
561  stl_synth_flags, true);
563  cpp_category_sp,
565  "weak_ptr synthetic children",
566  ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"),
567  stl_synth_flags, true);
568 
571  "libc++ std::function summary provider",
572  ConstString("^std::__[[:alnum:]]+::function<.+>$"), stl_summary_flags,
573  true);
574 
575  stl_summary_flags.SetDontShowChildren(false);
576  stl_summary_flags.SetSkipPointers(false);
577  AddCXXSummary(cpp_category_sp,
579  "libc++ std::bitset summary provider",
580  ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"),
581  stl_summary_flags, true);
582  AddCXXSummary(cpp_category_sp,
584  "libc++ std::vector summary provider",
585  ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"),
586  stl_summary_flags, true);
587  AddCXXSummary(cpp_category_sp,
589  "libc++ std::list summary provider",
590  ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
591  stl_summary_flags, true);
592  AddCXXSummary(cpp_category_sp,
594  "libc++ std::list summary provider",
595  ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"),
596  stl_summary_flags, true);
597  AddCXXSummary(cpp_category_sp,
599  "libc++ std::map summary provider",
600  ConstString("^std::__[[:alnum:]]+::map<.+>(( )?&)?$"),
601  stl_summary_flags, true);
602  AddCXXSummary(cpp_category_sp,
604  "libc++ std::deque summary provider",
605  ConstString("^std::__[[:alnum:]]+::deque<.+>(( )?&)?$"),
606  stl_summary_flags, true);
607  AddCXXSummary(cpp_category_sp,
609  "libc++ std::queue summary provider",
610  ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"),
611  stl_summary_flags, true);
612  AddCXXSummary(cpp_category_sp,
614  "libc++ std::set summary provider",
615  ConstString("^std::__[[:alnum:]]+::set<.+>(( )?&)?$"),
616  stl_summary_flags, true);
617  AddCXXSummary(cpp_category_sp,
619  "libc++ std::multiset summary provider",
620  ConstString("^std::__[[:alnum:]]+::multiset<.+>(( )?&)?$"),
621  stl_summary_flags, true);
622  AddCXXSummary(cpp_category_sp,
624  "libc++ std::multimap summary provider",
625  ConstString("^std::__[[:alnum:]]+::multimap<.+>(( )?&)?$"),
626  stl_summary_flags, true);
629  "libc++ std::unordered containers summary provider",
630  ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"),
631  stl_summary_flags, true);
633  "libc++ std::tuple summary provider",
634  ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"),
635  stl_summary_flags, true);
638  "libc++ std::atomic summary provider",
639  ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_summary_flags,
640  true);
641  AddCXXSummary(cpp_category_sp,
643  "libc++ std::optional summary provider",
644  ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"),
645  stl_summary_flags, true);
646  AddCXXSummary(cpp_category_sp,
648  "libc++ std::variant summary provider",
649  ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"),
650  stl_summary_flags, true);
651 
652  stl_summary_flags.SetSkipPointers(true);
653 
654  AddCXXSummary(cpp_category_sp,
656  "libc++ std::shared_ptr summary provider",
657  ConstString("^std::__[[:alnum:]]+::shared_ptr<.+>(( )?&)?$"),
658  stl_summary_flags, true);
659  AddCXXSummary(cpp_category_sp,
661  "libc++ std::weak_ptr summary provider",
662  ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"),
663  stl_summary_flags, true);
664 
666  cpp_category_sp,
668  "std::vector iterator synthetic children",
669  ConstString("^std::__[[:alnum:]]+::__wrap_iter<.+>$"), stl_synth_flags,
670  true);
671 
673  cpp_category_sp,
675  "std::map iterator synthetic children",
676  ConstString("^std::__[[:alnum:]]+::__map_iterator<.+>$"), stl_synth_flags,
677  true);
678 }
679 
680 static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
681  if (!cpp_category_sp)
682  return;
683 
684  TypeSummaryImpl::Flags stl_summary_flags;
685  stl_summary_flags.SetCascades(true)
686  .SetSkipPointers(false)
687  .SetSkipReferences(false)
688  .SetDontShowChildren(true)
689  .SetDontShowValue(true)
690  .SetShowMembersOneLiner(false)
691  .SetHideItemNames(false);
692 
693  lldb::TypeSummaryImplSP std_string_summary_sp(
694  new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p}"));
695 
696  lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(
697  stl_summary_flags, LibStdcppStringSummaryProvider,
698  "libstdc++ c++11 std::string summary provider"));
699  lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(
700  stl_summary_flags, LibStdcppWStringSummaryProvider,
701  "libstdc++ c++11 std::wstring summary provider"));
702 
703  cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
704  std_string_summary_sp);
705  cpp_category_sp->GetTypeSummariesContainer()->Add(
706  ConstString("std::basic_string<char>"), std_string_summary_sp);
707  cpp_category_sp->GetTypeSummariesContainer()->Add(
708  ConstString("std::basic_string<char,std::char_traits<char>,std::"
709  "allocator<char> >"),
710  std_string_summary_sp);
711  cpp_category_sp->GetTypeSummariesContainer()->Add(
712  ConstString("std::basic_string<char, std::char_traits<char>, "
713  "std::allocator<char> >"),
714  std_string_summary_sp);
715 
716  cpp_category_sp->GetTypeSummariesContainer()->Add(
717  ConstString("std::__cxx11::string"), cxx11_string_summary_sp);
718  cpp_category_sp->GetTypeSummariesContainer()->Add(
719  ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, "
720  "std::allocator<char> >"),
721  cxx11_string_summary_sp);
722 
723  // making sure we force-pick the summary for printing wstring (_M_p is a
724  // wchar_t*)
725  lldb::TypeSummaryImplSP std_wstring_summary_sp(
726  new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}"));
727 
728  cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"),
729  std_wstring_summary_sp);
730  cpp_category_sp->GetTypeSummariesContainer()->Add(
731  ConstString("std::basic_string<wchar_t>"), std_wstring_summary_sp);
732  cpp_category_sp->GetTypeSummariesContainer()->Add(
733  ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::"
734  "allocator<wchar_t> >"),
735  std_wstring_summary_sp);
736  cpp_category_sp->GetTypeSummariesContainer()->Add(
737  ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, "
738  "std::allocator<wchar_t> >"),
739  std_wstring_summary_sp);
740 
741  cpp_category_sp->GetTypeSummariesContainer()->Add(
742  ConstString("std::__cxx11::wstring"), cxx11_wstring_summary_sp);
743  cpp_category_sp->GetTypeSummariesContainer()->Add(
744  ConstString("std::__cxx11::basic_string<wchar_t, "
745  "std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
746  cxx11_wstring_summary_sp);
747 
748  SyntheticChildren::Flags stl_synth_flags;
749  stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
750  false);
751 
752  cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
753  RegularExpressionSP(
754  new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
755  SyntheticChildrenSP(new ScriptedSyntheticChildren(
756  stl_synth_flags,
757  "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
758  cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
759  RegularExpressionSP(
760  new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
761  SyntheticChildrenSP(new ScriptedSyntheticChildren(
762  stl_synth_flags,
763  "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
764  cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
765  RegularExpressionSP(new RegularExpression(
766  llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
767  SyntheticChildrenSP(new ScriptedSyntheticChildren(
768  stl_synth_flags,
769  "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
770  stl_summary_flags.SetDontShowChildren(false);
771  stl_summary_flags.SetSkipPointers(true);
772  cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
773  RegularExpressionSP(
774  new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
775  TypeSummaryImplSP(
776  new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
777  cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
778  RegularExpressionSP(
779  new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
780  TypeSummaryImplSP(
781  new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
782  cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
783  RegularExpressionSP(new RegularExpression(
784  llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
785  TypeSummaryImplSP(
786  new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
787 
789  cpp_category_sp,
791  "std::vector iterator synthetic children",
792  ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
793 
795  cpp_category_sp,
797  "std::map iterator synthetic children",
798  ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
799 
801  cpp_category_sp,
803  "std::unique_ptr synthetic children",
804  ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
806  cpp_category_sp,
808  "std::shared_ptr synthetic children",
809  ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
811  cpp_category_sp,
813  "std::weak_ptr synthetic children",
814  ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
816  cpp_category_sp,
818  "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"),
819  stl_synth_flags, true);
820 
821  AddCXXSummary(cpp_category_sp,
823  "libstdc++ std::unique_ptr summary provider",
824  ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags,
825  true);
826  AddCXXSummary(cpp_category_sp,
828  "libstdc++ std::shared_ptr summary provider",
829  ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags,
830  true);
831  AddCXXSummary(cpp_category_sp,
833  "libstdc++ std::weak_ptr summary provider",
834  ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags,
835  true);
836 }
837 
838 static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
839  if (!cpp_category_sp)
840  return;
841 
842  TypeSummaryImpl::Flags string_flags;
843  string_flags.SetCascades(true)
844  .SetSkipPointers(true)
845  .SetSkipReferences(false)
846  .SetDontShowChildren(true)
847  .SetDontShowValue(false)
848  .SetShowMembersOneLiner(false)
849  .SetHideItemNames(false);
850 
851  TypeSummaryImpl::Flags string_array_flags;
852  string_array_flags.SetCascades(true)
853  .SetSkipPointers(true)
854  .SetSkipReferences(false)
855  .SetDontShowChildren(true)
856  .SetDontShowValue(true)
857  .SetShowMembersOneLiner(false)
858  .SetHideItemNames(false);
859 
860  // FIXME because of a bug in the FormattersContainer we need to add a summary
861  // for both X* and const X* (<rdar://problem/12717717>)
864  "char16_t * summary provider", ConstString("char16_t *"), string_flags);
865  AddCXXSummary(cpp_category_sp,
867  "char16_t [] summary provider",
868  ConstString("char16_t \\[[0-9]+\\]"), string_array_flags, true);
869 
872  "char32_t * summary provider", ConstString("char32_t *"), string_flags);
873  AddCXXSummary(cpp_category_sp,
875  "char32_t [] summary provider",
876  ConstString("char32_t \\[[0-9]+\\]"), string_array_flags, true);
877 
880  "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
881  AddCXXSummary(cpp_category_sp,
883  "wchar_t * summary provider",
884  ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true);
885 
888  "unichar * summary provider", ConstString("unichar *"), string_flags);
889 
890  TypeSummaryImpl::Flags widechar_flags;
891  widechar_flags.SetDontShowValue(true)
892  .SetSkipPointers(true)
893  .SetSkipReferences(false)
894  .SetCascades(true)
895  .SetDontShowChildren(true)
896  .SetHideItemNames(true)
897  .SetShowMembersOneLiner(false);
898 
901  "char16_t summary provider", ConstString("char16_t"), widechar_flags);
904  "char32_t summary provider", ConstString("char32_t"), widechar_flags);
906  "wchar_t summary provider", ConstString("wchar_t"),
907  widechar_flags);
908 
911  "unichar summary provider", ConstString("unichar"), widechar_flags);
912 }
913 
914 std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() {
915  class CPlusPlusTypeScavenger : public Language::ImageListTypeScavenger {
916  public:
917  CompilerType AdjustForInclusion(CompilerType &candidate) override {
918  LanguageType lang_type(candidate.GetMinimumLanguage());
919  if (!Language::LanguageIsC(lang_type) &&
920  !Language::LanguageIsCPlusPlus(lang_type))
921  return CompilerType();
922  if (candidate.IsTypedefType())
923  return candidate.GetTypedefedType();
924  return candidate;
925  }
926  };
927 
928  return std::unique_ptr<TypeScavenger>(new CPlusPlusTypeScavenger());
929 }
930 
931 lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
932  static llvm::once_flag g_initialize;
933  static TypeCategoryImplSP g_category;
934 
935  llvm::call_once(g_initialize, [this]() -> void {
936  DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
937  if (g_category) {
938  LoadLibStdcppFormatters(g_category);
939  LoadLibCxxFormatters(g_category);
940  LoadSystemFormatters(g_category);
941  }
942  });
943  return g_category;
944 }
945 
947 CPlusPlusLanguage::GetHardcodedSummaries() {
948  static llvm::once_flag g_initialize;
949  static ConstString g_vectortypes("VectorTypes");
951 
952  llvm::call_once(g_initialize, []() -> void {
953  g_formatters.push_back(
956  static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
960  "Function pointer summary provider"));
961  if (valobj.GetCompilerType().IsFunctionPointerType()) {
962  return formatter_sp;
963  }
964  return nullptr;
965  });
966  g_formatters.push_back(
969  static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
972  .SetCascades(true)
973  .SetDontShowChildren(true)
974  .SetHideItemNames(true)
975  .SetShowMembersOneLiner(true)
976  .SetSkipPointers(true)
977  .SetSkipReferences(false),
979  "vector_type pointer summary provider"));
980  if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
981  if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
982  return formatter_sp;
983  }
984  return nullptr;
985  });
986  g_formatters.push_back(
989  static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
992  .SetCascades(true)
993  .SetDontShowChildren(true)
994  .SetHideItemNames(true)
995  .SetShowMembersOneLiner(true)
996  .SetSkipPointers(true)
997  .SetSkipReferences(false),
999  "block pointer summary provider"));
1000  if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
1001  return formatter_sp;
1002  }
1003  return nullptr;
1004  });
1005  });
1006 
1007  return g_formatters;
1008 }
1009 
1011 CPlusPlusLanguage::GetHardcodedSynthetics() {
1012  static llvm::once_flag g_initialize;
1013  static ConstString g_vectortypes("VectorTypes");
1015 
1016  llvm::call_once(g_initialize, []() -> void {
1017  g_formatters.push_back([](lldb_private::ValueObject &valobj,
1019  FormatManager &
1020  fmt_mgr) -> SyntheticChildren::SharedPointer {
1021  static CXXSyntheticChildren::SharedPointer formatter_sp(
1024  .SetCascades(true)
1025  .SetSkipPointers(true)
1026  .SetSkipReferences(true)
1027  .SetNonCacheable(true),
1028  "vector_type synthetic children",
1030  if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
1031  if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
1032  return formatter_sp;
1033  }
1034  return nullptr;
1035  });
1036  g_formatters.push_back([](lldb_private::ValueObject &valobj,
1038  FormatManager &
1039  fmt_mgr) -> SyntheticChildren::SharedPointer {
1040  static CXXSyntheticChildren::SharedPointer formatter_sp(
1043  .SetCascades(true)
1044  .SetSkipPointers(true)
1045  .SetSkipReferences(true)
1046  .SetNonCacheable(true),
1047  "block pointer synthetic children",
1049  if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
1050  return formatter_sp;
1051  }
1052  return nullptr;
1053  });
1054 
1055  });
1056 
1057  return g_formatters;
1058 }
1059 
1060 bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
1061  const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c",
1062  ".h", ".hh", ".hpp", ".hxx", ".h++"};
1063  for (auto suffix : suffixes) {
1064  if (file_path.endswith_lower(suffix))
1065  return true;
1066  }
1067 
1068  // Check if we're in a STL path (where the files usually have no extension
1069  // that we could check for.
1070  return file_path.contains("/usr/include/c++/");
1071 }
bool BlockPointerSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &)
bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
SyntheticChildrenFrontEnd * LibCxxVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxx.cpp:333
A command line argument class.
Definition: Args.h:32
CompilerType GetCompilerType()
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
Flags & SetCascades(bool value=true)
Definition: TypeSummary.h:85
static bool IsTrivialBasename(const llvm::StringRef &basename)
HardcodedFormatterFinders< SyntheticChildren > HardcodedSyntheticFinder
Definition: FormatClasses.h:42
bool IsFunctionPointerType() const
SyntheticChildrenFrontEnd * LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcpp.cpp:170
Flags & SetHideItemNames(bool value=true)
Definition: TypeSummary.h:176
bool LibcxxStringSummaryProviderUTF16(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition: LibCxx.cpp:668
static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp)
bool Char16StringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool WCharSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool LibStdcppWStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibStdcpp.cpp:280
std::shared_ptr< TypeSummaryImpl > SharedPointer
Definition: TypeSummary.h:266
bool LibStdcppStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibStdcpp.cpp:232
"lldb/Utility/RegularExpression.h" A C++ wrapper class for regex.
Flags & SetSkipReferences(bool value=true)
bool LibcxxWStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:546
bool LibStdcppUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool LibcxxStringSummaryProviderUTF32(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition: LibCxx.cpp:675
#define LIBLLDB_LOG_LANGUAGE
Definition: Logging.h:42
static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp)
#define LLDB_LOG(log,...)
Definition: Log.h:209
bool Char32SummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
SyntheticChildrenFrontEnd * LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
bool LibcxxOptionalSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:34
HardcodedFormatterFinders< TypeSummaryImpl > HardcodedSummaryFinder
Definition: FormatClasses.h:41
Flags & SetCascades(bool value=true)
bool LibStdcppSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibStdcpp.cpp:389
SyntheticChildrenFrontEnd * LibStdcppSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcpp.cpp:383
bool IsVectorType(CompilerType *element_type, uint64_t *size) const
bool LibCxxAtomicSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
SyntheticChildrenFrontEnd * LibCxxMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxx.cpp:317
SyntheticChildrenFrontEnd * LibcxxStdForwardListSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxxList.cpp:441
std::shared_ptr< SyntheticChildren > SharedPointer
SyntheticChildrenFrontEnd * LibcxxTupleFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxxTuple.cpp:77
LanguageType
Programming language type.
lldb::LanguageType GetMinimumLanguage()
Node * Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc)
Parse the given postfix expression.
bool LibcxxContainerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:452
Flags & SetFrontEndWantsDereference(bool value=true)
SyntheticChildrenFrontEnd * LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
SyntheticChildrenFrontEnd * BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Flags & SetDontShowValue(bool value=true)
Definition: TypeSummary.h:150
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
Flags & SetSkipPointers(bool value=true)
Flags & SetSkipPointers(bool value=true)
Definition: TypeSummary.h:98
const_iterator begin() const
Definition: Args.h:128
static bool ReverseFindMatchingChars(const llvm::StringRef &s, const llvm::StringRef &left_right_chars, size_t &left_pos, size_t &right_pos, size_t pos=llvm::StringRef::npos)
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:233
static bool ExtractContextAndIdentifier(llvm::StringRef name, llvm::StringRef &context, llvm::StringRef &identifier)
bool Char16SummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
bool LibcxxStringSummaryProviderASCII(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition: LibCxx.cpp:661
void AddCXXSummary(TypeCategoryImpl::SharedPointer category_sp, CXXFunctionSummaryFormat::Callback funct, const char *description, ConstString type_name, TypeSummaryImpl::Flags flags, bool regex=false)
static bool IsMSVCUndecoratedName(llvm::StringRef name)
SyntheticChildrenFrontEnd * LibcxxStdMapSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxxMap.cpp:460
SyntheticChildrenFrontEnd * VectorTypeSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: VectorType.cpp:292
bool WCharStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
SyntheticChildrenFrontEnd * LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxx.cpp:446
SyntheticChildrenFrontEnd * LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxxList.cpp:435
bool VectorTypeSummaryProvider(ValueObject &, Stream &, const TypeSummaryOptions &)
Definition: VectorType.cpp:254
std::shared_ptr< CXXFunctionSummaryFormat > SharedPointer
Definition: TypeSummary.h:344
SyntheticChildrenFrontEnd * LibcxxAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
SyntheticChildrenFrontEnd * LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp)
Flags & SetDontShowChildren(bool value=true)
Definition: TypeSummary.h:124
SyntheticChildrenFrontEnd * LibcxxStdUnorderedMapSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
A uniqued constant string class.
Definition: ConstString.h:38
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
char * basename(char *path)
Definition: SBAddress.h:15
static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp)
SyntheticChildrenFrontEnd * LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
lldb::TypeCategoryImplSP GetCategory(const char *category_name=nullptr, bool can_create=true)
CompilerType GetTypedefedType() const
bool LibcxxFunctionSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:56
bool CXXFunctionPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
SyntheticChildrenFrontEnd * LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp)
bool IsBlockPointerType(CompilerType *function_pointer_type_ptr) const
SyntheticChildrenFrontEnd * LibstdcppMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibStdcpp.cpp:153
bool Char32StringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Flags & SetSkipReferences(bool value=true)
Definition: TypeSummary.h:111
Flags & SetShowMembersOneLiner(bool value=true)
Definition: TypeSummary.h:163
SyntheticChildrenFrontEnd * LibcxxQueueFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxxQueue.cpp:55
SyntheticChildrenFrontEnd * LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
bool LibcxxSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:104
SyntheticChildrenFrontEnd * LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
void AddCXXSynthetic(TypeCategoryImpl::SharedPointer category_sp, CXXSyntheticChildren::CreateFrontEndCallback generator, const char *description, ConstString type_name, ScriptedSyntheticChildren::Flags flags, bool regex=false)
llvm::Optional< ParsedName > ParseAsFullName()