23#include "llvm/ADT/StringMap.h"
24#include "llvm/Support/Error.h"
30llvm::StringMap<CXXFunctionSummaryFormat::Callback> &
32 static llvm::StringMap<CXXFunctionSummaryFormat::Callback> g_map;
36llvm::StringMap<CXXSyntheticChildren::CreateFrontEndCallback> &
38 static llvm::StringMap<CXXSyntheticChildren::CreateFrontEndCallback> g_map;
106template <
typename D32,
typename D64>
153 struct DataDescriptor_32 {
160 struct DataDescriptor_64 {
172 struct DataDescriptor_32 {
181 struct DataDescriptor_64 {
193 template <
typename DD>
199 DD descriptor = DD();
200 process.
ReadMemory(start_of_descriptor, &descriptor,
sizeof(descriptor),
205 return descriptor._used;
221template <
bool cf_style>
224 static constexpr llvm::StringLiteral g_TypeHint(
"NSSet");
238 if (!descriptor || !descriptor->IsValid())
241 uint32_t ptr_size = process_sp->GetAddressByteSize();
242 bool is_64bit = (ptr_size == 8);
251 llvm::StringRef class_name(descriptor->GetClassName());
253 static constexpr llvm::StringLiteral g_SetI(
"__NSSetI");
254 static constexpr llvm::StringLiteral g_OrderedSetI(
"__NSOrderedSetI");
255 static constexpr llvm::StringLiteral g_SetM(
"__NSSetM");
256 static constexpr llvm::StringLiteral g_SetCF(
"__NSCFSet");
257 static constexpr llvm::StringLiteral g_SetCFRef(
"CFSetRef");
259 if (class_name.empty())
262 if (class_name == g_SetI || class_name == g_OrderedSetI) {
264 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
268 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
269 }
else if (class_name == g_SetM) {
271 llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
276 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
278 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
282 }
else if (class_name == g_SetCF || class_name == g_SetCFRef) {
285 if (!cfbh.
Update(valobj_addr, exe_ctx))
290 auto iter = map.find(class_name), end = map.end();
292 return iter->second(valobj, stream, options);
297 llvm::StringRef prefix, suffix;
299 std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint);
302 stream.
Printf(
"%" PRIu64
" %s%s", value,
"element", value == 1 ?
"" :
"s");
318 Flags flags(valobj_type.GetTypeInfo());
320 if (flags.IsClear(eTypeIsPointer)) {
322 valobj_sp = valobj_sp->AddressOf(
error);
323 if (
error.Fail() || !valobj_sp)
330 if (!descriptor || !descriptor->IsValid())
333 llvm::StringRef class_name = descriptor->GetClassName();
335 static constexpr llvm::StringLiteral g_SetI(
"__NSSetI");
336 static constexpr llvm::StringLiteral g_OrderedSetI(
"__NSOrderedSetI");
337 static constexpr llvm::StringLiteral g_SetM(
"__NSSetM");
338 static constexpr llvm::StringLiteral g_SetCF(
"__NSCFSet");
339 static constexpr llvm::StringLiteral g_SetCFRef(
"CFSetRef");
341 if (class_name.empty())
344 if (class_name == g_SetI || class_name == g_OrderedSetI) {
346 }
else if (class_name == g_SetM) {
347 AppleObjCRuntime *apple_runtime =
348 llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
359 }
else if (class_name == g_SetCF || class_name == g_SetCFRef) {
360 return (
new NSCFSetSyntheticFrontEnd(valobj_sp));
363 auto iter = map.find(class_name), end = map.end();
365 return iter->second(synth, valobj_sp);
384llvm::Expected<uint32_t>
406 m_ptr_size = process_sp->GetAddressByteSize();
407 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) +
m_ptr_size;
429 if (idx >= num_children)
441 uint32_t test_idx = 0;
443 while (tries < num_children) {
447 llvm::Expected<lldb::addr_t> obj_at_idx_or_err =
448 process_sp->ReadPointerFromMemory(obj_at_idx);
449 if (!obj_at_idx_or_err) {
450 llvm::consumeError(obj_at_idx_or_err.takeError());
453 obj_at_idx = *obj_at_idx_or_err;
472 auto ptr_size = process_sp->GetAddressByteSize();
478 *
reinterpret_cast<uint32_t *
>(buffer.
GetBytes()) =
479 static_cast<uint32_t
>(set_item.
item_ptr);
482 *
reinterpret_cast<uint64_t *
>(buffer.
GetBytes()) =
483 static_cast<uint64_t
>(set_item.
item_ptr);
486 lldbassert(
false &&
"pointer size is not 4 nor 8");
489 idx_name.
Printf(
"[%" PRIu64
"]", (uint64_t)idx);
492 process_sp->GetByteOrder(),
493 process_sp->GetAddressByteSize());
497 m_backend.GetCompilerType().GetBasicTypeFromAST(
508llvm::Expected<uint32_t>
527 m_ptr_size = process_sp->GetAddressByteSize();
528 m_order = process_sp->GetByteOrder();
541 if (idx >= num_children)
552 uint32_t test_idx = 0;
558 while (tries < num_children) {
559 val_at_idx = m_values_ptr + (test_idx *
m_ptr_size);
561 llvm::Expected<lldb::addr_t> val_at_idx_or_err =
562 process_sp->ReadPointerFromMemory(val_at_idx);
563 if (!val_at_idx_or_err) {
564 llvm::consumeError(val_at_idx_or_err.takeError());
567 val_at_idx = *val_at_idx_or_err;
593 *
reinterpret_cast<uint32_t *
>(buffer_sp->GetBytes()) =
594 static_cast<uint32_t
>(set_item.
item_ptr);
597 *
reinterpret_cast<uint64_t *
>(buffer_sp->GetBytes()) =
598 static_cast<uint64_t
>(set_item.
item_ptr);
601 lldbassert(
false &&
"pointer size is not 4 nor 8");
604 idx_name.
Printf(
"[%" PRIu64
"]", (uint64_t)idx);
610 m_backend.GetCompilerType().GetBasicTypeFromAST(
617template <
typename D32,
typename D64>
626template <
typename D32,
typename D64>
635template <
typename D32,
typename D64>
636llvm::Expected<uint32_t>
644template <
typename D32,
typename D64>
662 m_ptr_size = process_sp->GetAddressByteSize();
663 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) +
m_ptr_size;
667 process_sp->ReadMemory(data_location,
m_data_32,
sizeof(D32),
671 process_sp->ReadMemory(data_location,
m_data_64,
sizeof(D64),
678template <
typename D32,
typename D64>
687 if (idx >= num_children)
699 uint32_t test_idx = 0;
701 while (tries < num_children) {
702 obj_at_idx = m_objs_addr + (test_idx *
m_ptr_size);
705 llvm::Expected<lldb::addr_t> obj_at_idx_or_err =
706 process_sp->ReadPointerFromMemory(obj_at_idx);
707 if (!obj_at_idx_or_err) {
708 llvm::consumeError(obj_at_idx_or_err.takeError());
711 obj_at_idx = *obj_at_idx_or_err;
730 auto ptr_size = process_sp->GetAddressByteSize();
742 assert(
false &&
"pointer size is not 4 nor 8 - get out of here ASAP");
745 idx_name.
Printf(
"[%" PRIu64
"]", (uint64_t)idx);
748 process_sp->GetByteOrder(),
749 process_sp->GetAddressByteSize());
753 m_backend.GetCompilerType().GetBasicTypeFromAST(
static llvm::raw_ostream & error(Stream &strm)
static std::optional< size_t > CalculateNumChildren(CompilerType container_elem_type, uint64_t num_elements, CompilerType element_type)
Calculates the number of elements stored in a container (with element type 'container_elem_type') as ...
uint32_t GetFoundationVersion()
bool Update(lldb::addr_t addr, ExecutionContextRef exe_ctx_rf)
Generic representation of a type in a programming language.
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::offset_t GetByteSize() const override
Get the number of bytes in the data buffer.
Execution context objects refer to objects in the execution of the program that is being debugged.
"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 plug-in interface definition class for debugging a process.
size_t ReadMemory(const ProcessAddress &process_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
uint32_t GetAddressByteSize() const
llvm::StringRef GetString() const
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.
uint32_t CalculateNumChildrenIgnoringErrors(uint32_t max=UINT32_MAX)
SyntheticChildrenFrontEnd(ValueObject &backend)
lldb::ValueObjectSP CreateChildValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
lldb::LanguageType GetLanguage() const
lldb::ProcessSP GetProcessSP() const
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
uint8_t * GetBytes()
Get a pointer to the data.
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
@ eReuse
Children did not change and don't need to be recomputed; re-use what we computed the last time we cal...
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Process > ProcessSP
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP