Skip to content

Commit

Permalink
User Story 1556891: [MIEngine Natvis] Support multi-dimensional arrays (
Browse files Browse the repository at this point in the history
#1346)

Support multi-dimensional arrays
  • Loading branch information
gc46 authored Sep 9, 2022
1 parent c594534 commit 7983eaa
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 4 deletions.
85 changes: 82 additions & 3 deletions src/MIDebugEngine/Natvis.Impl/Natvis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -577,9 +577,39 @@ private IVariableInformation[] ExpandVisualized(IVariableInformation variable)
{
continue;
}

uint totalSize = 0;
string val = GetExpressionValue(item.Size, variable, visualizer.ScopedNames);
totalSize = MICore.Debugger.ParseUint(val, throwOnError: true);
int rank = 0;
uint[] dimensions = null;

if (!string.IsNullOrEmpty(item.Rank))
{
totalSize = 1;
if (!int.TryParse(item.Rank, NumberStyles.None, CultureInfo.InvariantCulture, out rank))
{
string expressionValue = GetExpressionValue(item.Rank, variable, visualizer.ScopedNames);
rank = Int32.Parse(expressionValue, CultureInfo.InvariantCulture);
}
if (rank <= 0)
{
throw new Exception("Invalid rank value");
}
dimensions = new uint[rank];
for (int idx = 0; idx < rank; idx++)
{
// replace $i with Item.Rank here before passing it into GetExpressionValue
string substitute = item.Size.Replace("$i", idx.ToString(CultureInfo.InvariantCulture));
string val = GetExpressionValue(substitute, variable, visualizer.ScopedNames);
uint tmp = MICore.Debugger.ParseUint(val, throwOnError: true);
dimensions[idx] = tmp;
totalSize *= tmp;
}
}
else
{
string val = GetExpressionValue(item.Size, variable, visualizer.ScopedNames);
totalSize = MICore.Debugger.ParseUint(val, throwOnError: true);
}

uint startIndex = 0;
if (variable is PaginatedVisualizerWrapper pvwVariable)
Expand Down Expand Up @@ -624,10 +654,17 @@ private IVariableInformation[] ExpandVisualized(IVariableInformation variable)
if (arrayExpr.CountChildren != 0)
{
uint offset = startIndex + requestedSize;
bool isForward = item.Direction != ArrayDirectionType.Backward;

for (uint index = 0; index < requestedSize; ++index)
{
children.Add(new SimpleWrapper("[" + (startIndex + index).ToString(CultureInfo.InvariantCulture) + "]", _process.Engine, arrayExpr.Children[index]));
string displayName = (startIndex + index).ToString(CultureInfo.InvariantCulture);
if (rank > 1)
{
displayName = GetDisplayNameFromArrayIndex(index, rank, dimensions, isForward);
}

children.Add(new SimpleWrapper("[" + displayName + "]", _process.Engine, arrayExpr.Children[index]));
}

if (totalSize > offset)
Expand Down Expand Up @@ -1286,5 +1323,47 @@ private string GetExpressionValue(string expression, IVariableInformation variab
expressionVariable.SyncEval();
return FormatDisplayString(expressionVariable).value;
}

private string GetDisplayNameFromArrayIndex(uint arrayIndex, int rank, uint[] dimensions, bool isForward)
{
StringBuilder displayName = new StringBuilder();
uint index = arrayIndex;

int i = rank - 1;
int inc = -1;
int endLoop = -1;

if (!isForward)
{
i = 0;
inc = 1;
endLoop = rank;
}

uint[] indices = new uint[rank];

while (i != endLoop)
{
uint dimensionSize = dimensions[i];
uint divResult = index / dimensionSize;
uint modResult = index % dimensionSize;

indices[i] = modResult;
index = divResult;

i += inc;
}

string format = _process.Engine.CurrentRadix() == 16 ? "0x{0:X}" : "{0:D}";
displayName.AppendFormat(CultureInfo.InvariantCulture, format, indices[0]);
for (i = 1; i < rank; i++)
{
displayName.Append(',');
displayName.AppendFormat(CultureInfo.InvariantCulture, format, indices[i]);
}

return displayName.ToString();
}

}
}
6 changes: 5 additions & 1 deletion test/CppTests/Tests/NatvisTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public NatvisTests(ITestOutputHelper outputHelper) : base(outputHelper)

private const string NatvisName = "natvis";
private const string NatvisSourceName = "main.cpp";
private const int ReturnSourceLine = 48;
private const int ReturnSourceLine = 51;

[Theory]
[RequiresTestSettings]
Expand Down Expand Up @@ -175,6 +175,10 @@ public void TestArrayItems(ITestSettings settings)
// Index element for ArrayItems
Assert.Equal("20", ll.GetVariable("[5]").Value);
Assert.Equal("51", ll.GetVariable("[More...]").GetVariable("[51]").Value);

// Multi-dimensional array
var matrix = currentFrame.GetVariable("matrix");
Assert.Equal("3", matrix.GetVariable("[1,1]").Value);
}

runner.Expects.ExitedEvent(exitCode: 0).TerminatedEvent().AfterContinue();
Expand Down
27 changes: 27 additions & 0 deletions test/CppTests/debuggees/natvis/src/SimpleMatrix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class SimpleMatrix
{
public:
int m_size1;
int m_size2;
bool m_fUseSize1;
int* m_pData;

SimpleMatrix(int size1, int size2, bool fUseSize1)
{
m_size1 = size1;
m_size2 = size2;
m_fUseSize1 = fUseSize1;

m_pData = new int[GetSize()];

for (int i = 0; i < GetSize(); i++)
{
m_pData[i] = i;
}
}

int GetSize()
{
return m_fUseSize1 ? m_size1 : m_size2;
}
};
3 changes: 3 additions & 0 deletions test/CppTests/debuggees/natvis/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "SimpleVector.h"
#include "SimpleArray.h"
#include "SimpleClass.h"
#include "SimpleMatrix.h"

class SimpleDisplayObject
{
Expand Down Expand Up @@ -45,5 +46,7 @@ int main(int argc, char** argv)
SimpleClass* simpleClass = nullptr;
simpleClass = new SimpleClass();

SimpleMatrix matrix(5, 8, false);

return 0;
}
12 changes: 12 additions & 0 deletions test/CppTests/debuggees/natvis/src/visualizer_files/Simple.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,16 @@
</TreeItems>
</Expand>
</Type>

<Type Name="SimpleMatrix">
<DisplayString>SimpleMatrix</DisplayString>
<Expand>
<ArrayItems>
<Direction>Forward</Direction>
<Rank>2</Rank>
<Size>($i == 1) ? 2 : m_size2/2</Size>
<ValuePointer>m_pData</ValuePointer>
</ArrayItems>
</Expand>
</Type>
</AutoVisualizer>

0 comments on commit 7983eaa

Please sign in to comment.