Skip to content

Commit bfd12f3

Browse files
authored
[lldb][libc++] Adds system_clock data formatters. (#78609)
1 parent bcfdab8 commit bfd12f3

File tree

5 files changed

+252
-2
lines changed

5 files changed

+252
-2
lines changed

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,31 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
10321032
TypeSummaryImplSP(new StringSummaryFormat(
10331033
eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));
10341034

1035+
// Chrono time point types
1036+
1037+
AddCXXSummary(cpp_category_sp,
1038+
lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider,
1039+
"libc++ std::chrono::sys_seconds summary provider",
1040+
"^std::__[[:alnum:]]+::chrono::time_point<"
1041+
"std::__[[:alnum:]]+::chrono::system_clock, "
1042+
"std::__[[:alnum:]]+::chrono::duration<long long, "
1043+
"std::__[[:alnum:]]+::ratio<1, 1> "
1044+
"> >$",
1045+
eTypeOptionHideChildren | eTypeOptionHideValue |
1046+
eTypeOptionCascade,
1047+
true);
1048+
AddCXXSummary(cpp_category_sp,
1049+
lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider,
1050+
"libc++ std::chrono::sys_seconds summary provider",
1051+
"^std::__[[:alnum:]]+::chrono::time_point<"
1052+
"std::__[[:alnum:]]+::chrono::system_clock, "
1053+
"std::__[[:alnum:]]+::chrono::duration<int, "
1054+
"std::__[[:alnum:]]+::ratio<86400, 1> "
1055+
"> >$",
1056+
eTypeOptionHideChildren | eTypeOptionHideValue |
1057+
eTypeOptionCascade,
1058+
true);
1059+
10351060
// Chrono calendar types
10361061

10371062
cpp_category_sp->AddTypeSummary(

lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,18 +1073,87 @@ bool lldb_private::formatters::LibcxxWStringViewSummaryProvider(
10731073
bool success;
10741074
ValueObjectSP dataobj;
10751075
size_t size;
1076-
std::tie( success, dataobj, size ) = LibcxxExtractStringViewData(valobj);
1076+
std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
10771077

10781078
if (!success) {
10791079
stream << "Summary Unavailable";
10801080
return true;
10811081
}
10821082

1083-
10841083
return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options,
10851084
dataobj, size);
10861085
}
10871086

1087+
bool lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
1088+
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
1089+
ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__d_");
1090+
if (!ptr_sp)
1091+
return false;
1092+
ptr_sp = ptr_sp->GetChildMemberWithName("__rep_");
1093+
if (!ptr_sp)
1094+
return false;
1095+
1096+
// The date time in the chrono library is valid in the range
1097+
// [-32767-01-01T00:00:00Z, 32767-12-31T23:59:59Z]. A 64-bit time_t has a
1098+
// larger range, the function strftime is not able to format the entire range
1099+
// of time_t. The exact point has not been investigated; it's limited to
1100+
// chrono's range.
1101+
const std::time_t chrono_timestamp_min =
1102+
-1'096'193'779'200; // -32767-01-01T00:00:00Z
1103+
const std::time_t chrono_timestamp_max =
1104+
971'890'963'199; // 32767-12-31T23:59:59Z
1105+
1106+
const std::time_t seconds = ptr_sp->GetValueAsSigned(0);
1107+
if (seconds < chrono_timestamp_min || seconds > chrono_timestamp_max)
1108+
stream.Printf("timestamp=%ld s", seconds);
1109+
else {
1110+
std::array<char, 128> str;
1111+
std::size_t size =
1112+
std::strftime(str.data(), str.size(), "%FT%H:%M:%SZ", gmtime(&seconds));
1113+
if (size == 0)
1114+
return false;
1115+
1116+
stream.Printf("date/time=%s timestamp=%ld s", str.data(), seconds);
1117+
}
1118+
1119+
return true;
1120+
}
1121+
1122+
bool lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
1123+
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
1124+
ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__d_");
1125+
if (!ptr_sp)
1126+
return false;
1127+
ptr_sp = ptr_sp->GetChildMemberWithName("__rep_");
1128+
if (!ptr_sp)
1129+
return false;
1130+
1131+
// The date time in the chrono library is valid in the range
1132+
// [-32767-01-01Z, 32767-12-31Z]. A 32-bit time_t has a larger range, the
1133+
// function strftime is not able to format the entire range of time_t. The
1134+
// exact point has not been investigated; it's limited to chrono's range.
1135+
const int chrono_timestamp_min = -12'687'428; // -32767-01-01Z
1136+
const int chrono_timestamp_max = 11'248'737; // 32767-12-31Z
1137+
1138+
const int days = ptr_sp->GetValueAsSigned(0);
1139+
if (days < chrono_timestamp_min || days > chrono_timestamp_max)
1140+
stream.Printf("timestamp=%d days", days);
1141+
1142+
else {
1143+
const std::time_t seconds = std::time_t(86400) * days;
1144+
1145+
std::array<char, 128> str;
1146+
std::size_t size =
1147+
std::strftime(str.data(), str.size(), "%FZ", gmtime(&seconds));
1148+
if (size == 0)
1149+
return false;
1150+
1151+
stream.Printf("date=%s timestamp=%d days", str.data(), days);
1152+
}
1153+
1154+
return true;
1155+
}
1156+
10881157
bool lldb_private::formatters::LibcxxChronoMonthSummaryProvider(
10891158
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
10901159
// FIXME: These are the names used in the C++20 ostream operator. Since LLVM

lldb/source/Plugins/Language/CPlusPlus/LibCxx.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,14 @@ SyntheticChildrenFrontEnd *
261261
LibcxxStdRangesRefViewSyntheticFrontEndCreator(CXXSyntheticChildren *,
262262
lldb::ValueObjectSP);
263263

264+
bool LibcxxChronoSysSecondsSummaryProvider(
265+
ValueObject &valobj, Stream &stream,
266+
const TypeSummaryOptions &options); // libc++ std::chrono::sys_seconds
267+
268+
bool LibcxxChronoSysDaysSummaryProvider(
269+
ValueObject &valobj, Stream &stream,
270+
const TypeSummaryOptions &options); // libc++ std::chrono::sys_days
271+
264272
bool LibcxxChronoMonthSummaryProvider(
265273
ValueObject &valobj, Stream &stream,
266274
const TypeSummaryOptions &options); // libc++ std::chrono::month

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/TestDataFormatterLibcxxChrono.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,102 @@ def test_with_run_command(self):
3232
self.expect("frame variable m", substrs=["m = 4321 months"])
3333
self.expect("frame variable y", substrs=["y = 321 years"])
3434

35+
self.expect(
36+
"frame variable ss_tp",
37+
substrs=["ss_tp = date/time=1970-01-01T00:00:00Z timestamp=0 s"],
38+
)
39+
self.expect(
40+
"frame variable ss_tp_d",
41+
substrs=["ss_tp_d = date/time=1970-01-01T00:00:00Z timestamp=0 s"],
42+
)
43+
self.expect(
44+
"frame variable ss_tp_d_r",
45+
substrs=["ss_tp_d_r = date/time=1970-01-01T00:00:00Z timestamp=0 s"],
46+
)
47+
self.expect(
48+
"frame variable ss_tp_d_r2",
49+
substrs=["ss_tp_d_r2 = date/time=1970-01-01T00:00:00Z timestamp=0 s"],
50+
)
51+
52+
self.expect(
53+
"frame variable ss_0",
54+
substrs=["ss_0 = date/time=1970-01-01T00:00:00Z timestamp=0 s"],
55+
)
56+
57+
self.expect(
58+
"frame variable ss_neg_date_time",
59+
substrs=[
60+
"ss_neg_date_time = date/time=-32767-01-01T00:00:00Z timestamp=-1096193779200 s"
61+
],
62+
)
63+
self.expect(
64+
"frame variable ss_neg_seconds",
65+
substrs=["ss_neg_seconds = timestamp=-1096193779201 s"],
66+
)
67+
68+
self.expect(
69+
"frame variable ss_pos_date_time",
70+
substrs=[
71+
"ss_pos_date_time = date/time=32767-12-31T23:59:59Z timestamp=971890963199 s"
72+
],
73+
)
74+
self.expect(
75+
"frame variable ss_pos_seconds",
76+
substrs=["ss_pos_seconds = timestamp=971890963200 s"],
77+
)
78+
79+
self.expect(
80+
"frame variable ss_min",
81+
substrs=["ss_min = timestamp=-9223372036854775808 s"],
82+
)
83+
self.expect(
84+
"frame variable ss_max",
85+
substrs=["ss_max = timestamp=9223372036854775807 s"],
86+
)
87+
88+
self.expect(
89+
"frame variable sd_tp",
90+
substrs=["sd_tp = date=1970-01-01Z timestamp=0 days"],
91+
)
92+
self.expect(
93+
"frame variable sd_tp_d_r",
94+
substrs=["sd_tp_d_r = date=1970-01-01Z timestamp=0 days"],
95+
)
96+
self.expect(
97+
"frame variable sd_tp_d_r2",
98+
substrs=["sd_tp_d_r2 = date=1970-01-01Z timestamp=0 days"],
99+
)
100+
101+
self.expect(
102+
"frame variable sd_0", substrs=["sd_0 = date=1970-01-01Z timestamp=0 days"]
103+
)
104+
self.expect(
105+
"frame variable sd_neg_date",
106+
substrs=["sd_neg_date = date=-32767-01-01Z timestamp=-12687428 days"],
107+
)
108+
self.expect(
109+
"frame variable sd_neg_days",
110+
substrs=["sd_neg_days = timestamp=-12687429 days"],
111+
)
112+
113+
self.expect(
114+
"frame variable sd_pos_date",
115+
substrs=["sd_pos_date = date=32767-12-31Z timestamp=11248737 days"],
116+
)
117+
self.expect(
118+
"frame variable sd_pos_days",
119+
substrs=["sd_pos_days = timestamp=11248738 days"],
120+
)
121+
122+
self.expect(
123+
"frame variable sd_min",
124+
substrs=["sd_min = timestamp=-2147483648 days"],
125+
)
126+
self.expect(
127+
"frame variable sd_max",
128+
substrs=["sd_max = timestamp=2147483647 days"],
129+
)
130+
35131
self.expect("frame variable d_0", substrs=["d_0 = day=0"])
36132
self.expect("frame variable d_1", substrs=["d_1 = day=1"])
37133
self.expect("frame variable d_31", substrs=["d_31 = day=31"])

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/main.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,58 @@ int main() {
1515
std::chrono::months m{4321};
1616
std::chrono::years y{321};
1717

18+
// sys_seconds aliasses
19+
std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>
20+
ss_tp{std::chrono::seconds{0}};
21+
std::chrono::time_point<std::chrono::system_clock,
22+
std::chrono::duration<long long>>
23+
ss_tp_d{std::chrono::seconds{0}};
24+
std::chrono::time_point<std::chrono::system_clock,
25+
std::chrono::duration<long long, std::ratio<1>>>
26+
ss_tp_d_r{std::chrono::seconds{0}};
27+
std::chrono::time_point<std::chrono::system_clock,
28+
std::chrono::duration<long long, std::ratio<1>>>
29+
ss_tp_d_r2{std::chrono::seconds{0}};
30+
31+
// sys_seconds
32+
std::chrono::sys_seconds ss_0{std::chrono::seconds{0}};
33+
std::chrono::sys_seconds ss_neg_date_time{
34+
std::chrono::seconds{-1'096'193'779'200}};
35+
std::chrono::sys_seconds ss_neg_seconds{
36+
std::chrono::seconds{-1'096'193'779'201}};
37+
std::chrono::sys_seconds ss_pos_date_time{
38+
std::chrono::seconds{971'890'963'199}};
39+
std::chrono::sys_seconds ss_pos_seconds{
40+
std::chrono::seconds{971'890'963'200}};
41+
std::chrono::sys_seconds ss_min{
42+
std::chrono::seconds{std::numeric_limits<long long>::min()}};
43+
std::chrono::sys_seconds ss_max{
44+
std::chrono::seconds{std::numeric_limits<long long>::max()}};
45+
46+
// sys_days aliasses
47+
std::chrono::time_point<std::chrono::system_clock, std::chrono::days> sd_tp{
48+
std::chrono::days{0}};
49+
std::chrono::time_point<std::chrono::system_clock,
50+
std::chrono::duration<int, std::ratio<86400>>>
51+
sd_tp_d_r{std::chrono::days{0}};
52+
std::chrono::time_point<std::chrono::system_clock,
53+
std::chrono::duration<int, std::ratio<86400, 1>>>
54+
sd_tp_d_r2{std::chrono::days{0}};
55+
56+
// sys_days
57+
std::chrono::sys_days sd_0{std::chrono::days{0}};
58+
59+
std::chrono::sys_days sd_neg_date{std::chrono::days{-12'687'428}};
60+
std::chrono::sys_days sd_neg_days{std::chrono::days{-12'687'429}};
61+
62+
std::chrono::sys_days sd_pos_date{std::chrono::days{11'248'737}};
63+
std::chrono::sys_days sd_pos_days{std::chrono::days{11'248'738}};
64+
65+
std::chrono::sys_days sd_min{
66+
std::chrono::days{std::numeric_limits<int>::min()}};
67+
std::chrono::sys_days sd_max{
68+
std::chrono::days{std::numeric_limits<int>::max()}};
69+
1870
std::chrono::day d_0{0};
1971
std::chrono::day d_1{1};
2072
std::chrono::day d_31{31};

0 commit comments

Comments
 (0)