27std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
29 static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
36 static constexpr llvm::StringLiteral g_TypeHint(
"NSString");
50 if (!descriptor.get() || !descriptor->IsValid())
53 uint32_t ptr_size = process_sp->GetAddressByteSize();
60 ConstString class_name_cs = descriptor->GetClassName();
61 llvm::StringRef class_name = class_name_cs.
GetStringRef();
63 if (class_name.empty())
66 bool is_tagged_ptr = class_name ==
"NSTaggedPointerString" &&
67 descriptor->GetTaggedPointerInfo();
74 auto iter = additionals_map.find(class_name_cs), end = additionals_map.end();
76 return iter->second(valobj, stream, summary_options);
79 uint64_t info_bits_location = valobj_addr + ptr_size;
81 info_bits_location += 3;
85 uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(
86 info_bits_location, 1, 0,
error);
90 bool is_mutable = (info_bits & 1) == 1;
91 bool is_inline = (info_bits & 0x60) == 0;
92 bool has_explicit_length = (info_bits & (1 | 4)) != 4;
93 bool is_unicode = (info_bits & 0x10) == 0x10;
94 bool is_path_store = class_name ==
"NSPathStore2";
95 bool has_null = (info_bits & 8) == 8;
97 size_t explicit_length = 0;
98 if (!has_null && has_explicit_length && !is_path_store) {
100 if (is_mutable && !is_inline)
101 explicit_length_offset =
102 explicit_length_offset + ptr_size;
104 explicit_length = explicit_length + 0;
105 else if (!is_inline && !is_mutable)
106 explicit_length_offset =
107 explicit_length_offset + ptr_size;
109 explicit_length_offset = 0;
111 if (explicit_length_offset) {
112 explicit_length_offset = valobj_addr + explicit_length_offset;
113 explicit_length = process_sp->ReadUnsignedIntegerFromMemory(
114 explicit_length_offset, 4, 0,
error);
118 const llvm::StringSet<> supported_string_classes = {
119 "NSString",
"CFMutableStringRef",
120 "CFStringRef",
"__NSCFConstantString",
121 "__NSCFString",
"NSCFConstantString",
122 "NSCFString",
"NSPathStore2"};
123 if (supported_string_classes.count(class_name) == 0) {
129 llvm::StringRef prefix, suffix;
131 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
138 uint64_t location = 2 * ptr_size + valobj_addr;
139 location = process_sp->ReadPointerFromMemory(location,
error);
142 if (has_explicit_length && is_unicode) {
151 TypeSummaryCapping::eTypeSummaryUncapped);
154 StringPrinter::StringElementType::UTF16>(options);
163 TypeSummaryCapping::eTypeSummaryUncapped);
166 StringPrinter::StringElementType::ASCII>(options);
168 }
else if (is_inline && has_explicit_length && !is_unicode &&
169 !is_path_store && !is_mutable) {
170 uint64_t location = 3 * ptr_size + valobj_addr;
179 TypeSummaryCapping::eTypeSummaryUncapped);
181 StringPrinter::StringElementType::ASCII>(options);
182 }
else if (is_unicode) {
183 uint64_t location = valobj_addr + 2 * ptr_size;
185 if (!has_explicit_length) {
188 location += ptr_size;
190 location = process_sp->ReadPointerFromMemory(location,
error);
202 TypeSummaryCapping::eTypeSummaryUncapped);
205 StringPrinter::StringElementType::UTF16>(options);
206 }
else if (is_path_store) {
208 uint64_t length_ivar_offset = 1 * ptr_size;
214 if (!length_valobj_sp)
217 explicit_length = length_valobj_sp->GetValueAsUnsigned(0) >> 20;
228 TypeSummaryCapping::eTypeSummaryUncapped);
231 StringPrinter::StringElementType::UTF16>(options);
232 }
else if (is_inline) {
233 uint64_t location = valobj_addr + 2 * ptr_size;
234 if (!has_explicit_length) {
239 process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0,
error);
240 has_explicit_length = !(
error.Fail() || explicit_length == 0);
250 TypeSummaryCapping::eTypeSummaryUncapped);
252 if (has_explicit_length)
254 StringPrinter::StringElementType::UTF8>(options);
257 StringPrinter::StringElementType::ASCII>(options);
259 uint64_t location = valobj_addr + 2 * ptr_size;
260 location = process_sp->ReadPointerFromMemory(location,
error);
263 if (has_explicit_length && !has_null)
272 TypeSummaryCapping::eTypeSummaryUncapped);
274 StringPrinter::StringElementType::ASCII>(options);
283 uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
287 pointer_value += addr_size;
291 "string_ptr", pointer_value, exe_ctx, type));
296 child_ptr_sp->GetData(data,
error);
299 ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData(
300 "string_data", data, exe_ctx, type));
301 child_sp->GetValueAsUnsigned(0);
315 static constexpr llvm::StringLiteral g_TypeHint(
"NSString");
319 uint64_t len_bits = 0, data_bits = 0;
320 if (!descriptor->GetTaggedPointerInfo(&len_bits, &data_bits,
nullptr))
323 static const int g_MaxNonBitmaskedLen = 7;
324 static const int g_SixbitMaxLen = 9;
325 static const int g_fiveBitMaxLen = 11;
327 static const char *sixBitToCharLookup =
"eilotrm.apdnsIc ufkMShjTRxgC4013"
328 "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
330 if (len_bits > g_fiveBitMaxLen)
333 llvm::StringRef prefix, suffix;
335 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
340 if (len_bits <= g_MaxNonBitmaskedLen) {
342 stream.
Printf(
"\"%s\"", (
const char *)&data_bits);
349 uint8_t shift_offset = 0;
351 if (len_bits <= g_SixbitMaxLen) {
359 std::vector<uint8_t> bytes;
360 bytes.resize(len_bits);
361 for (; len_bits > 0; data_bits >>= shift_offset, --len_bits) {
362 uint8_t packed = data_bits & bitmask;
363 bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
367 stream.
Printf(
"\"%s\"", &bytes[0]);
static llvm::raw_ostream & error(Stream &strm)
Generic representation of a type in a programming language.
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
Create related types using the current type's AST.
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
static Language * FindPlugin(lldb::LanguageType language)
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
static ObjCLanguageRuntime * Get(Process &process)
virtual ClassDescriptorSP GetClassDescriptor(ValueObject &in_value)
A stream class that can stream formatted output to a file.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
lldb::LanguageType GetLanguage() const
lldb::TypeSummaryCapping GetCapping() const
CompilerType GetCompilerType()
lldb::ProcessSP GetProcessSP() const
virtual lldb::ValueObjectSP GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type, bool can_create, ConstString name_const_str=ConstString())
static lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type, bool do_deref=true)
Given an address either create a value object containing the value at that address,...
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
lldb::TargetSP GetTargetSP() const
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Target > TargetSP