VectorType.cpp revision 360784
1//===-- VectorType.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 9#include "lldb/DataFormatters/VectorType.h" 10 11#include "lldb/Core/ValueObject.h" 12#include "lldb/DataFormatters/FormattersHelpers.h" 13#include "lldb/Symbol/CompilerType.h" 14#include "lldb/Symbol/TypeSystem.h" 15#include "lldb/Target/Target.h" 16 17#include "lldb/Utility/LLDBAssert.h" 18#include "lldb/Utility/Log.h" 19 20using namespace lldb; 21using namespace lldb_private; 22using namespace lldb_private::formatters; 23 24static CompilerType GetCompilerTypeForFormat(lldb::Format format, 25 CompilerType element_type, 26 TypeSystem *type_system) { 27 lldbassert(type_system && "type_system needs to be not NULL"); 28 29 switch (format) { 30 case lldb::eFormatAddressInfo: 31 case lldb::eFormatPointer: 32 return type_system->GetBuiltinTypeForEncodingAndBitSize( 33 eEncodingUint, 8 * type_system->GetPointerByteSize()); 34 35 case lldb::eFormatBoolean: 36 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeBool); 37 38 case lldb::eFormatBytes: 39 case lldb::eFormatBytesWithASCII: 40 case lldb::eFormatChar: 41 case lldb::eFormatCharArray: 42 case lldb::eFormatCharPrintable: 43 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar); 44 45 case lldb::eFormatComplex /* lldb::eFormatComplexFloat */: 46 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloatComplex); 47 48 case lldb::eFormatCString: 49 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar) 50 .GetPointerType(); 51 52 case lldb::eFormatFloat: 53 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat); 54 55 case lldb::eFormatHex: 56 case lldb::eFormatHexUppercase: 57 case lldb::eFormatOctal: 58 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeInt); 59 60 case lldb::eFormatHexFloat: 61 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat); 62 63 case lldb::eFormatUnicode16: 64 case lldb::eFormatUnicode32: 65 66 case lldb::eFormatUnsigned: 67 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt); 68 69 case lldb::eFormatVectorOfChar: 70 return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar); 71 72 case lldb::eFormatVectorOfFloat32: 73 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754, 74 32); 75 76 case lldb::eFormatVectorOfFloat64: 77 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754, 78 64); 79 80 case lldb::eFormatVectorOfSInt16: 81 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 16); 82 83 case lldb::eFormatVectorOfSInt32: 84 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32); 85 86 case lldb::eFormatVectorOfSInt64: 87 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64); 88 89 case lldb::eFormatVectorOfSInt8: 90 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 8); 91 92 case lldb::eFormatVectorOfUInt128: 93 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 128); 94 95 case lldb::eFormatVectorOfUInt16: 96 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16); 97 98 case lldb::eFormatVectorOfUInt32: 99 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32); 100 101 case lldb::eFormatVectorOfUInt64: 102 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64); 103 104 case lldb::eFormatVectorOfUInt8: 105 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8); 106 107 case lldb::eFormatDefault: 108 return element_type; 109 110 case lldb::eFormatBinary: 111 case lldb::eFormatComplexInteger: 112 case lldb::eFormatDecimal: 113 case lldb::eFormatEnum: 114 case lldb::eFormatInstruction: 115 case lldb::eFormatOSType: 116 case lldb::eFormatVoid: 117 default: 118 return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8); 119 } 120} 121 122static lldb::Format GetItemFormatForFormat(lldb::Format format, 123 CompilerType element_type) { 124 switch (format) { 125 case lldb::eFormatVectorOfChar: 126 return lldb::eFormatChar; 127 128 case lldb::eFormatVectorOfFloat32: 129 case lldb::eFormatVectorOfFloat64: 130 return lldb::eFormatFloat; 131 132 case lldb::eFormatVectorOfSInt16: 133 case lldb::eFormatVectorOfSInt32: 134 case lldb::eFormatVectorOfSInt64: 135 case lldb::eFormatVectorOfSInt8: 136 return lldb::eFormatDecimal; 137 138 case lldb::eFormatVectorOfUInt128: 139 case lldb::eFormatVectorOfUInt16: 140 case lldb::eFormatVectorOfUInt32: 141 case lldb::eFormatVectorOfUInt64: 142 case lldb::eFormatVectorOfUInt8: 143 return lldb::eFormatUnsigned; 144 145 case lldb::eFormatBinary: 146 case lldb::eFormatComplexInteger: 147 case lldb::eFormatDecimal: 148 case lldb::eFormatEnum: 149 case lldb::eFormatInstruction: 150 case lldb::eFormatOSType: 151 case lldb::eFormatVoid: 152 return eFormatHex; 153 154 case lldb::eFormatDefault: { 155 // special case the (default, char) combination to actually display as an 156 // integer value most often, you won't want to see the ASCII characters... 157 // (and if you do, eFormatChar is a keystroke away) 158 bool is_char = element_type.IsCharType(); 159 bool is_signed = false; 160 element_type.IsIntegerType(is_signed); 161 return is_char ? (is_signed ? lldb::eFormatDecimal : eFormatHex) : format; 162 } break; 163 164 default: 165 return format; 166 } 167} 168 169static size_t CalculateNumChildren( 170 CompilerType container_type, CompilerType element_type, 171 lldb_private::ExecutionContextScope *exe_scope = 172 nullptr // does not matter here because all we trade in are basic types 173 ) { 174 llvm::Optional<uint64_t> container_size = 175 container_type.GetByteSize(exe_scope); 176 llvm::Optional<uint64_t> element_size = element_type.GetByteSize(exe_scope); 177 178 if (container_size && element_size && *element_size) { 179 if (*container_size % *element_size) 180 return 0; 181 return *container_size / *element_size; 182 } 183 return 0; 184} 185 186namespace lldb_private { 187namespace formatters { 188 189class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd { 190public: 191 VectorTypeSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) 192 : SyntheticChildrenFrontEnd(*valobj_sp), m_parent_format(eFormatInvalid), 193 m_item_format(eFormatInvalid), m_child_type(), m_num_children(0) {} 194 195 ~VectorTypeSyntheticFrontEnd() override = default; 196 197 size_t CalculateNumChildren() override { return m_num_children; } 198 199 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { 200 if (idx >= CalculateNumChildren()) 201 return {}; 202 llvm::Optional<uint64_t> size = m_child_type.GetByteSize(nullptr); 203 if (!size) 204 return {}; 205 auto offset = idx * *size; 206 StreamString idx_name; 207 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); 208 ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset( 209 offset, m_child_type, true, ConstString(idx_name.GetString()))); 210 if (!child_sp) 211 return child_sp; 212 213 child_sp->SetFormat(m_item_format); 214 215 return child_sp; 216 } 217 218 bool Update() override { 219 m_parent_format = m_backend.GetFormat(); 220 CompilerType parent_type(m_backend.GetCompilerType()); 221 CompilerType element_type; 222 parent_type.IsVectorType(&element_type, nullptr); 223 TypeSystem *type_system = nullptr; 224 if (auto target_sp = m_backend.GetTargetSP()) { 225 auto type_system_or_err = 226 target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC); 227 if (auto err = type_system_or_err.takeError()) { 228 LLDB_LOG_ERROR( 229 lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS), 230 std::move(err), "Unable to update from scratch TypeSystem"); 231 } else { 232 type_system = &type_system_or_err.get(); 233 } 234 } 235 m_child_type = 236 ::GetCompilerTypeForFormat(m_parent_format, element_type, type_system); 237 m_num_children = ::CalculateNumChildren(parent_type, m_child_type); 238 m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type); 239 return false; 240 } 241 242 bool MightHaveChildren() override { return true; } 243 244 size_t GetIndexOfChildWithName(ConstString name) override { 245 const char *item_name = name.GetCString(); 246 uint32_t idx = ExtractIndexFromString(item_name); 247 if (idx < UINT32_MAX && idx >= CalculateNumChildren()) 248 return UINT32_MAX; 249 return idx; 250 } 251 252private: 253 lldb::Format m_parent_format; 254 lldb::Format m_item_format; 255 CompilerType m_child_type; 256 size_t m_num_children; 257}; 258 259} // namespace formatters 260} // namespace lldb_private 261 262bool lldb_private::formatters::VectorTypeSummaryProvider( 263 ValueObject &valobj, Stream &s, const TypeSummaryOptions &) { 264 auto synthetic_children = 265 VectorTypeSyntheticFrontEndCreator(nullptr, valobj.GetSP()); 266 if (!synthetic_children) 267 return false; 268 269 synthetic_children->Update(); 270 271 s.PutChar('('); 272 bool first = true; 273 274 size_t idx = 0, len = synthetic_children->CalculateNumChildren(); 275 276 for (; idx < len; idx++) { 277 auto child_sp = synthetic_children->GetChildAtIndex(idx); 278 if (!child_sp) 279 continue; 280 child_sp = child_sp->GetQualifiedRepresentationIfAvailable( 281 lldb::eDynamicDontRunTarget, true); 282 283 const char *child_value = child_sp->GetValueAsCString(); 284 if (child_value && *child_value) { 285 if (first) { 286 s.Printf("%s", child_value); 287 first = false; 288 } else { 289 s.Printf(", %s", child_value); 290 } 291 } 292 } 293 294 s.PutChar(')'); 295 296 return true; 297} 298 299lldb_private::SyntheticChildrenFrontEnd * 300lldb_private::formatters::VectorTypeSyntheticFrontEndCreator( 301 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { 302 if (!valobj_sp) 303 return nullptr; 304 return new VectorTypeSyntheticFrontEnd(valobj_sp); 305} 306