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