Skip to content

Commit 94becb7

Browse files
authored
Merge pull request #7622 from Michael137/bugfix/lldb-vector_type-format-fix-to-20230725
[cherry-pick][stable/20230725] [lldb][DataFormatter] VectorType: fix format for arrays with size not a power-of-2
2 parents 27a290b + 6746090 commit 94becb7

File tree

3 files changed

+58
-18
lines changed

3 files changed

+58
-18
lines changed

lldb/source/DataFormatters/VectorType.cpp

+48-17
Original file line numberDiff line numberDiff line change
@@ -169,21 +169,49 @@ static lldb::Format GetItemFormatForFormat(lldb::Format format,
169169
}
170170
}
171171

172-
static size_t CalculateNumChildren(
173-
CompilerType container_type, CompilerType element_type,
174-
lldb_private::ExecutionContextScope *exe_scope =
175-
nullptr // does not matter here because all we trade in are basic types
176-
) {
177-
std::optional<uint64_t> container_size =
178-
container_type.GetByteSize(exe_scope);
179-
std::optional<uint64_t> element_size = element_type.GetByteSize(exe_scope);
180-
181-
if (container_size && element_size && *element_size) {
182-
if (*container_size % *element_size)
183-
return 0;
184-
return *container_size / *element_size;
185-
}
186-
return 0;
172+
/// Calculates the number of elements stored in a container (with
173+
/// element type 'container_elem_type') as if it had elements of type
174+
/// 'element_type'.
175+
///
176+
/// For example, a container of type
177+
/// `uint8_t __attribute__((vector_size(16)))` has 16 elements.
178+
/// But calling `CalculateNumChildren` with an 'element_type'
179+
/// of `float` (4-bytes) will return `4` because we are interpreting
180+
/// the byte-array as a `float32[]`.
181+
///
182+
/// \param[in] container_elem_type The type of the elements stored
183+
/// in the container we are calculating the children of.
184+
///
185+
/// \param[in] num_elements Number of 'container_elem_type's our
186+
/// container stores.
187+
///
188+
/// \param[in] element_type The type of elements we interpret
189+
/// container_type to contain for the purposes of calculating
190+
/// the number of children.
191+
///
192+
/// \returns The number of elements stored in a container of
193+
/// type 'element_type'. Returns a std::nullopt if the
194+
/// size of the container is not a multiple of 'element_type'
195+
/// or if an error occurs.
196+
static std::optional<size_t>
197+
CalculateNumChildren(CompilerType container_elem_type, uint64_t num_elements,
198+
CompilerType element_type) {
199+
std::optional<uint64_t> container_elem_size =
200+
container_elem_type.GetByteSize(/* exe_scope */ nullptr);
201+
if (!container_elem_size)
202+
return {};
203+
204+
auto container_size = *container_elem_size * num_elements;
205+
206+
std::optional<uint64_t> element_size =
207+
element_type.GetByteSize(/* exe_scope */ nullptr);
208+
if (!element_size || !*element_size)
209+
return {};
210+
211+
if (container_size % *element_size)
212+
return {};
213+
214+
return container_size / *element_size;
187215
}
188216

189217
namespace lldb_private {
@@ -221,11 +249,14 @@ class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
221249
m_parent_format = m_backend.GetFormat();
222250
CompilerType parent_type(m_backend.GetCompilerType());
223251
CompilerType element_type;
224-
parent_type.IsVectorType(&element_type);
252+
uint64_t num_elements;
253+
parent_type.IsVectorType(&element_type, &num_elements);
225254
m_child_type = ::GetCompilerTypeForFormat(
226255
m_parent_format, element_type,
227256
parent_type.GetTypeSystem().GetSharedPointer());
228-
m_num_children = ::CalculateNumChildren(parent_type, m_child_type);
257+
m_num_children =
258+
::CalculateNumChildren(element_type, num_elements, m_child_type)
259+
.value_or(0);
229260
m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
230261
return false;
231262
}

lldb/test/API/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py

+7
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,10 @@ def cleanup():
8686
v.SetFormat(lldb.eFormatVectorOfFloat32)
8787
oldValueAgain = v.GetChildAtIndex(0).GetValue()
8888
self.assertEqual(oldValue, oldValueAgain, "same format but different values")
89+
90+
# Test formatter for vector types whose size is not a power-of-2
91+
f3 = self.frame().FindVariable("f3")
92+
self.assertEqual(f3.GetNumChildren(), 3)
93+
self.assertEqual(f3.GetChildAtIndex(0).GetData().float[0], 1.25)
94+
self.assertEqual(f3.GetChildAtIndex(1).GetData().float[0], 2.50)
95+
self.assertEqual(f3.GetChildAtIndex(2).GetData().float[0], 2.50)
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
typedef float float4 __attribute__((ext_vector_type(4)));
2-
typedef unsigned char vec __attribute__((ext_vector_type(16)));
2+
typedef unsigned char vec __attribute__((ext_vector_type(16)));
3+
typedef float float3 __attribute__((ext_vector_type(3)));
34

45
int main() {
56
float4 f4 = {1.25, 1.25, 2.50, 2.50};
67
vec v = (vec)f4;
8+
float3 f3 = f4.gba;
79
return 0; // break here
810
}

0 commit comments

Comments
 (0)