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