Add support for arrays display
authorIgor Kulaychuk <i.kulaychuk@samsung.com>
Tue, 11 Jul 2017 16:53:14 +0000 (19:53 +0300)
committerIgor Kulaychuk <i.kulaychuk@samsung.com>
Mon, 13 Nov 2017 19:22:40 +0000 (22:22 +0300)
src/debug/debugger/typeprinter.h
src/debug/debugger/valueprint.cpp
src/debug/debugger/valuewalk.cpp

index 2dcb342c5c87d33400fa7087a3d386d8f617c224..95f461b460fbf56418a32210e6b9d564b6f90451 100644 (file)
@@ -10,9 +10,9 @@ class TypePrinter
                                 std::list<std::string> &args);
     static HRESULT AddGenericArgs(ICorDebugType *pType, std::list<std::string> &args);
     static HRESULT AddGenericArgs(ICorDebugFrame *pFrame, std::list<std::string> &args);
-    static HRESULT GetTypeOfValue(ICorDebugType *pType, std::string &elementType, std::string &arrayType);
 public:
     static HRESULT GetTypeOfValue(ICorDebugType *pType, std::string &output);
     static HRESULT GetTypeOfValue(ICorDebugValue *pValue, std::string &output);
+    static HRESULT GetTypeOfValue(ICorDebugType *pType, std::string &elementType, std::string &arrayType);
     static HRESULT GetMethodName(ICorDebugFrame *pFrame, std::string &output);
 };
index ffe8d53da7b1f89a44b6b88b0303f02216917c4b..882ac98dc2003248fecd41fd1b674497eceb2c57 100644 (file)
@@ -66,6 +66,69 @@ static BOOL IsEnum(ICorDebugValue * pInputValue)
     return FALSE;
 }
 
+static HRESULT PrintArrayValue(ICorDebugValue *pValue,
+                               std::string &output)
+{
+    HRESULT Status = S_OK;
+
+    ToRelease<ICorDebugArrayValue> pArrayValue;
+    IfFailRet(pValue->QueryInterface(IID_ICorDebugArrayValue, (LPVOID*) &pArrayValue));
+
+    ULONG32 nRank;
+    IfFailRet(pArrayValue->GetRank(&nRank));
+    if (nRank < 1)
+    {
+        return E_UNEXPECTED;
+    }
+
+    ULONG32 cElements;
+    IfFailRet(pArrayValue->GetCount(&cElements));
+
+    std::stringstream ss;
+    ss << "{";
+
+    std::string elementType;
+    std::string arrayType;
+
+    CorElementType corElemType;
+    ToRelease<ICorDebugType> pFirstParameter;
+    ToRelease<ICorDebugValue2> pValue2;
+    ToRelease<ICorDebugType> pType;
+    if (SUCCEEDED(pArrayValue->QueryInterface(IID_ICorDebugValue2, (LPVOID *) &pValue2)) && SUCCEEDED(pValue2->GetExactType(&pType)))
+    {
+        if (SUCCEEDED(pType->GetFirstTypeParameter(&pFirstParameter)))
+        {
+            TypePrinter::GetTypeOfValue(pFirstParameter, elementType, arrayType);
+        }
+    }
+
+    std::vector<ULONG32> dims(nRank, 0);
+    pArrayValue->GetDimensions(nRank, &dims[0]);
+
+    std::vector<ULONG32> base(nRank, 0);
+    BOOL hasBaseIndicies = FALSE;
+    if (SUCCEEDED(pArrayValue->HasBaseIndicies(&hasBaseIndicies)) && hasBaseIndicies)
+        IfFailRet(pArrayValue->GetBaseIndicies(nRank, &base[0]));
+
+    ss << elementType << "[";
+    const char *sep = "";
+    for (size_t i = 0; i < dims.size(); ++i)
+    {
+        ss << sep;
+        sep = ", ";
+
+        if (base[i] > 0)
+            ss << base[i] << ".." << (base[i] + dims[i] - 1);
+        else
+            ss << dims[i];
+    }
+    ss << "]" << arrayType;
+
+    ss << "}";
+    output = ss.str();
+    return S_OK;
+}
+
 static HRESULT PrintStringValue(ICorDebugValue * pValue, std::string &output)
 {
     HRESULT Status;
@@ -127,11 +190,9 @@ HRESULT PrintValue(ICorDebugValue *pInputValue, ICorDebugILFrame * pILFrame, std
         return S_OK;
     }
 
-    if (corElemType == ELEMENT_TYPE_SZARRAY)
+    if (corElemType == ELEMENT_TYPE_SZARRAY || corElemType == ELEMENT_TYPE_ARRAY)
     {
-        output = "<ELEMENT_TYPE_SZARRAY>";
-        //return PrintSzArrayValue(pValue, pILFrame, pMD);
-        return S_OK;
+        return PrintArrayValue(pValue, output);
     }
 
     ToRelease<ICorDebugGenericValue> pGenericValue;
@@ -243,7 +304,6 @@ HRESULT PrintValue(ICorDebugValue *pInputValue, ICorDebugILFrame * pILFrame, std
 
         // TODO: The following corElementTypes are not yet implemented here.  Array
         // might be interesting to add, though the others may be of rather limited use:
-        // ELEMENT_TYPE_ARRAY          = 0x14,     // MDARRAY <type> <rank> <bcount> <bound1> ... <lbcount> <lb1> ...
         //
         // ELEMENT_TYPE_GENERICINST    = 0x15,     // GENERICINST <generic type> <argCnt> <arg1> ... <argn>
     }
index 935158052eaada117719a09335aeccaef4a51f93..765874f967f568c179a7f556e7d67a6a8b616242 100644 (file)
@@ -109,6 +109,37 @@ HRESULT EvalProperty(
     return pEval->GetResult(ppEvalResult);
 }
 
+static void IncIndicies(std::vector<ULONG32> &ind, const std::vector<ULONG32> &dims)
+{
+    int i = ind.size() - 1;
+
+    while (i >= 0)
+    {
+        ind[i] += 1;
+        if (ind[i] < dims[i])
+            return;
+        ind[i] = 0;
+        --i;
+    }
+}
+
+static std::string IndiciesToStr(const std::vector<ULONG32> &ind, const std::vector<ULONG32> &base)
+{
+    const size_t ind_size = ind.size();
+    if (ind_size < 1 || base.size() != ind_size)
+        return std::string();
+
+    std::stringstream ss;
+    const char *sep = "";
+    for (size_t i = 0; i < ind_size; ++i)
+    {
+        ss << sep;
+        sep = ", ";
+        ss << (base[i] + ind[i]);
+    }
+    return ss.str();
+}
+
 static HRESULT WalkMembers(ICorDebugValue *pInputValue, ICorDebugILFrame *pILFrame, ICorDebugType *pTypeCast, WalkMembersCallback cb)
 {
     HRESULT Status = S_OK;
@@ -129,11 +160,22 @@ static HRESULT WalkMembers(ICorDebugValue *pInputValue, ICorDebugILFrame *pILFra
         ULONG32 cElements;
         IfFailRet(pArrayValue->GetCount(&cElements));
 
+        std::vector<ULONG32> dims(nRank, 0);
+        IfFailRet(pArrayValue->GetDimensions(nRank, &dims[0]));
+
+        std::vector<ULONG32> base(nRank, 0);
+        BOOL hasBaseIndicies = FALSE;
+        if (SUCCEEDED(pArrayValue->HasBaseIndicies(&hasBaseIndicies)) && hasBaseIndicies)
+            IfFailRet(pArrayValue->GetBaseIndicies(nRank, &base[0]));
+
+        std::vector<ULONG32> ind(nRank, 0);
+
         for (ULONG32 i = 0; i < cElements; ++i)
         {
             ToRelease<ICorDebugValue> pElementValue;
             pArrayValue->GetElementAtPosition(i, &pElementValue);
-            IfFailRet(cb(mdMethodDefNil, nullptr, nullptr, pElementValue, false, "[" + std::to_string(i) + "]"));
+            IfFailRet(cb(mdMethodDefNil, nullptr, nullptr, pElementValue, false, "[" + IndiciesToStr(ind, base) + "]"));
+            IncIndicies(ind, dims);
         }
 
         return S_OK;