27std::map<ConstString, CXXFunctionSummaryFormat::Callback> &
29 static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
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 std::string prefix, suffix;
132 if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
144 uint64_t location = 2 * ptr_size + valobj_addr;
145 location = process_sp->ReadPointerFromMemory(location,
error);
148 if (has_explicit_length && is_unicode) {
157 TypeSummaryCapping::eTypeSummaryUncapped);
160 StringPrinter::StringElementType::UTF16>(options);
169 TypeSummaryCapping::eTypeSummaryUncapped);
172 StringPrinter::StringElementType::ASCII>(options);
174 }
else if (is_inline && has_explicit_length && !is_unicode &&
175 !is_path_store && !is_mutable) {
176 uint64_t location = 3 * ptr_size + valobj_addr;
185 TypeSummaryCapping::eTypeSummaryUncapped);
187 StringPrinter::StringElementType::ASCII>(options);
188 }
else if (is_unicode) {
189 uint64_t location = valobj_addr + 2 * ptr_size;
191 if (!has_explicit_length) {
194 location += ptr_size;
196 location = process_sp->ReadPointerFromMemory(location,
error);
208 TypeSummaryCapping::eTypeSummaryUncapped);
211 StringPrinter::StringElementType::UTF16>(options);
212 }
else if (is_path_store) {
214 uint64_t length_ivar_offset = 1 * ptr_size;
217 ValueObjectSP length_valobj_sp =
220 if (!length_valobj_sp)
223 explicit_length = length_valobj_sp->GetValueAsUnsigned(0) >> 20;
234 TypeSummaryCapping::eTypeSummaryUncapped);
237 StringPrinter::StringElementType::UTF16>(options);
238 }
else if (is_inline) {
239 uint64_t location = valobj_addr + 2 * ptr_size;
240 if (!has_explicit_length) {
245 process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0,
error);
246 has_explicit_length = !(
error.Fail() || explicit_length == 0);
256 TypeSummaryCapping::eTypeSummaryUncapped);
258 if (has_explicit_length)
260 StringPrinter::StringElementType::UTF8>(options);
263 StringPrinter::StringElementType::ASCII>(options);
265 uint64_t location = valobj_addr + 2 * ptr_size;
266 location = process_sp->ReadPointerFromMemory(location,
error);
269 if (has_explicit_length && !has_null)
278 TypeSummaryCapping::eTypeSummaryUncapped);
280 StringPrinter::StringElementType::ASCII>(options);
289 uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
293 pointer_value += addr_size;
297 "string_ptr", pointer_value, exe_ctx, type));
302 child_ptr_sp->GetData(data,
error);
305 ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData(
306 "string_data", data, exe_ctx, type));
307 child_sp->GetValueAsUnsigned(0);
325 uint64_t len_bits = 0, data_bits = 0;
326 if (!descriptor->GetTaggedPointerInfo(&len_bits, &data_bits,
nullptr))
329 static const int g_MaxNonBitmaskedLen = 7;
330 static const int g_SixbitMaxLen = 9;
331 static const int g_fiveBitMaxLen = 11;
333 static const char *sixBitToCharLookup =
"eilotrm.apdnsIc ufkMShjTRxgC4013"
334 "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
336 if (len_bits > g_fiveBitMaxLen)
339 std::string prefix, suffix;
342 if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
352 if (len_bits <= g_MaxNonBitmaskedLen) {
353 stream.
Printf(
"%s", prefix.c_str());
354 stream.
Printf(
"\"%s\"", (
const char *)&data_bits);
355 stream.
Printf(
"%s", suffix.c_str());
361 uint8_t shift_offset = 0;
363 if (len_bits <= g_SixbitMaxLen) {
371 std::vector<uint8_t> bytes;
372 bytes.resize(len_bits);
373 for (; len_bits > 0; data_bits >>= shift_offset, --len_bits) {
374 uint8_t packed = data_bits & bitmask;
375 bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
378 stream.
Printf(
"%s", prefix.c_str());
379 stream.
Printf(
"\"%s\"", &bytes[0]);
380 stream.
Printf(
"%s", suffix.c_str());
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())
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
lldb::TargetSP GetTargetSP() const
static lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type)
A class that represents a running process on the host machine.