1 //===-- VectorType.cpp ----------------------------------------------------===// 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 20 using namespace lldb; 21 using namespace lldb_private; 22 using namespace lldb_private::formatters; 23 24 static 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 122 static 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 169 static 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 186 namespace lldb_private { 187 namespace formatters { 188 189 class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd { 190 public: 191 VectorTypeSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) 192 : SyntheticChildrenFrontEnd(*valobj_sp), m_child_type() {} 193 194 ~VectorTypeSyntheticFrontEnd() override = default; 195 196 size_t CalculateNumChildren() override { return m_num_children; } 197 198 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { 199 if (idx >= CalculateNumChildren()) 200 return {}; 201 llvm::Optional<uint64_t> size = m_child_type.GetByteSize(nullptr); 202 if (!size) 203 return {}; 204 auto offset = idx * *size; 205 StreamString idx_name; 206 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); 207 ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset( 208 offset, m_child_type, true, ConstString(idx_name.GetString()))); 209 if (!child_sp) 210 return child_sp; 211 212 child_sp->SetFormat(m_item_format); 213 214 return child_sp; 215 } 216 217 bool Update() override { 218 m_parent_format = m_backend.GetFormat(); 219 CompilerType parent_type(m_backend.GetCompilerType()); 220 CompilerType element_type; 221 parent_type.IsVectorType(&element_type); 222 m_child_type = ::GetCompilerTypeForFormat(m_parent_format, element_type, 223 parent_type.GetTypeSystem()); 224 m_num_children = ::CalculateNumChildren(parent_type, m_child_type); 225 m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type); 226 return false; 227 } 228 229 bool MightHaveChildren() override { return true; } 230 231 size_t GetIndexOfChildWithName(ConstString name) override { 232 const char *item_name = name.GetCString(); 233 uint32_t idx = ExtractIndexFromString(item_name); 234 if (idx < UINT32_MAX && idx >= CalculateNumChildren()) 235 return UINT32_MAX; 236 return idx; 237 } 238 239 private: 240 lldb::Format m_parent_format = eFormatInvalid; 241 lldb::Format m_item_format = eFormatInvalid; 242 CompilerType m_child_type; 243 size_t m_num_children = 0; 244 }; 245 246 } // namespace formatters 247 } // namespace lldb_private 248 249 bool lldb_private::formatters::VectorTypeSummaryProvider( 250 ValueObject &valobj, Stream &s, const TypeSummaryOptions &) { 251 auto synthetic_children = 252 VectorTypeSyntheticFrontEndCreator(nullptr, valobj.GetSP()); 253 if (!synthetic_children) 254 return false; 255 256 synthetic_children->Update(); 257 258 s.PutChar('('); 259 bool first = true; 260 261 size_t idx = 0, len = synthetic_children->CalculateNumChildren(); 262 263 for (; idx < len; idx++) { 264 auto child_sp = synthetic_children->GetChildAtIndex(idx); 265 if (!child_sp) 266 continue; 267 child_sp = child_sp->GetQualifiedRepresentationIfAvailable( 268 lldb::eDynamicDontRunTarget, true); 269 270 const char *child_value = child_sp->GetValueAsCString(); 271 if (child_value && *child_value) { 272 if (first) { 273 s.Printf("%s", child_value); 274 first = false; 275 } else { 276 s.Printf(", %s", child_value); 277 } 278 } 279 } 280 281 s.PutChar(')'); 282 283 return true; 284 } 285 286 lldb_private::SyntheticChildrenFrontEnd * 287 lldb_private::formatters::VectorTypeSyntheticFrontEndCreator( 288 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { 289 if (!valobj_sp) 290 return nullptr; 291 return new VectorTypeSyntheticFrontEnd(valobj_sp); 292 } 293