38 static constexpr llvm::StringLiteral g_TypeHint(
"NSString");
52 if (!descriptor.get() || !descriptor->IsValid())
55 uint32_t ptr_size = process_sp->GetAddressByteSize();
62 llvm::StringRef class_name = descriptor->GetClassName();
64 if (class_name.empty())
68 bool is_tagged = descriptor->GetTaggedPointerInfo();
70 if (class_name ==
"NSTaggedPointerString")
74 if (class_name ==
"NSIndirectTaggedPointerString")
80 auto iter = additionals_map.find(class_name), end = additionals_map.end();
82 return iter->second(valobj, stream, summary_options);
85 uint64_t info_bits_location = valobj_addr + ptr_size;
87 info_bits_location += 3;
91 uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(
92 info_bits_location, 1, 0,
error);
96 bool is_mutable = (info_bits & 1) == 1;
97 bool is_inline = (info_bits & 0x60) == 0;
98 bool has_explicit_length = (info_bits & (1 | 4)) != 4;
99 bool is_unicode = (info_bits & 0x10) == 0x10;
100 bool is_path_store = class_name ==
"NSPathStore2";
101 bool has_null = (info_bits & 8) == 8;
103 size_t explicit_length = 0;
104 if (!has_null && has_explicit_length && !is_path_store) {
106 if (is_mutable && !is_inline)
107 explicit_length_offset =
108 explicit_length_offset + ptr_size;
110 explicit_length = explicit_length + 0;
111 else if (!is_inline && !is_mutable)
112 explicit_length_offset =
113 explicit_length_offset + ptr_size;
115 explicit_length_offset = 0;
117 if (explicit_length_offset) {
118 explicit_length_offset = valobj_addr + explicit_length_offset;
119 explicit_length = process_sp->ReadUnsignedIntegerFromMemory(
120 explicit_length_offset, 4, 0,
error);
124 const llvm::StringSet<> supported_string_classes = {
125 "NSString",
"CFMutableStringRef",
126 "CFStringRef",
"__NSCFConstantString",
127 "__NSCFString",
"NSCFConstantString",
128 "NSCFString",
"NSPathStore2"};
129 if (supported_string_classes.count(class_name) == 0) {
131 stream.
Format(
"class name = {0}", class_name);
135 llvm::StringRef prefix, suffix;
137 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
144 uint64_t location = 2 * ptr_size + valobj_addr;
145 llvm::Expected<lldb::addr_t> location_or_err =
146 process_sp->ReadPointerFromMemory(location);
147 if (!location_or_err) {
148 llvm::consumeError(location_or_err.takeError());
151 location = *location_or_err;
152 if (has_explicit_length && is_unicode) {
163 StringPrinter::StringElementType::UTF16>(options);
174 StringPrinter::StringElementType::ASCII>(options);
176 }
else if (is_inline && has_explicit_length && !is_unicode &&
177 !is_path_store && !is_mutable) {
178 uint64_t location = 3 * ptr_size + valobj_addr;
189 StringPrinter::StringElementType::ASCII>(options);
190 }
else if (is_unicode) {
191 uint64_t location = valobj_addr + 2 * ptr_size;
193 if (!has_explicit_length) {
196 location += ptr_size;
198 llvm::Expected<lldb::addr_t> location_or_err =
199 process_sp->ReadPointerFromMemory(location);
200 if (!location_or_err) {
201 llvm::consumeError(location_or_err.takeError());
204 location = *location_or_err;
212 if (has_explicit_length)
219 StringPrinter::StringElementType::UTF16>(options);
220 }
else if (is_path_store) {
222 uint64_t length_ivar_offset = 1 * ptr_size;
228 if (!length_valobj_sp)
231 explicit_length = length_valobj_sp->GetValueAsUnsigned(0) >> 20;
240 if (has_explicit_length)
247 StringPrinter::StringElementType::UTF16>(options);
248 }
else if (is_inline) {
249 uint64_t location = valobj_addr + 2 * ptr_size;
250 if (!has_explicit_length) {
255 process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0,
error);
256 has_explicit_length = !(
error.Fail() || explicit_length == 0);
264 if (has_explicit_length)
270 if (has_explicit_length)
272 StringPrinter::StringElementType::UTF8>(options);
275 StringPrinter::StringElementType::ASCII>(options);
277 uint64_t location = valobj_addr + 2 * ptr_size;
278 llvm::Expected<lldb::addr_t> location_or_err =
279 process_sp->ReadPointerFromMemory(location);
280 if (!location_or_err) {
281 llvm::consumeError(location_or_err.takeError());
284 location = *location_or_err;
285 if (has_explicit_length && !has_null)
296 StringPrinter::StringElementType::ASCII>(options);
337 static constexpr llvm::StringLiteral g_TypeHint(
"NSString");
341 uint64_t len_bits = 0, data_bits = 0;
342 if (!descriptor->GetTaggedPointerInfo(&len_bits, &data_bits,
nullptr))
345 static const int g_MaxNonBitmaskedLen = 7;
346 static const int g_SixbitMaxLen = 9;
347 static const int g_fiveBitMaxLen = 11;
349 static const char *sixBitToCharLookup =
"eilotrm.apdnsIc ufkMShjTRxgC4013"
350 "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
352 if (len_bits > g_fiveBitMaxLen)
355 llvm::StringRef prefix, suffix;
357 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
362 if (len_bits <= g_MaxNonBitmaskedLen) {
364 stream.
Printf(
"\"%s\"", (
const char *)&data_bits);
371 uint8_t shift_offset = 0;
373 if (len_bits <= g_SixbitMaxLen) {
381 std::vector<uint8_t> bytes;
382 bytes.resize(len_bits);
383 for (; len_bits > 0; data_bits >>= shift_offset, --len_bits) {
384 uint8_t packed = data_bits & bitmask;
385 bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
389 stream.
Printf(
"\"%s\"", &bytes[0]);
"lldb/Target/ExecutionContext.h" A class that contains an execution context.