Skip to content

[lldb][libc++] Adds some C++20 calendar data formatters. #76983

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 9, 2024

Conversation

mordante
Copy link
Member

@mordante mordante commented Jan 4, 2024

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.

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.
@mordante mordante requested a review from Michael137 January 4, 2024 17:46
@mordante mordante requested a review from JDevlieghere as a code owner January 4, 2024 17:46
@llvmbot llvmbot added the lldb label Jan 4, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 4, 2024

@llvm/pr-subscribers-lldb

Author: Mark de Wever (mordante)

Changes

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.

Full diff: https://github.com/llvm/llvm-project/pull/76983.diff

5 Files Affected:

  • (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+35)
  • (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (+40)
  • (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (+8)
  • (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/TestDataFormatterLibcxxChrono.py (+67)
  • (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/main.cpp (+54)
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";
 }

@mordante
Copy link
Member Author

mordante commented Jan 4, 2024

Note: I'd be happy to add the missing calendar data formatters to this review. I just want to make sure we're happy with the proposed output before adding them.

Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a lot of knowledge about the C++20 calendar types, but the LLDB implementation looks ok to me.

What do you think @Michael137?

Copy link
Member

@Michael137 Michael137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(sorry had the review comments pending but didn't click the Submit review button)

LGTM

Just left some minor comments

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we FIXME this?

@mordante
Copy link
Member Author

mordante commented Jan 9, 2024

Thanks for the reviews!

@mordante mordante merged commit b5f2db9 into llvm:main Jan 9, 2024
@mordante mordante deleted the lldb_calendar_formatters branch January 9, 2024 16:19
mordante added a commit to mordante/llvm-project that referenced this pull request Jan 12, 2024
This is a followup of llvm#76983 and adds the data formatters for
- weekday,
- weekday_indexed,
- weekday_last,
- month_weekday,
- month_weekday_last,
- year_month,
- year_month_day_last
- year_month_weekday, and
- year_month_weekday_last.
mordante added a commit that referenced this pull request Jan 13, 2024
This is a followup of #76983 and adds the libc++ data formatters for
- weekday,
- weekday_indexed,
- weekday_last,
- month_weekday,
- month_weekday_last,
- year_month,
- year_month_day_last
- year_month_weekday, and
- year_month_weekday_last.
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
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.
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
This is a followup of llvm#76983 and adds the libc++ data formatters for
- weekday,
- weekday_indexed,
- weekday_last,
- month_weekday,
- month_weekday_last,
- year_month,
- year_month_day_last
- year_month_weekday, and
- year_month_weekday_last.
Michael137 pushed a commit to Michael137/llvm-project that referenced this pull request Feb 16, 2024
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.

(cherry picked from commit b5f2db9)
Michael137 pushed a commit to Michael137/llvm-project that referenced this pull request Feb 16, 2024
This is a followup of llvm#76983 and adds the libc++ data formatters for
- weekday,
- weekday_indexed,
- weekday_last,
- month_weekday,
- month_weekday_last,
- year_month,
- year_month_day_last
- year_month_weekday, and
- year_month_weekday_last.

(cherry picked from commit e3fde34)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants