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"
18#include "lldb/Target/Target.h"
21#include "lldb/Utility/Endian.h"
22#include "lldb/Utility/Status.h"
23#include "lldb/Utility/Stream.h"
26
32#include "lldb/lldb-forward.h"
33#include <optional>
34#include <tuple>
35
36using namespace lldb;
37using namespace lldb_private;
38using namespace lldb_private::formatters;
39
40static void consumeInlineNamespace(llvm::StringRef &name) {
41 // Delete past an inline namespace, if any: __[a-zA-Z0-9_]+::
42 auto scratch = name;
43 if (scratch.consume_front("__") &&
44 std::isalnum(static_cast<unsigned char>(scratch[0]))) {
45 scratch = scratch.drop_while(
46 [](char c) { return std::isalnum(static_cast<unsigned char>(c)); });
47 if (scratch.consume_front("::")) {
48 // Successfully consumed a namespace.
49 name = scratch;
50 }
51 }
52}
53
55 llvm::StringRef type) {
56 llvm::StringRef name = type_name.GetStringRef();
57 // The type name may be prefixed with `std::__<inline-namespace>::`.
58 if (name.consume_front("std::"))
60 return name.consume_front(type) && name.starts_with("<");
61}
62
64 ValueObject &obj, llvm::ArrayRef<ConstString> alternative_names) {
65 for (ConstString name : alternative_names) {
67
68 if (child_sp)
69 return child_sp;
70 }
71 return {};
72}
73
76 ValueObject &pair) {
77 ValueObjectSP value;
78 ValueObjectSP first_child = pair.GetChildAtIndex(0);
79 if (first_child)
80 value = first_child->GetChildMemberWithName("__value_");
81 if (!value) {
82 // pre-c88580c member name
83 value = pair.GetChildMemberWithName("__first_");
84 }
85 return value;
86}
87
90 ValueObject &pair) {
91 ValueObjectSP value;
92 if (pair.GetNumChildrenIgnoringErrors() > 1) {
93 ValueObjectSP second_child = pair.GetChildAtIndex(1);
94 if (second_child) {
95 value = second_child->GetChildMemberWithName("__value_");
96 }
97 }
98 if (!value) {
99 // pre-c88580c member name
100 value = pair.GetChildMemberWithName("__second_");
101 }
102 return value;
103}
104
105std::pair<lldb::ValueObjectSP, bool>
107 ValueObject &obj, size_t anon_struct_idx, llvm::StringRef child_name,
108 llvm::StringRef compressed_pair_name) {
109 auto is_old_compressed_pair = [](ValueObject &pair_obj) -> bool {
110 return isStdTemplate(pair_obj.GetTypeName(), "__compressed_pair");
111 };
112
113 // Try searching the child member in an anonymous structure first.
114 if (auto unwrapped = obj.GetChildAtIndex(anon_struct_idx)) {
115 ValueObjectSP node_sp(obj.GetChildMemberWithName(child_name));
116 if (node_sp)
117 return {node_sp, is_old_compressed_pair(*node_sp)};
118 }
119
120 // Older versions of libc++ don't wrap the children in anonymous structures.
121 // Try that instead.
122 ValueObjectSP node_sp(obj.GetChildMemberWithName(child_name));
123 if (node_sp)
124 return {node_sp, is_old_compressed_pair(*node_sp)};
125
126 // Try the even older __compressed_pair layout.
127
128 assert(!compressed_pair_name.empty());
129
130 node_sp = obj.GetChildMemberWithName(compressed_pair_name);
131
132 // Unrecognized layout (possibly older than LLDB supports).
133 if (!node_sp)
134 return {nullptr, false};
135
136 // Expected old compressed_pair layout, but got something else.
137 if (!is_old_compressed_pair(*node_sp))
138 return {nullptr, false};
139
140 return {node_sp, true};
141}
142
144 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
145
146 ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
147
148 if (!valobj_sp)
149 return false;
150
151 ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
152 Process *process = exe_ctx.GetProcessPtr();
153
154 if (process == nullptr)
155 return false;
156
157 CPPLanguageRuntime *cpp_runtime = CPPLanguageRuntime::Get(*process);
158
159 if (!cpp_runtime)
160 return false;
161
163 cpp_runtime->FindLibCppStdFunctionCallableInfo(valobj_sp);
164
165 switch (callable_info.callable_case) {
167 stream.Printf(" __f_ = %" PRIu64, callable_info.member_f_pointer_value);
168 return false;
169 break;
171 stream.Printf(
172 " Lambda in File %s at Line %u",
174 callable_info.callable_line_entry.line);
175 break;
177 stream.Printf(
178 " Function in File %s at Line %u",
180 callable_info.callable_line_entry.line);
181 break;
183 stream.Printf(" Function = %s ",
184 callable_info.callable_symbol.GetName().GetCString());
185 break;
186 }
187
188 return true;
189}
190
192 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
193 ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
194 if (!valobj_sp)
195 return false;
196
197 ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("__ptr_"));
198 ValueObjectSP ctrl_sp(valobj_sp->GetChildMemberWithName("__cntrl_"));
199 if (!ctrl_sp || !ptr_sp)
200 return false;
201
202 DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);
203
204 bool success;
205 uint64_t ctrl_addr = ctrl_sp->GetValueAsUnsigned(0, &success);
206 // Empty control field. We're done.
207 if (!success || ctrl_addr == 0)
208 return true;
209
210 if (auto count_sp = ctrl_sp->GetChildMemberWithName("__shared_owners_")) {
211 bool success;
212 uint64_t count = count_sp->GetValueAsUnsigned(0, &success);
213 if (!success)
214 return false;
215
216 // std::shared_ptr releases the underlying resource when the
217 // __shared_owners_ count hits -1. So `__shared_owners_ == 0` indicates 1
218 // owner. Hence add +1 here.
219 stream.Printf(" strong=%" PRIu64, count + 1);
220 }
221
222 if (auto weak_count_sp =
223 ctrl_sp->GetChildMemberWithName("__shared_weak_owners_")) {
224 bool success;
225 uint64_t count = weak_count_sp->GetValueAsUnsigned(0, &success);
226 if (!success)
227 return false;
228
229 // Unlike __shared_owners_, __shared_weak_owners_ indicates the exact
230 // std::weak_ptr reference count.
231 stream.Printf(" weak=%" PRIu64, count);
232 }
233
234 return true;
235}
236
238 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
239 ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
240 if (!valobj_sp)
241 return false;
242
243 auto [ptr_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
244 *valobj_sp, /*anon_struct_idx=*/0, "__ptr_", "__ptr_");
245 if (!ptr_sp)
246 return false;
247
248 if (is_compressed_pair)
249 ptr_sp = GetFirstValueOfLibCXXCompressedPair(*ptr_sp);
250
251 if (!ptr_sp)
252 return false;
253
254 DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);
255
256 return true;
257}
258
259/*
260 (lldb) fr var ibeg --raw --ptr-depth 1 -T
261 (std::__1::__wrap_iter<int *>) ibeg = {
262 (std::__1::__wrap_iter<int *>::iterator_type) __i = 0x00000001001037a0 {
263 (int) *__i = 1
264 }
265 }
266*/
267
271 return (valobj_sp ? new VectorIteratorSyntheticFrontEnd(
272 valobj_sp, {ConstString("__i_"), ConstString("__i")})
273 : nullptr);
274}
275
283
284llvm::Expected<uint32_t> lldb_private::formatters::
286 return (m_cntrl ? 1 : 0);
287}
288
291 uint32_t idx) {
292 if (!m_cntrl || !m_ptr_obj)
293 return lldb::ValueObjectSP();
294
295 ValueObjectSP valobj_sp = m_backend.GetSP();
296 if (!valobj_sp)
297 return lldb::ValueObjectSP();
298
299 if (idx == 0)
300 return m_ptr_obj->GetSP();
301
302 if (idx == 1) {
303 Status status;
304 ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
305 if (status.Success())
306 return value_sp;
307 }
308
309 return lldb::ValueObjectSP();
310}
311
314 m_cntrl = nullptr;
315 m_ptr_obj = nullptr;
316
317 ValueObjectSP valobj_sp = m_backend.GetSP();
318 if (!valobj_sp)
320
321 TargetSP target_sp(valobj_sp->GetTargetSP());
322 if (!target_sp)
324
325 auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("__ptr_");
326 if (!ptr_obj_sp)
328
329 auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
330 if (!cast_ptr_sp)
332
333 m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();
334
335 lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName("__cntrl_"));
336
337 m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular
338 // dependency
340}
341
342llvm::Expected<size_t>
345 if (name == "pointer")
346 return 0;
347
348 if (name == "object" || name == "$$dereference$$")
349 return 1;
350
351 return llvm::createStringError("Type has no child named '%s'",
352 name.AsCString());
353}
354
357
364
371
374
381
382llvm::Expected<uint32_t> lldb_private::formatters::
384 if (m_value_ptr_sp)
385 return m_deleter_sp ? 2 : 1;
386 return 0;
387}
388
391 uint32_t idx) {
392 if (!m_value_ptr_sp)
393 return lldb::ValueObjectSP();
394
395 if (idx == 0)
396 return m_value_ptr_sp;
397
398 if (idx == 1)
399 return m_deleter_sp;
400
401 if (idx == 2) {
402 Status status;
403 auto value_sp = m_value_ptr_sp->Dereference(status);
404 if (status.Success()) {
405 return value_sp;
406 }
407 }
408
409 return lldb::ValueObjectSP();
410}
411
414 ValueObjectSP valobj_sp = m_backend.GetSP();
415 if (!valobj_sp)
417
418 auto [ptr_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
419 *valobj_sp, /*anon_struct_idx=*/0, "__ptr_", "__ptr_");
420 if (!ptr_sp)
422
423 // Retrieve the actual pointer and the deleter, and clone them to give them
424 // user-friendly names.
425 if (is_compressed_pair) {
426 if (ValueObjectSP value_pointer_sp =
428 m_value_ptr_sp = value_pointer_sp->Clone(ConstString("pointer"));
429
430 if (ValueObjectSP deleter_sp =
432 m_deleter_sp = deleter_sp->Clone(ConstString("deleter"));
433 } else {
434 m_value_ptr_sp = ptr_sp->Clone(ConstString("pointer"));
435
436 if (ValueObjectSP deleter_sp =
437 valobj_sp->GetChildMemberWithName("__deleter_"))
438 if (deleter_sp->GetNumChildrenIgnoringErrors() > 0)
439 m_deleter_sp = deleter_sp->Clone(ConstString("deleter"));
440 }
441
443}
444
445llvm::Expected<size_t>
448 if (name == "pointer")
449 return 0;
450 if (name == "deleter")
451 return 1;
452 if (name == "obj" || name == "object" || name == "$$dereference$$")
453 return 2;
454 return llvm::createStringError("Type has no child named '%s'",
455 name.AsCString());
456}
457
458/// The field layout in a libc++ string (cap, side, data or data, size, cap).
459namespace {
460enum class StringLayout { CSD, DSC };
461}
462
464 auto [valobj_r_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
465 valobj, /*anon_struct_idx=*/0, "__rep_", "__r_");
466 if (!valobj_r_sp)
467 return nullptr;
468
469 if (is_compressed_pair)
470 return GetFirstValueOfLibCXXCompressedPair(*valobj_r_sp);
471
472 return valobj_r_sp;
473}
474
475/// Determine the size in bytes of \p valobj (a libc++ std::string object) and
476/// extract its data payload. Return the size + payload pair.
477// TODO: Support big-endian architectures.
478static std::optional<std::pair<uint64_t, ValueObjectSP>>
480 ValueObjectSP valobj_rep_sp = ExtractLibCxxStringData(valobj);
481 if (!valobj_rep_sp || !valobj_rep_sp->GetError().Success())
482 return {};
483
484 ValueObjectSP l = valobj_rep_sp->GetChildMemberWithName("__l");
485 if (!l)
486 return {};
487
488 auto index_or_err = l->GetIndexOfChildWithName("__data_");
489 if (!index_or_err) {
490 LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), index_or_err.takeError(),
491 "{0}");
492 return {};
493 }
494
495 StringLayout layout =
496 *index_or_err == 0 ? StringLayout::DSC : StringLayout::CSD;
497
498 bool short_mode = false; // this means the string is in short-mode and the
499 // data is stored inline
500 bool using_bitmasks = true; // Whether the class uses bitmasks for the mode
501 // flag (pre-D123580).
502 uint64_t size;
503 uint64_t size_mode_value = 0;
504
505 ValueObjectSP short_sp = valobj_rep_sp->GetChildMemberWithName("__s");
506 if (!short_sp)
507 return {};
508
509 ValueObjectSP is_long = short_sp->GetChildMemberWithName("__is_long_");
510 ValueObjectSP size_sp = short_sp->GetChildMemberWithName("__size_");
511 if (!size_sp)
512 return {};
513
514 if (is_long) {
515 using_bitmasks = false;
516 short_mode = !is_long->GetValueAsUnsigned(/*fail_value=*/0);
517 size = size_sp->GetValueAsUnsigned(/*fail_value=*/0);
518 } else {
519 // The string mode is encoded in the size field.
520 size_mode_value = size_sp->GetValueAsUnsigned(0);
521 uint8_t mode_mask = layout == StringLayout::DSC ? 0x80 : 1;
522 short_mode = (size_mode_value & mode_mask) == 0;
523 }
524
525 if (short_mode) {
526 ValueObjectSP location_sp = short_sp->GetChildMemberWithName("__data_");
527 if (using_bitmasks)
528 size = (layout == StringLayout::DSC) ? size_mode_value
529 : ((size_mode_value >> 1) % 256);
530
531 if (!location_sp)
532 return {};
533
534 // When the small-string optimization takes place, the data must fit in the
535 // inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's
536 // likely that the string isn't initialized and we're reading garbage.
537 ExecutionContext exe_ctx(location_sp->GetExecutionContextRef());
538 const std::optional<uint64_t> max_bytes =
539 llvm::expectedToOptional(location_sp->GetCompilerType().GetByteSize(
541 if (!max_bytes || size > *max_bytes)
542 return {};
543
544 return std::make_pair(size, location_sp);
545 }
546
547 // we can use the layout_decider object as the data pointer
548 ValueObjectSP location_sp = l->GetChildMemberWithName("__data_");
549 ValueObjectSP size_vo = l->GetChildMemberWithName("__size_");
550 ValueObjectSP capacity_vo = l->GetChildMemberWithName("__cap_");
551 if (!size_vo || !location_sp || !capacity_vo)
552 return {};
553 size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
554 uint64_t capacity = capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
555 if (!using_bitmasks && layout == StringLayout::CSD)
556 capacity *= 2;
557 if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET ||
558 capacity < size)
559 return {};
560 return std::make_pair(size, location_sp);
561}
562
564 ValueObject &valobj, Stream &stream,
565 const TypeSummaryOptions &summary_options) {
566 auto string_info = ExtractLibcxxStringInfo(valobj);
567 if (!string_info)
568 return false;
569 uint64_t size;
570 ValueObjectSP location_sp;
571 std::tie(size, location_sp) = *string_info;
572
573 auto wchar_t_size = GetWCharByteSize(valobj);
574 if (!wchar_t_size)
575 return false;
576
577 switch (*wchar_t_size) {
578 case 1:
580 stream, summary_options, location_sp, size, "L");
581 case 2:
583 stream, summary_options, location_sp, size, "L");
584 case 4:
586 stream, summary_options, location_sp, size, "L");
587 }
588 return false;
589}
590
591template <StringPrinter::StringElementType element_type>
592static bool
594 const TypeSummaryOptions &summary_options,
595 std::string prefix_token) {
596 auto string_info = ExtractLibcxxStringInfo(valobj);
597 if (!string_info)
598 return false;
599 uint64_t size;
600 ValueObjectSP location_sp;
601 std::tie(size, location_sp) = *string_info;
602
604 stream, summary_options, location_sp, size, prefix_token);
605}
606template <StringPrinter::StringElementType element_type>
607static bool formatStringImpl(ValueObject &valobj, Stream &stream,
608 const TypeSummaryOptions &summary_options,
609 std::string prefix_token) {
610 StreamString scratch_stream;
612 valobj, scratch_stream, summary_options, prefix_token);
613 if (success)
614 stream << scratch_stream.GetData();
615 else
616 stream << "Summary Unavailable";
617 return true;
618}
619
621 ValueObject &valobj, Stream &stream,
622 const TypeSummaryOptions &summary_options) {
624 valobj, stream, summary_options, "");
625}
626
628 ValueObject &valobj, Stream &stream,
629 const TypeSummaryOptions &summary_options) {
631 valobj, stream, summary_options, "u");
632}
633
635 ValueObject &valobj, Stream &stream,
636 const TypeSummaryOptions &summary_options) {
638 valobj, stream, summary_options, "U");
639}
640
641static std::tuple<bool, ValueObjectSP, size_t>
643 auto dataobj = GetChildMemberWithName(
644 valobj, {ConstString("__data_"), ConstString("__data")});
645 auto sizeobj = GetChildMemberWithName(
646 valobj, {ConstString("__size_"), ConstString("__size")});
647 if (!dataobj || !sizeobj)
648 return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
649
650 if (!dataobj->GetError().Success() || !sizeobj->GetError().Success())
651 return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
652
653 bool success{false};
654 uint64_t size = sizeobj->GetValueAsUnsigned(0, &success);
655 if (!success)
656 return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
657
658 return std::make_tuple(true,dataobj,size);
659}
660
661template <StringPrinter::StringElementType element_type>
662static bool formatStringViewImpl(ValueObject &valobj, Stream &stream,
663 const TypeSummaryOptions &summary_options,
664 std::string prefix_token) {
665
666 bool success;
667 ValueObjectSP dataobj;
668 size_t size;
669 std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
670
671 if (!success) {
672 stream << "Summary Unavailable";
673 return true;
674 }
675
676 return StringBufferSummaryProvider<element_type>(stream, summary_options,
677 dataobj, size, prefix_token);
678}
679
681 ValueObject &valobj, Stream &stream,
682 const TypeSummaryOptions &summary_options) {
684 valobj, stream, summary_options, "");
685}
686
688 ValueObject &valobj, Stream &stream,
689 const TypeSummaryOptions &summary_options) {
691 valobj, stream, summary_options, "u");
692}
693
695 ValueObject &valobj, Stream &stream,
696 const TypeSummaryOptions &summary_options) {
698 valobj, stream, summary_options, "U");
699}
700
702 ValueObject &valobj, Stream &stream,
703 const TypeSummaryOptions &summary_options) {
704
705 bool success;
706 ValueObjectSP dataobj;
707 size_t size;
708 std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
709
710 if (!success) {
711 stream << "Summary Unavailable";
712 return true;
713 }
714
715 auto wchar_t_size = GetWCharByteSize(valobj);
716 if (!wchar_t_size)
717 return false;
718
719 switch (*wchar_t_size) {
720 case 1:
722 stream, summary_options, dataobj, size, "L");
723 case 2:
725 stream, summary_options, dataobj, size, "L");
726 case 4:
728 stream, summary_options, dataobj, size, "L");
729 }
730 return false;
731}
732
733static bool
735 const TypeSummaryOptions &options,
736 const char *fmt) {
737 ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__d_");
738 if (!ptr_sp)
739 return false;
740 ptr_sp = ptr_sp->GetChildMemberWithName("__rep_");
741 if (!ptr_sp)
742 return false;
743
744#ifndef _WIN32
745 // The date time in the chrono library is valid in the range
746 // [-32767-01-01T00:00:00Z, 32767-12-31T23:59:59Z]. A 64-bit time_t has a
747 // larger range, the function strftime is not able to format the entire range
748 // of time_t. The exact point has not been investigated; it's limited to
749 // chrono's range.
750 const std::time_t chrono_timestamp_min =
751 -1'096'193'779'200; // -32767-01-01T00:00:00Z
752 const std::time_t chrono_timestamp_max =
753 971'890'963'199; // 32767-12-31T23:59:59Z
754#else
755 const std::time_t chrono_timestamp_min = -43'200; // 1969-12-31T12:00:00Z
756 const std::time_t chrono_timestamp_max =
757 32'536'850'399; // 3001-01-19T21:59:59
758#endif
759
760 const std::time_t seconds = ptr_sp->GetValueAsSigned(0);
761 if (seconds < chrono_timestamp_min || seconds > chrono_timestamp_max)
762 stream.Printf("timestamp=%" PRId64 " s", static_cast<int64_t>(seconds));
763 else {
764 std::array<char, 128> str;
765 std::size_t size =
766 std::strftime(str.data(), str.size(), fmt, gmtime(&seconds));
767 if (size == 0)
768 return false;
769
770 stream.Printf("date/time=%s timestamp=%" PRId64 " s", str.data(),
771 static_cast<int64_t>(seconds));
772 }
773
774 return true;
775}
776
778 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
779 return LibcxxChronoTimePointSecondsSummaryProvider(valobj, stream, options,
780 "%FT%H:%M:%SZ");
781}
782
784 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
785 return LibcxxChronoTimePointSecondsSummaryProvider(valobj, stream, options,
786 "%FT%H:%M:%S");
787}
788
789static bool
791 const TypeSummaryOptions &options,
792 const char *fmt) {
793 ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__d_");
794 if (!ptr_sp)
795 return false;
796 ptr_sp = ptr_sp->GetChildMemberWithName("__rep_");
797 if (!ptr_sp)
798 return false;
799
800#ifndef _WIN32
801 // The date time in the chrono library is valid in the range
802 // [-32767-01-01Z, 32767-12-31Z]. A 32-bit time_t has a larger range, the
803 // function strftime is not able to format the entire range of time_t. The
804 // exact point has not been investigated; it's limited to chrono's range.
805 const int chrono_timestamp_min = -12'687'428; // -32767-01-01Z
806 const int chrono_timestamp_max = 11'248'737; // 32767-12-31Z
807#else
808 const int chrono_timestamp_min = 0; // 1970-01-01Z
809 const int chrono_timestamp_max = 376'583; // 3001-01-19Z
810#endif
811
812 const int days = ptr_sp->GetValueAsSigned(0);
813 if (days < chrono_timestamp_min || days > chrono_timestamp_max)
814 stream.Printf("timestamp=%d days", days);
815
816 else {
817 const std::time_t seconds = std::time_t(86400) * days;
818
819 std::array<char, 128> str;
820 std::size_t size =
821 std::strftime(str.data(), str.size(), fmt, gmtime(&seconds));
822 if (size == 0)
823 return false;
824
825 stream.Printf("date=%s timestamp=%d days", str.data(), days);
826 }
827
828 return true;
829}
830
832 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
833 return LibcxxChronoTimepointDaysSummaryProvider(valobj, stream, options,
834 "%FZ");
835}
836
838 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
839 return LibcxxChronoTimepointDaysSummaryProvider(valobj, stream, options,
840 "%F");
841}
842
844 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
845 // FIXME: These are the names used in the C++20 ostream operator. Since LLVM
846 // uses C++17 it's not possible to use the ostream operator directly.
847 static const std::array<std::string_view, 12> months = {
848 "January", "February", "March", "April", "May", "June",
849 "July", "August", "September", "October", "November", "December"};
850
851 ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__m_");
852 if (!ptr_sp)
853 return false;
854
855 const unsigned month = ptr_sp->GetValueAsUnsigned(0);
856 if (month >= 1 && month <= 12)
857 stream << "month=" << months[month - 1];
858 else
859 stream.Printf("month=%u", month);
860
861 return true;
862}
863
865 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
866 // FIXME: These are the names used in the C++20 ostream operator. Since LLVM
867 // uses C++17 it's not possible to use the ostream operator directly.
868 static const std::array<std::string_view, 7> weekdays = {
869 "Sunday", "Monday", "Tuesday", "Wednesday",
870 "Thursday", "Friday", "Saturday"};
871
872 ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__wd_");
873 if (!ptr_sp)
874 return false;
875
876 const unsigned weekday = ptr_sp->GetValueAsUnsigned(0);
877 if (weekday < 7)
878 stream << "weekday=" << weekdays[weekday];
879 else
880 stream.Printf("weekday=%u", weekday);
881
882 return true;
883}
884
886 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
887 ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__y_");
888 if (!ptr_sp)
889 return false;
890 ptr_sp = ptr_sp->GetChildMemberWithName("__y_");
891 if (!ptr_sp)
892 return false;
893 int year = ptr_sp->GetValueAsSigned(0);
894
895 ptr_sp = valobj.GetChildMemberWithName("__m_");
896 if (!ptr_sp)
897 return false;
898 ptr_sp = ptr_sp->GetChildMemberWithName("__m_");
899 if (!ptr_sp)
900 return false;
901 const unsigned month = ptr_sp->GetValueAsUnsigned(0);
902
903 ptr_sp = valobj.GetChildMemberWithName("__d_");
904 if (!ptr_sp)
905 return false;
906 ptr_sp = ptr_sp->GetChildMemberWithName("__d_");
907 if (!ptr_sp)
908 return false;
909 const unsigned day = ptr_sp->GetValueAsUnsigned(0);
910
911 stream << "date=";
912 if (year < 0) {
913 stream << '-';
914 year = -year;
915 }
916 stream.Printf("%04d-%02u-%02u", year, month, day);
917
918 return true;
919}
static bool LibcxxChronoTimepointDaysSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options, const char *fmt)
Definition LibCxx.cpp:790
static ValueObjectSP ExtractLibCxxStringData(ValueObject &valobj)
Definition LibCxx.cpp:463
static bool formatStringImpl(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token)
Definition LibCxx.cpp:607
static std::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:479
static bool formatStringViewImpl(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token)
Definition LibCxx.cpp:662
static std::tuple< bool, ValueObjectSP, size_t > LibcxxExtractStringViewData(ValueObject &valobj)
Definition LibCxx.cpp:642
static bool LibcxxChronoTimePointSecondsSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options, const char *fmt)
Definition LibCxx.cpp:734
static bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options, std::string prefix_token)
Definition LibCxx.cpp:593
static void consumeInlineNamespace(llvm::StringRef &name)
Definition LibCxx.cpp:40
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:392
LibCppStdFunctionCallableInfo FindLibCppStdFunctionCallableInfo(lldb::ValueObjectSP &valobj_sp)
static CPPLanguageRuntime * Get(Process &process)
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
Process * GetProcessPtr() const
Returns a pointer to the process object.
const ConstString & GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:251
A plug-in interface definition class for debugging a process.
Definition Process.h:357
An error handling class.
Definition Status.h:118
bool Success() const
Test for success condition.
Definition Status.cpp:304
const char * GetData() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
ConstString GetName() const
Definition Symbol.cpp:511
SyntheticChildrenFrontEnd(ValueObject &backend)
virtual lldb::ValueObjectSP GetChildAtIndex(uint32_t idx, bool can_create=true)
virtual lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, bool can_create=true)
virtual lldb::ValueObjectSP GetNonSyntheticValue()
uint32_t GetNumChildrenIgnoringErrors(uint32_t max=UINT32_MAX)
Like GetNumChildren but returns 0 on error.
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
Definition LibCxx.cpp:290
llvm::Expected< uint32_t > CalculateNumChildren() override
Definition LibCxx.cpp:285
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Definition LibCxx.cpp:344
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
Definition LibCxx.cpp:313
LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition LibCxx.cpp:277
llvm::Expected< uint32_t > CalculateNumChildren() override
Definition LibCxx.cpp:383
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
Definition LibCxx.cpp:413
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
Definition LibCxx.cpp:447
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
Definition LibCxx.cpp:390
LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
Definition LibCxx.cpp:366
#define LLDB_INVALID_OFFSET
lldb::ValueObjectSP GetChildMemberWithName(ValueObject &obj, llvm::ArrayRef< ConstString > alternative_names)
Find a child member of obj_sp, trying all alternative names in order.
Definition LibCxx.cpp:63
bool LibcxxChronoSysSecondsSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:777
bool LibcxxChronoMonthSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:843
SyntheticChildrenFrontEnd * LibcxxUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition LibCxx.cpp:376
bool LibcxxUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:237
lldb::ValueObjectSP GetDesugaredSmartPointerValue(ValueObject &ptr, ValueObject &container)
Return the ValueObjectSP of the underlying pointer member whose type is a desugared 'std::shared_ptr:...
Definition Generic.cpp:13
bool LibcxxSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:191
bool LibcxxStringViewSummaryProviderASCII(ValueObject &valueObj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition LibCxx.cpp:680
bool LibcxxStringViewSummaryProviderUTF16(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition LibCxx.cpp:687
std::optional< uint64_t > GetWCharByteSize(ValueObject &valobj)
SyntheticChildrenFrontEnd * LibCxxVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition LibCxx.cpp:269
bool LibcxxStringViewSummaryProviderUTF32(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition LibCxx.cpp:694
bool StringBufferSummaryProvider(Stream &stream, const TypeSummaryOptions &summary_options, lldb::ValueObjectSP location_sp, uint64_t size, std::string prefix_token)
Print a summary for a string buffer to stream.
bool LibcxxChronoYearMonthDaySummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:885
bool LibcxxWStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:563
bool LibcxxStringSummaryProviderASCII(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition LibCxx.cpp:620
bool LibcxxChronoLocalSecondsSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:783
bool LibcxxWStringViewSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:701
bool LibcxxChronoWeekdaySummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:864
bool isStdTemplate(ConstString type_name, llvm::StringRef type)
Definition LibCxx.cpp:54
lldb::ValueObjectSP GetFirstValueOfLibCXXCompressedPair(ValueObject &pair)
Definition LibCxx.cpp:75
bool LibcxxStringSummaryProviderUTF16(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition LibCxx.cpp:627
bool LibcxxFunctionSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:143
bool LibcxxStringSummaryProviderUTF32(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options)
Definition LibCxx.cpp:634
bool LibcxxChronoLocalDaysSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:837
lldb::ValueObjectSP GetSecondValueOfLibCXXCompressedPair(ValueObject &pair)
Definition LibCxx.cpp:89
std::pair< lldb::ValueObjectSP, bool > GetValueOrOldCompressedPair(ValueObject &obj, size_t anon_struct_idx, llvm::StringRef child_name, llvm::StringRef compressed_pair_name)
Returns the ValueObjectSP of the child of obj.
Definition LibCxx.cpp:106
SyntheticChildrenFrontEnd * LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP)
Definition LibCxx.cpp:359
bool LibcxxChronoSysDaysSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
Definition LibCxx.cpp:831
void DumpCxxSmartPtrPointerSummary(Stream &stream, ValueObject &ptr, const TypeSummaryOptions &options)
Prints the summary for the pointer value of a C++ std::unique_ptr/stdshared_ptr/stdweak_ptr.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Target > TargetSP
uint32_t line
The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line number information.
Definition LineEntry.h:147
const FileSpec & GetFile() const
Helper to access the file.
Definition LineEntry.h:134