Skip to content

Commit 826a40d

Browse files
mordanteMichael137
authored andcommitted
[lldb][libc++] Adds system_clock data formatters. (llvm#78609)
(cherry picked from commit bfd12f3)
1 parent 6985135 commit 826a40d

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
@@ -1047,6 +1047,31 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
10471047
TypeSummaryImplSP(new StringSummaryFormat(
10481048
eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));
10491049

1050+
// Chrono time point types
1051+
1052+
AddCXXSummary(cpp_category_sp,
1053+
lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider,
1054+
"libc++ std::chrono::sys_seconds summary provider",
1055+
"^std::__[[:alnum:]]+::chrono::time_point<"
1056+
"std::__[[:alnum:]]+::chrono::system_clock, "
1057+
"std::__[[:alnum:]]+::chrono::duration<long long, "
1058+
"std::__[[:alnum:]]+::ratio<1, 1> "
1059+
"> >$",
1060+
eTypeOptionHideChildren | eTypeOptionHideValue |
1061+
eTypeOptionCascade,
1062+
true);
1063+
AddCXXSummary(cpp_category_sp,
1064+
lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider,
1065+
"libc++ std::chrono::sys_seconds summary provider",
1066+
"^std::__[[:alnum:]]+::chrono::time_point<"
1067+
"std::__[[:alnum:]]+::chrono::system_clock, "
1068+
"std::__[[:alnum:]]+::chrono::duration<int, "
1069+
"std::__[[:alnum:]]+::ratio<86400, 1> "
1070+
"> >$",
1071+
eTypeOptionHideChildren | eTypeOptionHideValue |
1072+
eTypeOptionCascade,
1073+
true);
1074+
10501075
// Chrono calendar types
10511076

10521077
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
@@ -1076,18 +1076,87 @@ bool lldb_private::formatters::LibcxxWStringViewSummaryProvider(
10761076
bool success;
10771077
ValueObjectSP dataobj;
10781078
size_t size;
1079-
std::tie( success, dataobj, size ) = LibcxxExtractStringViewData(valobj);
1079+
std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
10801080

10811081
if (!success) {
10821082
stream << "Summary Unavailable";
10831083
return true;
10841084
}
10851085

1086-
10871086
return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options,
10881087
dataobj, size);
10891088
}
10901089

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

268+
bool LibcxxChronoSysSecondsSummaryProvider(
269+
ValueObject &valobj, Stream &stream,
270+
const TypeSummaryOptions &options); // libc++ std::chrono::sys_seconds
271+
272+
bool LibcxxChronoSysDaysSummaryProvider(
273+
ValueObject &valobj, Stream &stream,
274+
const TypeSummaryOptions &options); // libc++ std::chrono::sys_days
275+
268276
bool LibcxxChronoMonthSummaryProvider(
269277
ValueObject &valobj, Stream &stream,
270278
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
@@ -31,6 +31,102 @@ def test_with_run_command(self):
3131
self.expect("frame variable m", substrs=["m = 4321 months"])
3232
self.expect("frame variable y", substrs=["y = 321 years"])
3333

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