1 //===-- CoreMedia.cpp -----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "CoreMedia.h"
10 
11 #include "lldb/Utility/Flags.h"
12 #include "lldb/Utility/Log.h"
13 
14 #include "lldb/Symbol/TypeSystem.h"
15 #include "lldb/Target/Target.h"
16 #include <inttypes.h>
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 using namespace lldb_private::formatters;
21 
22 bool lldb_private::formatters::CMTimeSummaryProvider(
23     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
24   CompilerType type = valobj.GetCompilerType();
25   if (!type.IsValid())
26     return false;
27 
28   TypeSystem *type_system = type.GetTypeSystem();
29   // fetch children by offset to compensate for potential lack of debug info
30   auto int64_ty =
31       type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
32   auto int32_ty =
33       type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
34 
35   auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true));
36   auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true));
37   auto flags_sp(valobj.GetSyntheticChildAtOffset(12, int32_ty, true));
38 
39   if (!value_sp || !timescale_sp || !flags_sp)
40     return false;
41 
42   auto value = value_sp->GetValueAsUnsigned(0);
43   auto timescale = (int32_t)timescale_sp->GetValueAsUnsigned(
44       0); // the timescale specifies the fraction of a second each unit in the
45           // numerator occupies
46   auto flags = Flags(flags_sp->GetValueAsUnsigned(0) &
47                      0x00000000000000FF); // the flags I need sit in the LSB
48 
49   const unsigned int FlagPositiveInf = 4;
50   const unsigned int FlagNegativeInf = 8;
51   const unsigned int FlagIndefinite = 16;
52 
53   if (flags.AnySet(FlagIndefinite)) {
54     stream.Printf("indefinite");
55     return true;
56   }
57 
58   if (flags.AnySet(FlagPositiveInf)) {
59     stream.Printf("+oo");
60     return true;
61   }
62 
63   if (flags.AnySet(FlagNegativeInf)) {
64     stream.Printf("-oo");
65     return true;
66   }
67 
68   if (timescale == 0)
69     return false;
70 
71   switch (timescale) {
72   case 0:
73     return false;
74   case 1:
75     stream.Printf("%" PRId64 " seconds", value);
76     return true;
77   case 2:
78     stream.Printf("%" PRId64 " half seconds", value);
79     return true;
80   case 3:
81     stream.Printf("%" PRId64 " third%sof a second", value,
82                   value == 1 ? " " : "s ");
83     return true;
84   default:
85     stream.Printf("%" PRId64 " %" PRId32 "th%sof a second", value, timescale,
86                   value == 1 ? " " : "s ");
87     return true;
88   }
89 }
90