LLDB  mainline
LibCxx.cpp
Go to the documentation of this file.
1 //===-- LibCxx.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 "LibCxx.h"
10 
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/FormatEntity.h"
13 #include "lldb/Core/ValueObject.h"
21 #include "lldb/Target/Target.h"
23 #include "lldb/Utility/Endian.h"
24 #include "lldb/Utility/Status.h"
25 #include "lldb/Utility/Stream.h"
26 
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 using namespace lldb_private::formatters;
33 
35  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
36  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
37  if (!valobj_sp)
38  return false;
39 
40  // An optional either contains a value or not, the member __engaged_ is
41  // a bool flag, it is true if the optional has a value and false otherwise.
42  ValueObjectSP engaged_sp(
43  valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true));
44 
45  if (!engaged_sp)
46  return false;
47 
48  llvm::StringRef engaged_as_cstring(
49  engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false");
50 
51  stream.Printf(" Has Value=%s ", engaged_as_cstring.data());
52 
53  return true;
54 }
55 
57  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
58 
59  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
60 
61  if (!valobj_sp)
62  return false;
63 
64  ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
65  Process *process = exe_ctx.GetProcessPtr();
66 
67  if (process == nullptr)
68  return false;
69 
70  CPPLanguageRuntime *cpp_runtime = CPPLanguageRuntime::Get(*process);
71 
72  if (!cpp_runtime)
73  return false;
74 
76  cpp_runtime->FindLibCppStdFunctionCallableInfo(valobj_sp);
77 
78  switch (callable_info.callable_case) {
79  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Invalid:
80  stream.Printf(" __f_ = %" PRIu64, callable_info.member__f_pointer_value);
81  return false;
82  break;
83  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda:
84  stream.Printf(
85  " Lambda in File %s at Line %u",
87  callable_info.callable_line_entry.line);
88  break;
89  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::CallableObject:
90  stream.Printf(
91  " Function in File %s at Line %u",
93  callable_info.callable_line_entry.line);
94  break;
95  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::FreeOrMemberFunction:
96  stream.Printf(" Function = %s ",
97  callable_info.callable_symbol.GetName().GetCString());
98  break;
99  }
100 
101  return true;
102 }
103 
105  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
106  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
107  if (!valobj_sp)
108  return false;
109  ValueObjectSP ptr_sp(
110  valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
111  ValueObjectSP count_sp(valobj_sp->GetChildAtNamePath(
112  {ConstString("__cntrl_"), ConstString("__shared_owners_")}));
113  ValueObjectSP weakcount_sp(valobj_sp->GetChildAtNamePath(
114  {ConstString("__cntrl_"), ConstString("__shared_weak_owners_")}));
115 
116  if (!ptr_sp)
117  return false;
118 
119  if (ptr_sp->GetValueAsUnsigned(0) == 0) {
120  stream.Printf("nullptr");
121  return true;
122  } else {
123  bool print_pointee = false;
124  Status error;
125  ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
126  if (pointee_sp && error.Success()) {
127  if (pointee_sp->DumpPrintableRepresentation(
128  stream, ValueObject::eValueObjectRepresentationStyleSummary,
130  ValueObject::PrintableRepresentationSpecialCases::eDisable,
131  false))
132  print_pointee = true;
133  }
134  if (!print_pointee)
135  stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
136  }
137 
138  if (count_sp)
139  stream.Printf(" strong=%" PRIu64, 1 + count_sp->GetValueAsUnsigned(0));
140 
141  if (weakcount_sp)
142  stream.Printf(" weak=%" PRIu64, 1 + weakcount_sp->GetValueAsUnsigned(0));
143 
144  return true;
145 }
146 
148  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
149  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
150  if (!valobj_sp)
151  return false;
152 
153  ValueObjectSP ptr_sp(
154  valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
155  if (!ptr_sp)
156  return false;
157 
158  ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
159  if (!ptr_sp)
160  return false;
161 
162  if (ptr_sp->GetValueAsUnsigned(0) == 0) {
163  stream.Printf("nullptr");
164  return true;
165  } else {
166  bool print_pointee = false;
167  Status error;
168  ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
169  if (pointee_sp && error.Success()) {
170  if (pointee_sp->DumpPrintableRepresentation(
171  stream, ValueObject::eValueObjectRepresentationStyleSummary,
173  ValueObject::PrintableRepresentationSpecialCases::eDisable,
174  false))
175  print_pointee = true;
176  }
177  if (!print_pointee)
178  stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
179  }
180 
181  return true;
182 }
183 
184 /*
185  (lldb) fr var ibeg --raw --ptr-depth 1
186  (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int,
187  std::__1::basic_string<char, std::__1::char_traits<char>,
188  std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::pair<int,
189  std::__1::basic_string<char, std::__1::char_traits<char>,
190  std::__1::allocator<char> > >, void *> *, long> >) ibeg = {
191  __i_ = {
192  __ptr_ = 0x0000000100103870 {
193  std::__1::__tree_node_base<void *> = {
194  std::__1::__tree_end_node<std::__1::__tree_node_base<void *> *> = {
195  __left_ = 0x0000000000000000
196  }
197  __right_ = 0x0000000000000000
198  __parent_ = 0x00000001001038b0
199  __is_black_ = true
200  }
201  __value_ = {
202  first = 0
203  second = { std::string }
204  */
205 
207  LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
208  : SyntheticChildrenFrontEnd(*valobj_sp), m_pair_ptr(), m_pair_sp() {
209  if (valobj_sp)
210  Update();
211 }
212 
214  m_pair_sp.reset();
215  m_pair_ptr = nullptr;
216 
217  ValueObjectSP valobj_sp = m_backend.GetSP();
218  if (!valobj_sp)
219  return false;
220 
221  TargetSP target_sp(valobj_sp->GetTargetSP());
222 
223  if (!target_sp)
224  return false;
225 
226  if (!valobj_sp)
227  return false;
228 
229  static ConstString g___i_("__i_");
230 
231  // this must be a ValueObject* because it is a child of the ValueObject we
232  // are producing children for it if were a ValueObjectSP, we would end up
233  // with a loop (iterator -> synthetic -> child -> parent == iterator) and
234  // that would in turn leak memory by never allowing the ValueObjects to die
235  // and free their memory
236  m_pair_ptr = valobj_sp
238  ".__i_.__ptr_->__value_", nullptr, nullptr,
240  .DontCheckDotVsArrowSyntax()
241  .SetSyntheticChildrenTraversal(
243  SyntheticChildrenTraversal::None),
244  nullptr)
245  .get();
246 
247  if (!m_pair_ptr) {
248  m_pair_ptr = valobj_sp
250  ".__i_.__ptr_", nullptr, nullptr,
252  .DontCheckDotVsArrowSyntax()
253  .SetSyntheticChildrenTraversal(
255  SyntheticChildrenTraversal::None),
256  nullptr)
257  .get();
258  if (m_pair_ptr) {
259  auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true));
260  if (!__i_) {
261  m_pair_ptr = nullptr;
262  return false;
263  }
264  CompilerType pair_type(
265  __i_->GetCompilerType().GetTypeTemplateArgument(0));
266  std::string name;
267  uint64_t bit_offset_ptr;
268  uint32_t bitfield_bit_size_ptr;
269  bool is_bitfield_ptr;
270  pair_type = pair_type.GetFieldAtIndex(
271  0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
272  if (!pair_type) {
273  m_pair_ptr = nullptr;
274  return false;
275  }
276 
278  m_pair_ptr = nullptr;
279  if (addr && addr != LLDB_INVALID_ADDRESS) {
280  TypeSystemClang *ast_ctx =
281  llvm::dyn_cast_or_null<TypeSystemClang>(pair_type.GetTypeSystem());
282  if (!ast_ctx)
283  return false;
284  CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
285  ConstString(),
286  {{"ptr0",
288  {"ptr1",
290  {"ptr2",
292  {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)},
293  {"payload", pair_type}});
294  llvm::Optional<uint64_t> size = tree_node_type.GetByteSize(nullptr);
295  if (!size)
296  return false;
297  DataBufferSP buffer_sp(new DataBufferHeap(*size, 0));
298  ProcessSP process_sp(target_sp->GetProcessSP());
299  Status error;
300  process_sp->ReadMemory(addr, buffer_sp->GetBytes(),
301  buffer_sp->GetByteSize(), error);
302  if (error.Fail())
303  return false;
304  DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(),
305  process_sp->GetAddressByteSize());
306  auto pair_sp = CreateValueObjectFromData(
307  "pair", extractor, valobj_sp->GetExecutionContextRef(),
308  tree_node_type);
309  if (pair_sp)
310  m_pair_sp = pair_sp->GetChildAtIndex(4, true);
311  }
312  }
313  }
314 
315  return false;
316 }
317 
320  return 2;
321 }
322 
323 lldb::ValueObjectSP
325  size_t idx) {
326  if (m_pair_ptr)
327  return m_pair_ptr->GetChildAtIndex(idx, true);
328  if (m_pair_sp)
329  return m_pair_sp->GetChildAtIndex(idx, true);
330  return lldb::ValueObjectSP();
331 }
332 
335  return true;
336 }
337 
340  if (name == "first")
341  return 0;
342  if (name == "second")
343  return 1;
344  return UINT32_MAX;
345 }
346 
349  // this will be deleted when its parent dies (since it's a child object)
350  // delete m_pair_ptr;
351 }
352 
355  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
356  return (valobj_sp ? new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp)
357  : nullptr);
358 }
359 
360 /*
361  (lldb) fr var ibeg --raw --ptr-depth 1 -T
362  (std::__1::__wrap_iter<int *>) ibeg = {
363  (std::__1::__wrap_iter<int *>::iterator_type) __i = 0x00000001001037a0 {
364  (int) *__i = 1
365  }
366  }
367 */
368 
371  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
372  static ConstString g_item_name;
373  if (!g_item_name)
374  g_item_name.SetCString("__i");
375  return (valobj_sp
376  ? new VectorIteratorSyntheticFrontEnd(valobj_sp, g_item_name)
377  : nullptr);
378 }
379 
381  LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
382  : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr), m_count_sp(),
383  m_weak_count_sp(), m_ptr_size(0), m_byte_order(lldb::eByteOrderInvalid) {
384  if (valobj_sp)
385  Update();
386 }
387 
390  return (m_cntrl ? 1 : 0);
391 }
392 
393 lldb::ValueObjectSP
395  size_t idx) {
396  if (!m_cntrl)
397  return lldb::ValueObjectSP();
398 
399  ValueObjectSP valobj_sp = m_backend.GetSP();
400  if (!valobj_sp)
401  return lldb::ValueObjectSP();
402 
403  if (idx == 0)
404  return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true);
405 
406  if (idx > 2)
407  return lldb::ValueObjectSP();
408 
409  if (idx == 1) {
410  if (!m_count_sp) {
411  ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(
412  ConstString("__shared_owners_"), true));
413  if (!shared_owners_sp)
414  return lldb::ValueObjectSP();
415  uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0);
416  DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
418  "count", data, valobj_sp->GetExecutionContextRef(),
419  shared_owners_sp->GetCompilerType());
420  }
421  return m_count_sp;
422  } else /* if (idx == 2) */
423  {
424  if (!m_weak_count_sp) {
425  ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(
426  ConstString("__shared_weak_owners_"), true));
427  if (!shared_weak_owners_sp)
428  return lldb::ValueObjectSP();
429  uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0);
430  DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
432  "count", data, valobj_sp->GetExecutionContextRef(),
433  shared_weak_owners_sp->GetCompilerType());
434  }
435  return m_weak_count_sp;
436  }
437 }
438 
440  m_count_sp.reset();
441  m_weak_count_sp.reset();
442  m_cntrl = nullptr;
443 
444  ValueObjectSP valobj_sp = m_backend.GetSP();
445  if (!valobj_sp)
446  return false;
447 
448  TargetSP target_sp(valobj_sp->GetTargetSP());
449  if (!target_sp)
450  return false;
451 
452  m_byte_order = target_sp->GetArchitecture().GetByteOrder();
453  m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize();
454 
455  lldb::ValueObjectSP cntrl_sp(
456  valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true));
457 
458  m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular
459  // dependency
460  return false;
461 }
462 
465  return true;
466 }
467 
470  if (name == "__ptr_")
471  return 0;
472  if (name == "count")
473  return 1;
474  if (name == "weak_count")
475  return 2;
476  return UINT32_MAX;
477 }
478 
481 
484  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
485  return (valobj_sp ? new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp)
486  : nullptr);
487 }
488 
490  LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
491  : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() {
492  if (valobj_sp)
493  Update();
494 }
495 
498 
501  CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
502  return (valobj_sp ? new LibcxxUniquePtrSyntheticFrontEnd(valobj_sp)
503  : nullptr);
504 }
505 
508  return (m_compressed_pair_sp ? 1 : 0);
509 }
510 
511 lldb::ValueObjectSP
513  size_t idx) {
515  return lldb::ValueObjectSP();
516 
517  if (idx != 0)
518  return lldb::ValueObjectSP();
519 
520  return m_compressed_pair_sp;
521 }
522 
524  ValueObjectSP valobj_sp = m_backend.GetSP();
525  if (!valobj_sp)
526  return false;
527 
528  ValueObjectSP ptr_sp(
529  valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true));
530  if (!ptr_sp)
531  return false;
532 
534 
535  return false;
536 }
537 
540  return true;
541 }
542 
545  if (name == "__value_")
546  return 0;
547  return UINT32_MAX;
548 }
549 
551  ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
552  if (valobj.IsPointerType()) {
553  uint64_t value = valobj.GetValueAsUnsigned(0);
554  if (!value)
555  return false;
556  stream.Printf("0x%016" PRIx64 " ", value);
557  }
558  return FormatEntity::FormatStringRef("size=${svar%#}", stream, nullptr,
559  nullptr, nullptr, &valobj, false, false);
560 }
561 
562 // the field layout in a libc++ string (cap, side, data or data, size, cap)
567 };
568 
569 /// Determine the size in bytes of \p valobj (a libc++ std::string object) and
570 /// extract its data payload. Return the size + payload pair.
571 static llvm::Optional<std::pair<uint64_t, ValueObjectSP>>
573  ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0}));
574  if (!D)
575  return {};
576 
577  ValueObjectSP layout_decider(
578  D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0})));
579 
580  // this child should exist
581  if (!layout_decider)
582  return {};
583 
584  ConstString g_data_name("__data_");
585  ConstString g_size_name("__size_");
586  bool short_mode = false; // this means the string is in short-mode and the
587  // data is stored inline
588  LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name)
591  uint64_t size_mode_value = 0;
592 
593  if (layout == eLibcxxStringLayoutModeDSC) {
594  ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0}));
595  if (!size_mode)
596  return {};
597 
598  if (size_mode->GetName() != g_size_name) {
599  // we are hitting the padding structure, move along
600  size_mode = D->GetChildAtIndexPath({1, 1, 1});
601  if (!size_mode)
602  return {};
603  }
604 
605  size_mode_value = (size_mode->GetValueAsUnsigned(0));
606  short_mode = ((size_mode_value & 0x80) == 0);
607  } else {
608  ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0}));
609  if (!size_mode)
610  return {};
611 
612  size_mode_value = (size_mode->GetValueAsUnsigned(0));
613  short_mode = ((size_mode_value & 1) == 0);
614  }
615 
616  if (short_mode) {
617  ValueObjectSP s(D->GetChildAtIndex(1, true));
618  if (!s)
619  return {};
620  ValueObjectSP location_sp = s->GetChildAtIndex(
621  (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
622  const uint64_t size = (layout == eLibcxxStringLayoutModeDSC)
623  ? size_mode_value
624  : ((size_mode_value >> 1) % 256);
625 
626  // When the small-string optimization takes place, the data must fit in the
627  // inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's
628  // likely that the string isn't initialized and we're reading garbage.
629  ExecutionContext exe_ctx(location_sp->GetExecutionContextRef());
630  const llvm::Optional<uint64_t> max_bytes =
631  location_sp->GetCompilerType().GetByteSize(
632  exe_ctx.GetBestExecutionContextScope());
633  if (!max_bytes || size > *max_bytes || !location_sp)
634  return {};
635 
636  return std::make_pair(size, location_sp);
637  }
638 
639  ValueObjectSP l(D->GetChildAtIndex(0, true));
640  if (!l)
641  return {};
642  // we can use the layout_decider object as the data pointer
643  ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC)
644  ? layout_decider
645  : l->GetChildAtIndex(2, true);
646  ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
647  const unsigned capacity_index =
648  (layout == eLibcxxStringLayoutModeDSC) ? 2 : 0;
649  ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true));
650  if (!size_vo || !location_sp || !capacity_vo)
651  return {};
652  const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
653  const uint64_t capacity =
654  capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
655  if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET ||
656  capacity < size)
657  return {};
658  return std::make_pair(size, location_sp);
659 }
660 
662  ValueObject &valobj, Stream &stream,
663  const TypeSummaryOptions &summary_options) {
664  auto string_info = ExtractLibcxxStringInfo(valobj);
665  if (!string_info)
666  return false;
667  uint64_t size;
668  ValueObjectSP location_sp;
669  std::tie(size, location_sp) = *string_info;
670 
671  if (size == 0) {
672  stream.Printf("L\"\"");
673  return true;
674  }
675  if (!location_sp)
676  return false;
677 
678 
680  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
681  const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
682  if (size > max_size) {
683  size = max_size;
684  options.SetIsTruncated(true);
685  }
686  }
687 
688  DataExtractor extractor;
689  const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
690  if (bytes_read < size)
691  return false;
692 
693  // std::wstring::size() is measured in 'characters', not bytes
694  TypeSystemClang *ast_context =
696  if (!ast_context)
697  return false;
698 
699  auto wchar_t_size =
700  ast_context->GetBasicType(lldb::eBasicTypeWChar).GetByteSize(nullptr);
701  if (!wchar_t_size)
702  return false;
703 
704  options.SetData(extractor);
705  options.SetStream(&stream);
706  options.SetPrefixToken("L");
707  options.SetQuote('"');
708  options.SetSourceSize(size);
709  options.SetBinaryZeroIsTerminator(false);
710 
711  switch (*wchar_t_size) {
712  case 1:
715  options);
716  break;
717 
718  case 2:
721  options);
722  break;
723 
724  case 4:
727  options);
728  }
729  return false;
730 }
731 
732 template <StringPrinter::StringElementType element_type>
734  const TypeSummaryOptions &summary_options,
735  std::string prefix_token) {
736  auto string_info = ExtractLibcxxStringInfo(valobj);
737  if (!string_info)
738  return false;
739  uint64_t size;
740  ValueObjectSP location_sp;
741  std::tie(size, location_sp) = *string_info;
742 
743  if (size == 0) {
744  stream.Printf("\"\"");
745  return true;
746  }
747 
748  if (!location_sp)
749  return false;
750 
752 
753  if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
754  const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
755  if (size > max_size) {
756  size = max_size;
757  options.SetIsTruncated(true);
758  }
759  }
760 
761  DataExtractor extractor;
762  const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
763  if (bytes_read < size)
764  return false;
765 
766  options.SetData(extractor);
767  options.SetStream(&stream);
768  if (prefix_token.empty())
769  options.SetPrefixToken(nullptr);
770  else
771  options.SetPrefixToken(prefix_token);
772  options.SetQuote('"');
773  options.SetSourceSize(size);
774  options.SetBinaryZeroIsTerminator(false);
775  return StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
776 }
777 
778 template <StringPrinter::StringElementType element_type>
779 static bool formatStringImpl(ValueObject &valobj, Stream &stream,
780  const TypeSummaryOptions &summary_options,
781  std::string prefix_token) {
782  StreamString scratch_stream;
783  const bool success = LibcxxStringSummaryProvider<element_type>(
784  valobj, scratch_stream, summary_options, prefix_token);
785  if (success)
786  stream << scratch_stream.GetData();
787  else
788  stream << "Summary Unavailable";
789  return true;
790 }
791 
793  ValueObject &valobj, Stream &stream,
794  const TypeSummaryOptions &summary_options) {
795  return formatStringImpl<StringPrinter::StringElementType::ASCII>(
796  valobj, stream, summary_options, "");
797 }
798 
800  ValueObject &valobj, Stream &stream,
801  const TypeSummaryOptions &summary_options) {
802  return formatStringImpl<StringPrinter::StringElementType::UTF16>(
803  valobj, stream, summary_options, "u");
804 }
805 
807  ValueObject &valobj, Stream &stream,
808  const TypeSummaryOptions &summary_options) {
809  return formatStringImpl<StringPrinter::StringElementType::UTF32>(
810  valobj, stream, summary_options, "U");
811 }
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:341
bool LibcxxUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:147
SyntheticChildrenFrontEnd * LibCxxVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxx.cpp:370
An data extractor class.
Definition: DataExtractor.h:46
A class that represents a running process on the host machine.
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
virtual lldb::ValueObjectSP GetChildMemberWithName(ConstString name, bool can_create)
A TypeSystem implementation based on Clang.
bool LibcxxStringSummaryProviderUTF16(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition: LibCxx.cpp:799
bool LibcxxWStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:661
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: LibCxx.cpp:324
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: LibCxx.cpp:394
lldb::TargetSP GetTargetSP() const
Definition: ValueObject.h:335
LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: LibCxx.cpp:490
lldb::TypeSummaryCapping GetCapping() const
Definition: TypeSummary.cpp:34
virtual bool IsPointerType()
bool LibcxxStringSummaryProviderUTF32(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition: LibCxx.cpp:806
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
bool LibcxxOptionalSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:34
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::ValueObjectSP GetValueForExpressionPath(llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop=nullptr, ExpressionPathEndResultType *final_value_type=nullptr, const GetValueForExpressionPathOptions &options=GetValueForExpressionPathOptions::DefaultOptions(), ExpressionPathAftermath *final_task_on_target=nullptr)
size_t GetIndexOfChildWithName(ConstString name) override
Definition: LibCxx.cpp:544
SyntheticChildrenFrontEnd * LibCxxMapIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxx.cpp:354
#define LLDB_INVALID_OFFSET
Definition: lldb-defines.h:96
CompilerType GetBasicType(lldb::BasicType type)
#define UINT32_MAX
Definition: lldb-defines.h:31
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
lldb::ValueObjectSP GetValueOfLibCXXCompressedPair(ValueObject &pair)
bool LibcxxContainerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:550
static llvm::raw_ostream & error(Stream &strm)
lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
SyntheticChildrenFrontEnd * LibcxxUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxx.cpp:500
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Definition: LibCxx.cpp:512
FileSpec file
The source file, possibly mapped by the target.source-map setting.
Definition: LineEntry.h:140
uint32_t line
The source line number, or zero if there is no line number information.
Definition: LineEntry.h:143
A plug-in interface definition class for debugging a process.
Definition: Process.h:362
LibCppStdFunctionCallableInfo FindLibCppStdFunctionCallableInfo(lldb::ValueObjectSP &valobj_sp)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
bool Success() const
Test for success condition.
Definition: Status.cpp:288
static bool formatStringImpl(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token)
Definition: LibCxx.cpp:779
LibcxxStringLayoutMode
Definition: LibCxx.cpp:563
bool LibcxxStringSummaryProviderASCII(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition: LibCxx.cpp:792
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
lldb::ValueObjectSP GetChildAtIndexPath(llvm::ArrayRef< size_t > idxs, size_t *index_of_error=nullptr)
SyntheticChildrenFrontEnd * LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition: LibCxx.cpp:483
static bool FormatStringRef(const llvm::StringRef &format, Stream &s, const SymbolContext *sc, const ExecutionContext *exe_ctx, const Address *addr, ValueObject *valobj, bool function_changed, bool initial_function)
size_t GetIndexOfChildWithName(ConstString name) override
Definition: LibCxx.cpp:339
LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: LibCxx.cpp:381
A uniqued constant string class.
Definition: ConstString.h:40
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:246
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
Definition: SBAddress.h:15
ConstString GetName() const
Definition: Symbol.cpp:499
Represents a generic type in a programming language.
Definition: CompilerType.h:33
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:539
bool LibcxxFunctionSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:56
static llvm::Optional< std::pair< uint64_t, ValueObjectSP > > ExtractLibcxxStringInfo(ValueObject &valobj)
Determine the size in bytes of valobj (a libc++ std::string object) and extract its data payload...
Definition: LibCxx.cpp:572
LibCxxMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition: LibCxx.cpp:207
bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token)
Definition: LibCxx.cpp:733
bool LibcxxSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition: LibCxx.cpp:104
static TypeSystemClang * GetScratch(Target &target, bool create_on_demand=true)
virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create)
virtual lldb::ValueObjectSP GetNonSyntheticValue()
static bool ReadBufferAndDumpToStream(const ReadBufferAndDumpToStreamOptions &options)
size_t GetIndexOfChildWithName(ConstString name) override
Definition: LibCxx.cpp:469
CompilerType CreateStructForIdentifier(ConstString type_name, const std::initializer_list< std::pair< const char *, CompilerType >> &type_fields, bool packed=false)
An error handling class.
Definition: Status.h:44
void SetCString(const char *cstr)
Set the C string value.