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