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-public.h"
20 #include "lldb/lldb-enumerations.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) :
39 TypeFormatImpl::~TypeFormatImpl ()
43 TypeFormatImpl_Format::TypeFormatImpl_Format (lldb::Format f,
44 const TypeFormatImpl::Flags& flags) :
45 TypeFormatImpl(flags),
50 TypeFormatImpl_Format::~TypeFormatImpl_Format ()
55 TypeFormatImpl_Format::FormatObject (ValueObject *valobj,
56 std::string& dest) const
60 if (valobj->CanProvideValue())
62 Value& value(valobj->GetValue());
63 const Value::ContextType context_type = value.GetContextType();
64 ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
67 if (context_type == Value::eContextTypeRegisterInfo)
69 const RegisterInfo *reg_info = value.GetRegisterInfo();
73 valobj->GetData(data, error);
77 StreamString reg_sstr;
87 exe_ctx.GetBestExecutionContextScope());
88 dest.swap(reg_sstr.GetString());
93 CompilerType compiler_type = value.GetCompilerType ();
96 // put custom bytes to display in the DataExtractor to override the default value logic
97 if (GetFormat() == eFormatCString)
99 lldb_private::Flags type_flags(compiler_type.GetTypeInfo(NULL)); // disambiguate w.r.t. TypeFormatImpl::Flags
100 if (type_flags.Test(eTypeIsPointer) && !type_flags.Test(eTypeIsObjC))
102 // if we are dumping a pointer as a c-string, get the pointee data as a string
103 TargetSP target_sp(valobj->GetTargetSP());
106 size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
108 DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0));
109 Address address(valobj->GetPointerValue());
110 if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success())
111 data.SetData(buffer_sp);
118 valobj->GetData(data, error);
124 compiler_type.DumpTypeValue (&sstr, // The stream to use for display
125 GetFormat(), // Format to display this type with
126 data, // Data to extract from
127 0, // Byte offset into "m_data"
128 valobj->GetByteSize(), // Byte size of item in "m_data"
129 valobj->GetBitfieldBitSize(), // Bitfield bit size
130 valobj->GetBitfieldBitOffset(), // Bitfield bit offset
131 exe_ctx.GetBestExecutionContextScope());
132 // Given that we do not want to set the ValueObject's m_error
133 // for a formatting error (or else we wouldn't be able to reformat
134 // until a next update), an empty string is treated as a "false"
135 // return from here, but that's about as severe as we get
136 // CompilerType::DumpTypeValue() should always return
137 // something, even if that something is an error message
138 if (sstr.GetString().empty())
141 dest.swap(sstr.GetString());
144 return !dest.empty();
151 TypeFormatImpl_Format::GetDescription()
154 sstr.Printf ("%s%s%s%s",
155 FormatManager::GetFormatAsCString (GetFormat()),
156 Cascades() ? "" : " (not cascading)",
157 SkipsPointers() ? " (skip pointers)" : "",
158 SkipsReferences() ? " (skip references)" : "");
159 return sstr.GetString();
162 TypeFormatImpl_EnumType::TypeFormatImpl_EnumType (ConstString type_name,
163 const TypeFormatImpl::Flags& flags) :
164 TypeFormatImpl(flags),
165 m_enum_type(type_name),
170 TypeFormatImpl_EnumType::~TypeFormatImpl_EnumType ()
175 TypeFormatImpl_EnumType::FormatObject (ValueObject *valobj,
176 std::string& dest) const
181 if (!valobj->CanProvideValue())
183 ProcessSP process_sp;
185 void* valobj_key = (process_sp = valobj->GetProcessSP()).get();
187 valobj_key = (target_sp = valobj->GetTargetSP()).get();
189 target_sp = process_sp->GetTarget().shared_from_this();
192 auto iter = m_types.find(valobj_key),
194 CompilerType valobj_enum_type;
197 // probably a redundant check
200 const ModuleList& images(target_sp->GetImages());
203 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
204 images.FindTypes(sc, m_enum_type, false, UINT32_MAX, searched_symbol_files, types);
205 if (types.GetSize() == 0)
207 for (lldb::TypeSP type_sp : types.Types())
211 if ( (type_sp->GetForwardCompilerType().GetTypeInfo() & eTypeIsEnumeration) == eTypeIsEnumeration)
213 valobj_enum_type = type_sp->GetFullCompilerType ();
214 m_types.emplace(valobj_key,valobj_enum_type);
220 valobj_enum_type = iter->second;
221 if (valobj_enum_type.IsValid() == false)
225 valobj->GetData(data, error);
228 ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
230 valobj_enum_type.DumpTypeValue(&sstr,
237 exe_ctx.GetBestExecutionContextScope());
238 if (!sstr.GetString().empty())
239 dest.swap(sstr.GetString());
240 return !dest.empty();
244 TypeFormatImpl_EnumType::GetDescription()
247 sstr.Printf ("as type %s%s%s%s",
248 m_enum_type.AsCString("<invalid type>"),
249 Cascades() ? "" : " (not cascading)",
250 SkipsPointers() ? " (skip pointers)" : "",
251 SkipsReferences() ? " (skip references)" : "");
252 return sstr.GetString();