bool GoASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope, bool is_base_class) { if (!type) return false; if (IsAggregateType(type)) { return false; } else { GoType *t = static_cast<GoType *>(type); if (t->IsTypedef()) { CompilerType typedef_compiler_type = t->GetElementType(); if (format == eFormatDefault) format = typedef_compiler_type.GetFormat(); uint64_t typedef_byte_size = typedef_compiler_type.GetByteSize(exe_scope); return typedef_compiler_type.DumpTypeValue( s, format, // The format with which to display the element data, // Data buffer containing all bytes for this type byte_offset, // Offset into "data" where to grab value from typedef_byte_size, // Size of this type in bytes bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield bitfield_bit_offset, // Offset in bits of a bitfield value if bitfield_bit_size != 0 exe_scope, is_base_class); } uint32_t item_count = 1; // A few formats, we might need to modify our size and count for depending // on how we are trying to display the value... switch (format) { default: case eFormatBoolean: case eFormatBinary: case eFormatComplex: case eFormatCString: // NULL terminated C strings case eFormatDecimal: case eFormatEnum: case eFormatHex: case eFormatHexUppercase: case eFormatFloat: case eFormatOctal: case eFormatOSType: case eFormatUnsigned: case eFormatPointer: case eFormatVectorOfChar: case eFormatVectorOfSInt8: case eFormatVectorOfUInt8: case eFormatVectorOfSInt16: case eFormatVectorOfUInt16: case eFormatVectorOfSInt32: case eFormatVectorOfUInt32: case eFormatVectorOfSInt64: case eFormatVectorOfUInt64: case eFormatVectorOfFloat32: case eFormatVectorOfFloat64: case eFormatVectorOfUInt128: break; case eFormatChar: case eFormatCharPrintable: case eFormatCharArray: case eFormatBytes: case eFormatBytesWithASCII: item_count = byte_size; byte_size = 1; break; case eFormatUnicode16: item_count = byte_size / 2; byte_size = 2; break; case eFormatUnicode32: item_count = byte_size / 4; byte_size = 4; break; } return data.Dump(s, byte_offset, format, byte_size, item_count, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset, exe_scope); } return 0; }
CompilerType GoASTContext::GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds, std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags) { child_name.clear(); child_byte_size = 0; child_byte_offset = 0; child_bitfield_bit_size = 0; child_bitfield_bit_offset = 0; child_is_base_class = false; child_is_deref_of_parent = false; language_flags = 0; if (!type || !GetCompleteType(type)) return CompilerType(); GoType *t = static_cast<GoType *>(type); if (t->GetStruct()) { uint64_t bit_offset; CompilerType ret = GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr); child_byte_size = ret.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); child_byte_offset = bit_offset / 8; return ret; } else if (t->GetGoKind() == GoType::KIND_PTR) { CompilerType pointee = t->GetElementType(); if (!pointee.IsValid() || pointee.IsVoidType()) return CompilerType(); if (transparent_pointers && pointee.IsAggregateType()) { bool tmp_child_is_deref_of_parent = false; return pointee.GetChildCompilerTypeAtIndex(exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, tmp_child_is_deref_of_parent, valobj, language_flags); } else { child_is_deref_of_parent = true; const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL; if (parent_name) { child_name.assign(1, '*'); child_name += parent_name; } // We have a pointer to an simple type if (idx == 0 && pointee.GetCompleteType()) { child_byte_size = pointee.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); child_byte_offset = 0; return pointee; } } } else if (GoArray *a = t->GetArray()) { if (ignore_array_bounds || idx < a->GetLength()) { CompilerType element_type = a->GetElementType(); if (element_type.GetCompleteType()) { char element_name[64]; ::snprintf(element_name, sizeof(element_name), "[%zu]", idx); child_name.assign(element_name); child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; return element_type; } } } else if (t->IsTypedef()) { return t->GetElementType().GetChildCompilerTypeAtIndex( exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, valobj, language_flags); } return CompilerType(); }