Skip to content

Commit 001c78d

Browse files
committed
[lldb][formatters] Add support for printing NSConstantDate and fix distantPast value
Summary: Certain `NSDate` constructors return a special `NSConstantDate` class which currently ends up being unformatted as it's not in the list of supported classes for the NSDate formatter. This patch adds that class to the supported class list so LLDB produces a summary for it. One of these special constructors is `[NSDate distantPast]` which returns the date for `0001-01-01 00:00:00 UTC`. LLDB has a special case for formatting this date but for some reason we did hardcode the wrong summary string in that special case. Maybe the summary string was correct back when the code was written but it isn't correct anymore (`distantPast` isn't actually defined to be a special date but just some 'a guaranteed temporal boundary.' so maybe someone changed the value in the last 10 years). If someone else is wondering why we even have this special case for `distantPast` but not for the future. The reason seems to be that our date formatting for really old dates is off by 24 hours. So for example, adding one second to `distantPast` will cause LLDB to print `0000-12-30 00:00:01 UTC` (which is 24 hours behind the expected result). So to make our code appear to be correct it seems we just hardcoded the most common NSDate result from that time span. I'll replace that logic with a generic solution in a probably more invasive follow up patch. I also took the freedom to replace the magic value `-63114076800` with some constant + documentation. I heard there are some people that don't know from the top of their head that there are 63114076800 seconds between 1. Jan 0001 and 1. January 2001 in whatever calendar system NSDate is using. Reviewers: mib, davide Reviewed By: mib Subscribers: JDevlieghere Differential Revision: https://reviews.llvm.org/D83217
1 parent de7bf72 commit 001c78d

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

lldb/source/Plugins/Language/ObjC/Cocoa.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,13 +818,14 @@ bool lldb_private::formatters::NSDateSummaryProvider(
818818
static const ConstString g___NSDate("__NSDate");
819819
static const ConstString g___NSTaggedDate("__NSTaggedDate");
820820
static const ConstString g_NSCalendarDate("NSCalendarDate");
821+
static const ConstString g_NSConstantDate("NSConstantDate");
821822

822823
if (class_name.IsEmpty())
823824
return false;
824825

825826
uint64_t info_bits = 0, value_bits = 0;
826827
if ((class_name == g_NSDate) || (class_name == g___NSDate) ||
827-
(class_name == g___NSTaggedDate)) {
828+
(class_name == g___NSTaggedDate) || (class_name == g_NSConstantDate)) {
828829
if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits)) {
829830
date_value_bits = ((value_bits << 8) | (info_bits << 4));
830831
memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
@@ -850,8 +851,14 @@ bool lldb_private::formatters::NSDateSummaryProvider(
850851
} else
851852
return false;
852853

853-
if (date_value == -63114076800) {
854-
stream.Printf("0001-12-30 00:00:00 +0000");
854+
// FIXME: It seems old dates are not formatted according to NSDate's calendar
855+
// so we hardcode distantPast's value so that it looks like LLDB is doing
856+
// the right thing.
857+
858+
// The relative time in seconds from Cocoa Epoch to [NSDate distantPast].
859+
const double RelSecondsFromCocoaEpochToNSDateDistantPast = -63114076800;
860+
if (date_value == RelSecondsFromCocoaEpochToNSDateDistantPast) {
861+
stream.Printf("0001-01-01 00:00:00 UTC");
855862
return true;
856863
}
857864

lldb/test/API/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjCNSDate.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,6 @@ def nsdate_data_formatter_commands(self):
6767
substrs=[
6868
'(CFMutableBitVectorRef) mut_bv = ',
6969
'1110 0110 1011 0000 1101 1010 1000 1111 0011 0101 1101 0001 00'])
70+
71+
self.expect_expr("distant_past", result_summary="0001-01-01 00:00:00 UTC")
72+
self.expect_expr("distant_future", result_summary="4001-01-01 00:00:00 UTC")

lldb/test/API/functionalities/data-formatter/data-formatter-objc/main.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,9 @@ int main(int argc, const char *argv[]) {
663663
NSDate *date_1970_plus_05 = [NSDate dateWithTimeIntervalSince1970:0.5];
664664
NSDate *date_1970_plus_04 = [NSDate dateWithTimeIntervalSince1970:0.4];
665665

666+
NSDate *distant_past = [NSDate distantPast];
667+
NSDate *distant_future = [NSDate distantFuture];
668+
666669
CFAbsoluteTime date1_abs = CFDateGetAbsoluteTime(date1);
667670
CFAbsoluteTime date2_abs = CFDateGetAbsoluteTime(date2);
668671
CFAbsoluteTime date3_abs = CFDateGetAbsoluteTime(date3);

0 commit comments

Comments
 (0)