1 //===-- TypeFormat.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/DataFormatters/TypeFormat.h"
16 // Other libraries and framework includes
19 #include "lldb/lldb-enumerations.h"
20 #include "lldb/lldb-public.h"
22 #include "lldb/Core/StreamString.h"
23 #include "lldb/DataFormatters/FormatManager.h"
24 #include "lldb/Symbol/CompilerType.h"
25 #include "lldb/Symbol/SymbolContext.h"
26 #include "lldb/Symbol/SymbolFile.h"
27 #include "lldb/Symbol/TypeList.h"
28 #include "lldb/Target/Target.h"
31 using namespace lldb_private;
33 TypeFormatImpl::TypeFormatImpl(const Flags &flags)
34 : m_flags(flags), m_my_revision(0) {}
36 TypeFormatImpl::~TypeFormatImpl() {}
38 TypeFormatImpl_Format::TypeFormatImpl_Format(lldb::Format f,
39 const TypeFormatImpl::Flags &flags)
40 : TypeFormatImpl(flags), m_format(f) {}
42 TypeFormatImpl_Format::~TypeFormatImpl_Format() {}
44 bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj,
45 std::string &dest) const {
48 if (valobj->CanProvideValue()) {
49 Value &value(valobj->GetValue());
50 const Value::ContextType context_type = value.GetContextType();
51 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
54 if (context_type == Value::eContextTypeRegisterInfo) {
55 const RegisterInfo *reg_info = value.GetRegisterInfo();
58 valobj->GetData(data, error);
62 StreamString reg_sstr;
63 data.Dump(®_sstr, 0, GetFormat(), reg_info->byte_size, 1, UINT32_MAX,
64 LLDB_INVALID_ADDRESS, 0, 0,
65 exe_ctx.GetBestExecutionContextScope());
66 dest = reg_sstr.GetString();
69 CompilerType compiler_type = value.GetCompilerType();
71 // put custom bytes to display in the DataExtractor to override the
72 // default value logic
73 if (GetFormat() == eFormatCString) {
74 lldb_private::Flags type_flags(compiler_type.GetTypeInfo(
75 NULL)); // disambiguate w.r.t. TypeFormatImpl::Flags
76 if (type_flags.Test(eTypeIsPointer) &&
77 !type_flags.Test(eTypeIsObjC)) {
78 // if we are dumping a pointer as a c-string, get the pointee data
80 TargetSP target_sp(valobj->GetTargetSP());
82 size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
84 DataBufferSP buffer_sp(new DataBufferHeap(max_len + 1, 0));
85 Address address(valobj->GetPointerValue());
86 if (target_sp->ReadCStringFromMemory(
87 address, (char *)buffer_sp->GetBytes(), max_len, error) &&
89 data.SetData(buffer_sp);
94 valobj->GetData(data, error);
100 ExecutionContextScope *exe_scope(
101 exe_ctx.GetBestExecutionContextScope());
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 compiler_type.GetByteSize(
108 exe_scope), // Byte size of item in "m_data"
109 valobj->GetBitfieldBitSize(), // Bitfield bit size
110 valobj->GetBitfieldBitOffset(), // Bitfield bit offset
112 // Given that we do not want to set the ValueObject's m_error
113 // for a formatting error (or else we wouldn't be able to reformat
114 // until a next update), an empty string is treated as a "false"
115 // return from here, but that's about as severe as we get
116 // CompilerType::DumpTypeValue() should always return
117 // something, even if that something is an error message
118 dest = sstr.GetString();
121 return !dest.empty();
126 std::string TypeFormatImpl_Format::GetDescription() {
128 sstr.Printf("%s%s%s%s", FormatManager::GetFormatAsCString(GetFormat()),
129 Cascades() ? "" : " (not cascading)",
130 SkipsPointers() ? " (skip pointers)" : "",
131 SkipsReferences() ? " (skip references)" : "");
132 return sstr.GetString();
135 TypeFormatImpl_EnumType::TypeFormatImpl_EnumType(
136 ConstString type_name, const TypeFormatImpl::Flags &flags)
137 : TypeFormatImpl(flags), m_enum_type(type_name), m_types() {}
139 TypeFormatImpl_EnumType::~TypeFormatImpl_EnumType() {}
141 bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj,
142 std::string &dest) const {
146 if (!valobj->CanProvideValue())
148 ProcessSP process_sp;
150 void *valobj_key = (process_sp = valobj->GetProcessSP()).get();
152 valobj_key = (target_sp = valobj->GetTargetSP()).get();
154 target_sp = process_sp->GetTarget().shared_from_this();
157 auto iter = m_types.find(valobj_key), end = m_types.end();
158 CompilerType valobj_enum_type;
160 // probably a redundant check
163 const ModuleList &images(target_sp->GetImages());
166 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
167 images.FindTypes(sc, m_enum_type, false, UINT32_MAX, searched_symbol_files,
169 if (types.GetSize() == 0)
171 for (lldb::TypeSP type_sp : types.Types()) {
174 if ((type_sp->GetForwardCompilerType().GetTypeInfo() &
175 eTypeIsEnumeration) == eTypeIsEnumeration) {
176 valobj_enum_type = type_sp->GetFullCompilerType();
177 m_types.emplace(valobj_key, valobj_enum_type);
182 valobj_enum_type = iter->second;
183 if (valobj_enum_type.IsValid() == false)
187 valobj->GetData(data, error);
190 ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
192 valobj_enum_type.DumpTypeValue(&sstr, lldb::eFormatEnum, data, 0,
193 data.GetByteSize(), 0, 0,
194 exe_ctx.GetBestExecutionContextScope());
195 if (!sstr.GetString().empty())
196 dest = sstr.GetString();
197 return !dest.empty();
200 std::string TypeFormatImpl_EnumType::GetDescription() {
202 sstr.Printf("as type %s%s%s%s", m_enum_type.AsCString("<invalid type>"),
203 Cascades() ? "" : " (not cascading)",
204 SkipsPointers() ? " (skip pointers)" : "",
205 SkipsReferences() ? " (skip references)" : "");
206 return sstr.GetString();