1//===-- TypeFormat.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 "lldb/lldb-python.h" 11 12// C Includes 13 14// C++ Includes 15 16// Other libraries and framework includes 17 18// Project includes 19#include "lldb/lldb-public.h" 20#include "lldb/lldb-enumerations.h" 21 22#include "lldb/Core/Debugger.h" 23#include "lldb/Core/StreamString.h" 24#include "lldb/Core/Timer.h" 25#include "lldb/DataFormatters/TypeFormat.h" 26#include "lldb/Interpreter/CommandInterpreter.h" 27#include "lldb/Symbol/ClangASTType.h" 28#include "lldb/Symbol/TypeList.h" 29#include "lldb/Target/StackFrame.h" 30#include "lldb/Target/Target.h" 31 32using namespace lldb; 33using namespace lldb_private; 34 35TypeFormatImpl::TypeFormatImpl (const Flags& flags) : 36m_flags(flags), 37m_my_revision(0) 38{ 39} 40 41 42TypeFormatImpl_Format::TypeFormatImpl_Format (lldb::Format f, 43 const TypeFormatImpl::Flags& flags) : 44TypeFormatImpl(flags), 45m_format (f) 46{ 47} 48 49bool 50TypeFormatImpl_Format::FormatObject (ValueObject *valobj, 51 std::string& dest) const 52{ 53 if (!valobj) 54 return false; 55 if (valobj->GetClangType().IsAggregateType () == false) 56 { 57 const Value& value(valobj->GetValue()); 58 const Value::ContextType context_type = value.GetContextType(); 59 ExecutionContext exe_ctx (valobj->GetExecutionContextRef()); 60 DataExtractor data; 61 62 if (context_type == Value::eContextTypeRegisterInfo) 63 { 64 const RegisterInfo *reg_info = value.GetRegisterInfo(); 65 if (reg_info) 66 { 67 valobj->GetData(data); 68 69 StreamString reg_sstr; 70 data.Dump (®_sstr, 71 0, 72 GetFormat(), 73 reg_info->byte_size, 74 1, 75 UINT32_MAX, 76 LLDB_INVALID_ADDRESS, 77 0, 78 0, 79 exe_ctx.GetBestExecutionContextScope()); 80 dest.swap(reg_sstr.GetString()); 81 } 82 } 83 else 84 { 85 ClangASTType clang_type = valobj->GetClangType (); 86 if (clang_type) 87 { 88 // put custom bytes to display in the DataExtractor to override the default value logic 89 if (GetFormat() == eFormatCString) 90 { 91 lldb_private::Flags type_flags(clang_type.GetTypeInfo(NULL)); // disambiguate w.r.t. TypeFormatImpl::Flags 92 if (type_flags.Test(ClangASTType::eTypeIsPointer) && !type_flags.Test(ClangASTType::eTypeIsObjC)) 93 { 94 // if we are dumping a pointer as a c-string, get the pointee data as a string 95 TargetSP target_sp(valobj->GetTargetSP()); 96 if (target_sp) 97 { 98 size_t max_len = target_sp->GetMaximumSizeOfStringSummary(); 99 Error error; 100 DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0)); 101 Address address(valobj->GetPointerValue()); 102 if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success()) 103 data.SetData(buffer_sp); 104 } 105 } 106 } 107 else 108 valobj->GetData(data); 109 110 StreamString sstr; 111 clang_type.DumpTypeValue (&sstr, // The stream to use for display 112 GetFormat(), // Format to display this type with 113 data, // Data to extract from 114 0, // Byte offset into "m_data" 115 valobj->GetByteSize(), // Byte size of item in "m_data" 116 valobj->GetBitfieldBitSize(), // Bitfield bit size 117 valobj->GetBitfieldBitOffset(), // Bitfield bit offset 118 exe_ctx.GetBestExecutionContextScope()); 119 // Given that we do not want to set the ValueObject's m_error 120 // for a formatting error (or else we wouldn't be able to reformat 121 // until a next update), an empty string is treated as a "false" 122 // return from here, but that's about as severe as we get 123 // ClangASTType::DumpTypeValue() should always return 124 // something, even if that something is an error message 125 if (sstr.GetString().empty()) 126 dest.clear(); 127 else 128 dest.swap(sstr.GetString()); 129 } 130 } 131 return !dest.empty(); 132 } 133 else 134 return false; 135} 136 137std::string 138TypeFormatImpl_Format::GetDescription() 139{ 140 StreamString sstr; 141 sstr.Printf ("%s%s%s%s", 142 FormatManager::GetFormatAsCString (GetFormat()), 143 Cascades() ? "" : " (not cascading)", 144 SkipsPointers() ? " (skip pointers)" : "", 145 SkipsReferences() ? " (skip references)" : ""); 146 return sstr.GetString(); 147} 148 149TypeFormatImpl_EnumType::TypeFormatImpl_EnumType (ConstString type_name, 150 const TypeFormatImpl::Flags& flags) : 151TypeFormatImpl(flags), 152m_enum_type(type_name), 153m_types() 154{ 155} 156 157bool 158TypeFormatImpl_EnumType::FormatObject (ValueObject *valobj, 159 std::string& dest) const 160{ 161 dest.clear(); 162 if (!valobj) 163 return false; 164 if (valobj->GetClangType().IsAggregateType ()) 165 return false; 166 ProcessSP process_sp; 167 TargetSP target_sp; 168 void* valobj_key = (process_sp = valobj->GetProcessSP()).get(); 169 if (!valobj_key) 170 valobj_key = (target_sp = valobj->GetTargetSP()).get(); 171 else 172 target_sp = process_sp->GetTarget().shared_from_this(); 173 if (!valobj_key) 174 return false; 175 auto iter = m_types.find(valobj_key), 176 end = m_types.end(); 177 ClangASTType valobj_enum_type; 178 if (iter == end) 179 { 180 // probably a redundant check 181 if (!target_sp) 182 return false; 183 const ModuleList& images(target_sp->GetImages()); 184 SymbolContext sc; 185 TypeList types; 186 images.FindTypes(sc, m_enum_type, false, UINT32_MAX, types); 187 if (types.GetSize() == 0) 188 return false; 189 for (lldb::TypeSP type_sp : types.Types()) 190 { 191 if (!type_sp) 192 continue; 193 if ( (type_sp->GetClangForwardType().GetTypeInfo() & ClangASTType::eTypeIsEnumeration) == ClangASTType::eTypeIsEnumeration) 194 { 195 valobj_enum_type = type_sp->GetClangFullType(); 196 m_types.emplace(valobj_key,valobj_enum_type); 197 break; 198 } 199 } 200 } 201 else 202 valobj_enum_type = iter->second; 203 if (valobj_enum_type.IsValid() == false) 204 return false; 205 DataExtractor data; 206 valobj->GetData(data); 207 ExecutionContext exe_ctx (valobj->GetExecutionContextRef()); 208 StreamString sstr; 209 valobj_enum_type.DumpTypeValue(&sstr, 210 lldb::eFormatEnum, 211 data, 212 0, 213 data.GetByteSize(), 214 0, 215 0, 216 exe_ctx.GetBestExecutionContextScope()); 217 if (!sstr.GetString().empty()) 218 dest.swap(sstr.GetString()); 219 return !dest.empty(); 220} 221 222std::string 223TypeFormatImpl_EnumType::GetDescription() 224{ 225 StreamString sstr; 226 sstr.Printf ("as type %s%s%s%s", 227 m_enum_type.AsCString("<invalid type>"), 228 Cascades() ? "" : " (not cascading)", 229 SkipsPointers() ? " (skip pointers)" : "", 230 SkipsReferences() ? " (skip references)" : ""); 231 return sstr.GetString(); 232} 233