LLDB  mainline
TypeFormat.cpp
Go to the documentation of this file.
1 //===-- TypeFormat.cpp ----------------------------------------*- C++ -*-===//
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 
10 
11 
12 
13 
14 #include "lldb/lldb-enumerations.h"
15 #include "lldb/lldb-public.h"
16 
21 #include "lldb/Symbol/SymbolFile.h"
22 #include "lldb/Symbol/TypeList.h"
23 #include "lldb/Target/Target.h"
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 
30 TypeFormatImpl::TypeFormatImpl(const Flags &flags)
31  : m_flags(flags), m_my_revision(0) {}
32 
34 
36  const TypeFormatImpl::Flags &flags)
37  : TypeFormatImpl(flags), m_format(f) {}
38 
40 
42  std::string &dest) const {
43  if (!valobj)
44  return false;
45  if (valobj->CanProvideValue()) {
46  Value &value(valobj->GetValue());
47  const Value::ContextType context_type = value.GetContextType();
48  ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
49  DataExtractor data;
50 
51  if (context_type == Value::eContextTypeRegisterInfo) {
52  const RegisterInfo *reg_info = value.GetRegisterInfo();
53  if (reg_info) {
54  Status error;
55  valobj->GetData(data, error);
56  if (error.Fail())
57  return false;
58 
59  StreamString reg_sstr;
60  DumpDataExtractor(data, &reg_sstr, 0, GetFormat(), reg_info->byte_size,
62  exe_ctx.GetBestExecutionContextScope());
63  dest = reg_sstr.GetString();
64  }
65  } else {
66  CompilerType compiler_type = value.GetCompilerType();
67  if (compiler_type) {
68  // put custom bytes to display in the DataExtractor to override the
69  // default value logic
70  if (GetFormat() == eFormatCString) {
71  lldb_private::Flags type_flags(compiler_type.GetTypeInfo(
72  NULL)); // disambiguate w.r.t. TypeFormatImpl::Flags
73  if (type_flags.Test(eTypeIsPointer) &&
74  !type_flags.Test(eTypeIsObjC)) {
75  // if we are dumping a pointer as a c-string, get the pointee data
76  // as a string
77  TargetSP target_sp(valobj->GetTargetSP());
78  if (target_sp) {
79  size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
80  Status error;
81  DataBufferSP buffer_sp(new DataBufferHeap(max_len + 1, 0));
82  Address address(valobj->GetPointerValue());
83  if (target_sp->ReadCStringFromMemory(
84  address, (char *)buffer_sp->GetBytes(), max_len, error) &&
85  error.Success())
86  data.SetData(buffer_sp);
87  }
88  }
89  } else {
90  Status error;
91  valobj->GetData(data, error);
92  if (error.Fail())
93  return false;
94  }
95 
96  ExecutionContextScope *exe_scope =
97  exe_ctx.GetBestExecutionContextScope();
98  llvm::Optional<uint64_t> size = compiler_type.GetByteSize(exe_scope);
99  if (!size)
100  return false;
101  StreamString sstr;
102  compiler_type.DumpTypeValue(
103  &sstr, // The stream to use for display
104  GetFormat(), // Format to display this type with
105  data, // Data to extract from
106  0, // Byte offset into "m_data"
107  *size, // Byte size of item in "m_data"
108  valobj->GetBitfieldBitSize(), // Bitfield bit size
109  valobj->GetBitfieldBitOffset(), // Bitfield bit offset
110  exe_scope);
111  // Given that we do not want to set the ValueObject's m_error for a
112  // formatting error (or else we wouldn't be able to reformat until a
113  // next update), an empty string is treated as a "false" return from
114  // here, but that's about as severe as we get
115  // CompilerType::DumpTypeValue() should always return something, even
116  // if that something is an error message
117  dest = sstr.GetString();
118  }
119  }
120  return !dest.empty();
121  } else
122  return false;
123 }
124 
126  StreamString sstr;
128  Cascades() ? "" : " (not cascading)",
129  SkipsPointers() ? " (skip pointers)" : "",
130  SkipsReferences() ? " (skip references)" : "");
131  return sstr.GetString();
132 }
133 
135  ConstString type_name, const TypeFormatImpl::Flags &flags)
136  : TypeFormatImpl(flags), m_enum_type(type_name), m_types() {}
137 
139 
141  std::string &dest) const {
142  dest.clear();
143  if (!valobj)
144  return false;
145  if (!valobj->CanProvideValue())
146  return false;
147  ProcessSP process_sp;
148  TargetSP target_sp;
149  void *valobj_key = (process_sp = valobj->GetProcessSP()).get();
150  if (!valobj_key)
151  valobj_key = (target_sp = valobj->GetTargetSP()).get();
152  else
153  target_sp = process_sp->GetTarget().shared_from_this();
154  if (!valobj_key)
155  return false;
156  auto iter = m_types.find(valobj_key), end = m_types.end();
157  CompilerType valobj_enum_type;
158  if (iter == end) {
159  // probably a redundant check
160  if (!target_sp)
161  return false;
162  const ModuleList &images(target_sp->GetImages());
163  TypeList types;
164  llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
165  images.FindTypes(nullptr, m_enum_type, false, UINT32_MAX,
166  searched_symbol_files, types);
167  if (types.GetSize() == 0)
168  return false;
169  for (lldb::TypeSP type_sp : types.Types()) {
170  if (!type_sp)
171  continue;
172  if ((type_sp->GetForwardCompilerType().GetTypeInfo() &
173  eTypeIsEnumeration) == eTypeIsEnumeration) {
174  valobj_enum_type = type_sp->GetFullCompilerType();
175  m_types.emplace(valobj_key, valobj_enum_type);
176  break;
177  }
178  }
179  } else
180  valobj_enum_type = iter->second;
181  if (!valobj_enum_type.IsValid())
182  return false;
183  DataExtractor data;
184  Status error;
185  valobj->GetData(data, error);
186  if (error.Fail())
187  return false;
188  ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
189  StreamString sstr;
190  valobj_enum_type.DumpTypeValue(&sstr, lldb::eFormatEnum, data, 0,
191  data.GetByteSize(), 0, 0,
192  exe_ctx.GetBestExecutionContextScope());
193  if (!sstr.GetString().empty())
194  dest = sstr.GetString();
195  return !dest.empty();
196 }
197 
199  StreamString sstr;
200  sstr.Printf("as type %s%s%s%s", m_enum_type.AsCString("<invalid type>"),
201  Cascades() ? "" : " (not cascading)",
202  SkipsPointers() ? " (skip pointers)" : "",
203  SkipsReferences() ? " (skip references)" : "");
204  return sstr.GetString();
205 }
bool FormatObject(ValueObject *valobj, std::string &dest) const override
Definition: TypeFormat.cpp:140
An data extractor class.
Definition: DataExtractor.h:47
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
lldb::TargetSP GetTargetSP() const
Definition: ValueObject.h:357
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
std::unordered_map< void *, CompilerType > m_types
Definition: TypeFormat.h:210
lldb::addr_t GetPointerValue(AddressType *address_type=nullptr)
A subclass of DataBuffer that stores a data buffer on the heap.
bool FormatObject(ValueObject *valobj, std::string &dest) const override
Definition: TypeFormat.cpp:41
bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope)
#define UINT32_MAX
Definition: lldb-defines.h:31
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
TypeFormatImpl_Format(lldb::Format f=lldb::eFormatInvalid, const TypeFormatImpl::Flags &flags=Flags())
Definition: TypeFormat.cpp:35
static const char * GetFormatAsCString(lldb::Format format)
virtual bool CanProvideValue()
A collection class for Module objects.
Definition: ModuleList.h:91
llvm::StringRef GetString() const
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
ContextType GetContextType() const
Definition: Value.h:152
std::string GetDescription() override
Definition: TypeFormat.cpp:198
const ExecutionContextRef & GetExecutionContextRef() const
Definition: ValueObject.h:353
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool Success() const
Test for success condition.
Definition: Status.cpp:287
TypeFormatImpl_EnumType(ConstString type_name=ConstString(""), const TypeFormatImpl::Flags &flags=Flags())
Definition: TypeFormat.cpp:134
A section + offset based address class.
Definition: Address.h:80
std::string GetDescription() override
Definition: TypeFormat.cpp:125
virtual uint64_t GetData(DataExtractor &data, Status &error)
virtual uint32_t GetBitfieldBitOffset()
Definition: ValueObject.h:441
lldb::offset_t DumpDataExtractor(const DataExtractor &DE, Stream *s, lldb::offset_t offset, lldb::Format item_format, size_t item_byte_size, size_t item_count, size_t num_per_line, uint64_t base_addr, uint32_t item_bit_size, uint32_t item_bit_offset, ExecutionContextScope *exe_scope=nullptr)
Dumps item_count objects into the stream s.
TypeList FindTypes(ConstString name)
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
A class to manage flags.
Definition: Flags.h:22
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
lldb::ProcessSP GetProcessSP() const
Definition: ValueObject.h:361
Definition: SBAddress.h:15
const Value & GetValue() const
lldb::Format GetFormat() const
Definition: TypeFormat.h:168
virtual uint32_t GetBitfieldBitSize()
Definition: ValueObject.h:439
An error handling class.
Definition: Status.h:44