[Lldb-commits] [lldb] [lldb][libc++] Adds some C++20 calendar data formatters. (PR #76983)

Mark de Wever via lldb-commits lldb-commits at lists.llvm.org
Thu Jan 4 09:46:55 PST 2024


https://github.com/mordante created https://github.com/llvm/llvm-project/pull/76983

This adds a subset of the C++20 calendar data formatters:
- day,
- month,
- year,
- month_day,
- month_day_last, and
- year_month_day.

A followup patch will add the missing calendar data formatters:
- weekday,
- weekday_indexed,
- weekday_last,
- month_weekday,
- month_weekday_last,
- year_month,
- year_month_day_last
- year_month_weekday, and
- year_month_weekday_last.

>From f92402067fcdb6b87adcf3d727bff1888ebf4ab7 Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Thu, 4 Jan 2024 18:43:54 +0100
Subject: [PATCH] [lldb][libc++] Adds some C++20 calendar data formatters.

This adds a subset of the C++20 calendar data formatters:
- day,
- month,
- year,
- month_day,
- month_day_last, and
- year_month_day.

A followup patch will add the missing calendar data formatters:
- weekday,
- weekday_indexed,
- weekday_last,
- month_weekday,
- month_weekday_last,
- year_month,
- year_month_day_last
- year_month_weekday, and
- year_month_weekday_last.
---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 35 ++++++++++
 .../Plugins/Language/CPlusPlus/LibCxx.cpp     | 40 +++++++++++
 .../Plugins/Language/CPlusPlus/LibCxx.h       |  8 +++
 .../chrono/TestDataFormatterLibcxxChrono.py   | 67 +++++++++++++++++++
 .../data-formatter-stl/libcxx/chrono/main.cpp | 54 +++++++++++++++
 5 files changed, 204 insertions(+)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 586cc08a6f1233..c6937ebca319fa 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1031,6 +1031,41 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
       "^std::__[[:alnum:]]+::chrono::seconds", eFormatterMatchRegex,
       TypeSummaryImplSP(new StringSummaryFormat(
           eTypeOptionHideChildren | eTypeOptionHideValue, "${var.__rep_} s")));
+
+  // Chrono calendar types
+
+  cpp_category_sp->AddTypeSummary(
+      "^std::__[[:alnum:]]+::chrono::day$", eFormatterMatchRegex,
+      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
+                                                    eTypeOptionHideValue,
+                                                "day=${var.__d_%u}")));
+  AddCXXSummary(cpp_category_sp,
+                lldb_private::formatters::LibcxxChronoMonthSummaryProvider,
+                "libc++ std::chrono::month summary provider",
+                "^std::__[[:alnum:]]+::chrono::month$",
+                eTypeOptionHideChildren | eTypeOptionHideValue, true);
+
+  cpp_category_sp->AddTypeSummary(
+      "^std::__[[:alnum:]]+::chrono::year$", eFormatterMatchRegex,
+      TypeSummaryImplSP(new StringSummaryFormat(
+          eTypeOptionHideChildren | eTypeOptionHideValue, "year=${var.__y_}")));
+
+  cpp_category_sp->AddTypeSummary(
+      "^std::__[[:alnum:]]+::chrono::month_day$", eFormatterMatchRegex,
+      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
+                                                    eTypeOptionHideValue,
+                                                "${var.__m_} ${var.__d_}")));
+  cpp_category_sp->AddTypeSummary(
+      "^std::__[[:alnum:]]+::chrono::month_day_last$", eFormatterMatchRegex,
+      TypeSummaryImplSP(new StringSummaryFormat(eTypeOptionHideChildren |
+                                                    eTypeOptionHideValue,
+                                                "${var.__m_} day=last")));
+  AddCXXSummary(
+      cpp_category_sp,
+      lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider,
+      "libc++ std::chrono::year_month_day summary provider",
+      "^std::__[[:alnum:]]+::chrono::year_month_day$",
+      eTypeOptionHideChildren | eTypeOptionHideValue, true);
 }
 
 static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index cae17ef992b215..5f9228c7b020c8 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -1084,3 +1084,43 @@ bool lldb_private::formatters::LibcxxWStringViewSummaryProvider(
   return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options,
                                         dataobj, size);
 }
+
+bool lldb_private::formatters::LibcxxChronoMonthSummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+  // These are the names used in the C++20 ostream operator. Since LLVM uses
+  // C++17 it's not possible to use the ostream operator directly.
+  static const std::array<std::string_view, 12> months = {
+      "January", "February", "March",     "April",   "May",      "June",
+      "July",    "August",   "September", "October", "November", "December"};
+
+  unsigned month = valobj.GetChildMemberWithName("__m_")->GetValueAsUnsigned(0);
+  if (month >= 1 && month <= 12)
+    stream << "month=" << months[month - 1];
+  else
+    stream.Printf("month=%u", month);
+
+  return true;
+}
+
+bool lldb_private::formatters::LibcxxChronoYearMonthDaySummaryProvider(
+    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+
+  stream << "date=";
+  int year = valobj.GetChildMemberWithName("__y_")
+                 ->GetChildMemberWithName("__y_")
+                 ->GetValueAsSigned(0);
+  if (year < 0) {
+    stream << '-';
+    year = -year;
+  }
+
+  unsigned month = valobj.GetChildMemberWithName("__m_")
+                       ->GetChildMemberWithName("__m_")
+                       ->GetValueAsUnsigned(0);
+  unsigned day = valobj.GetChildMemberWithName("__d_")
+                     ->GetChildMemberWithName("__d_")
+                     ->GetValueAsUnsigned(0);
+  stream.Printf("%04d-%02u-%02u", year, month, day);
+
+  return true;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index f65801e2cb1b9c..c252ae382dd922 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -261,6 +261,14 @@ SyntheticChildrenFrontEnd *
 LibcxxStdRangesRefViewSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                                lldb::ValueObjectSP);
 
+bool LibcxxChronoMonthSummaryProvider(
+    ValueObject &valobj, Stream &stream,
+    const TypeSummaryOptions &options); // libc++ std::chrono::month
+
+bool LibcxxChronoYearMonthDaySummaryProvider(
+    ValueObject &valobj, Stream &stream,
+    const TypeSummaryOptions &options); // libc++ std::chrono::year_month_day
+
 } // namespace formatters
 } // namespace lldb_private
 
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/TestDataFormatterLibcxxChrono.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/TestDataFormatterLibcxxChrono.py
index b2f86817f3b0e8..38a31d2ddb4590 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/TestDataFormatterLibcxxChrono.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/TestDataFormatterLibcxxChrono.py
@@ -32,3 +32,70 @@ def test_with_run_command(self):
         self.expect("frame variable m", substrs=["m = 4321 months"])
         self.expect("frame variable y", substrs=["y = 321 years"])
 
+        self.expect("frame variable d_0", substrs=["d_0 = day=0"])
+        self.expect("frame variable d_1", substrs=["d_1 = day=1"])
+        self.expect("frame variable d_31", substrs=["d_31 = day=31"])
+        self.expect("frame variable d_255", substrs=["d_255 = day=255"])
+
+        self.expect("frame variable jan", substrs=["jan = month=January"])
+        self.expect("frame variable feb", substrs=["feb = month=February"])
+        self.expect("frame variable mar", substrs=["mar = month=March"])
+        self.expect("frame variable apr", substrs=["apr = month=April"])
+        self.expect("frame variable may", substrs=["may = month=May"])
+        self.expect("frame variable jun", substrs=["jun = month=June"])
+        self.expect("frame variable jul", substrs=["jul = month=July"])
+        self.expect("frame variable aug", substrs=["aug = month=August"])
+        self.expect("frame variable sep", substrs=["sep = month=September"])
+        self.expect("frame variable oct", substrs=["oct = month=October"])
+        self.expect("frame variable nov", substrs=["nov = month=November"])
+        self.expect("frame variable dec", substrs=["dec = month=December"])
+
+        self.expect("frame variable month_0", substrs=["month_0 = month=0"])
+        self.expect("frame variable month_1", substrs=["month_1 = month=January"])
+        self.expect("frame variable month_2", substrs=["month_2 = month=February"])
+        self.expect("frame variable month_3", substrs=["month_3 = month=March"])
+        self.expect("frame variable month_4", substrs=["month_4 = month=April"])
+        self.expect("frame variable month_5", substrs=["month_5 = month=May"])
+        self.expect("frame variable month_6", substrs=["month_6 = month=June"])
+        self.expect("frame variable month_7", substrs=["month_7 = month=July"])
+        self.expect("frame variable month_8", substrs=["month_8 = month=August"])
+        self.expect("frame variable month_9", substrs=["month_9 = month=September"])
+        self.expect("frame variable month_10", substrs=["month_10 = month=October"])
+        self.expect("frame variable month_11", substrs=["month_11 = month=November"])
+        self.expect("frame variable month_12", substrs=["month_12 = month=December"])
+        self.expect("frame variable month_13", substrs=["month_13 = month=13"])
+        self.expect("frame variable month_255", substrs=["month_255 = month=255"])
+
+        self.expect("frame variable y_min", substrs=["y_min = year=-32767"])
+        self.expect("frame variable y_0", substrs=["y_0 = year=0"])
+        self.expect("frame variable y_1970", substrs=["y_1970 = year=1970"])
+        self.expect("frame variable y_2038", substrs=["y_2038 = year=2038"])
+        self.expect("frame variable y_max", substrs=["y_max = year=32767"])
+
+        self.expect(
+            "frame variable md_new_years_eve",
+            substrs=["md_new_years_eve = month=December day=31"],
+        )
+        self.expect(
+            "frame variable md_new_year", substrs=["md_new_year = month=January day=1"]
+        )
+        self.expect(
+            "frame variable md_invalid", substrs=["md_invalid = month=255 day=255"]
+        )
+
+        self.expect(
+            "frame variable mdl_jan", substrs=["mdl_jan = month=January day=last"]
+        )
+        self.expect(
+            "frame variable mdl_new_years_eve",
+            substrs=["mdl_new_years_eve = month=December day=last"],
+        )
+
+        self.expect("frame variable ymd_bc", substrs=["ymd_bc = date=-0001-03-255"])
+        self.expect(
+            "frame variable ymd_year_zero", substrs=["ymd_year_zero = date=0000-255-25"]
+        )
+        self.expect(
+            "frame variable ymd_unix_epoch",
+            substrs=["ymd_unix_epoch = date=1970-01-01"],
+        )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/main.cpp
index 9eba7daa294077..9aa011c97d0c13 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/main.cpp
@@ -15,5 +15,59 @@ int main() {
   std::chrono::months m{4321};
   std::chrono::years y{321};
 
+  std::chrono::day d_0{0};
+  std::chrono::day d_1{1};
+  std::chrono::day d_31{31};
+  std::chrono::day d_255{255};
+
+  std::chrono::month jan = std::chrono::January;
+  std::chrono::month feb = std::chrono::February;
+  std::chrono::month mar = std::chrono::March;
+  std::chrono::month apr = std::chrono::April;
+  std::chrono::month may = std::chrono::May;
+  std::chrono::month jun = std::chrono::June;
+  std::chrono::month jul = std::chrono::July;
+  std::chrono::month aug = std::chrono::August;
+  std::chrono::month sep = std::chrono::September;
+  std::chrono::month oct = std::chrono::October;
+  std::chrono::month nov = std::chrono::November;
+  std::chrono::month dec = std::chrono::December;
+
+  std::chrono::month month_0{0};
+  std::chrono::month month_1{1};
+  std::chrono::month month_2{2};
+  std::chrono::month month_3{3};
+  std::chrono::month month_4{4};
+  std::chrono::month month_5{5};
+  std::chrono::month month_6{6};
+  std::chrono::month month_7{7};
+  std::chrono::month month_8{8};
+  std::chrono::month month_9{9};
+  std::chrono::month month_10{10};
+  std::chrono::month month_11{11};
+  std::chrono::month month_12{12};
+  std::chrono::month month_13{13};
+  std::chrono::month month_255{255};
+
+  std::chrono::year y_min{std::chrono::year::min()};
+  std::chrono::year y_0{0};
+  std::chrono::year y_1970{1970};
+  std::chrono::year y_2038{2038};
+  std::chrono::year y_max{std::chrono::year::max()};
+
+  std::chrono::month_day md_new_years_eve{std::chrono::December / 31};
+  std::chrono::month_day md_new_year{std::chrono::January / 1};
+  std::chrono::month_day md_invalid{std::chrono::month{255} / 255};
+
+  std::chrono::month_day_last mdl_jan{std::chrono::January};
+  std::chrono::month_day_last mdl_new_years_eve{std::chrono::December};
+
+  std::chrono::year_month_day ymd_bc{std::chrono::year{-1}, std::chrono::March,
+                                     std::chrono::day{255}};
+  std::chrono::year_month_day ymd_year_zero{
+      std::chrono::year{0}, std::chrono::month{255}, std::chrono::day{25}};
+  std::chrono::year_month_day ymd_unix_epoch{
+      std::chrono::year{1970}, std::chrono::January, std::chrono::day{1}};
+
   std::cout << "break here\n";
 }



More information about the lldb-commits mailing list