Fix display of captured variables in lambda
authorIgor Kulaychuk <i.kulaychuk@samsung.com>
Sat, 22 Jul 2017 00:18:17 +0000 (03:18 +0300)
committerIgor Kulaychuk <i.kulaychuk@samsung.com>
Mon, 13 Nov 2017 19:22:40 +0000 (22:22 +0300)
src/debug/netcoredbg/valuewalk.cpp

index bb1f919..64c069b 100644 (file)
@@ -372,6 +372,44 @@ HRESULT WalkMembers(ICorDebugValue *pValue, ICorDebugILFrame *pILFrame, WalkMemb
     return WalkMembers(pValue, pILFrame, nullptr, cb);
 }
 
+static HRESULT HandleSpecialThisParam(ICorDebugValue *pThisValue,
+                                      ICorDebugILFrame *pILFrame,
+                                      WalkStackVarsCallback cb)
+{
+    static const std::string displayClass = "<>c__DisplayClass";
+    static const std::string hideClass = "<>c";
+
+    HRESULT Status;
+
+    std::string typeName;
+    TypePrinter::GetTypeOfValue(pThisValue, typeName);
+
+    std::size_t start = typeName.find_last_of('.');
+    if (start == std::string::npos)
+        return S_FALSE;
+
+    typeName = typeName.substr(start + 1);
+
+    if (!std::equal(hideClass.begin(), hideClass.end(), typeName.begin()))
+        return S_FALSE;
+
+    if (!std::equal(displayClass.begin(), displayClass.end(), typeName.begin()))
+        return S_OK; // just do not show this value
+
+    // Substitute this with its fields
+    IfFailRet(WalkMembers(pThisValue, pILFrame, [&](
+        mdMethodDef,
+        ICorDebugModule *,
+        ICorDebugType *,
+        ICorDebugValue *pValue,
+        bool is_static,
+        const std::string &name)
+    {
+        return cb(pILFrame, pValue, name.empty() ? "this" : name);
+    }));
+    return S_OK;
+}
+
 HRESULT WalkStackVars(ICorDebugFrame *pFrame, WalkStackVarsCallback cb)
 {
     HRESULT Status;
@@ -410,7 +448,8 @@ HRESULT WalkStackVars(ICorDebugFrame *pFrame, WalkStackVarsCallback cb)
             mdParamDef paramDef;
             WCHAR paramName[mdNameLen] = W("\0");
 
-            if(i == 0 && (methodAttr & mdStatic) == 0)
+            bool thisParam = i == 0 && (methodAttr & mdStatic) == 0;
+            if (thisParam)
                 swprintf_s(paramName, mdNameLen, W("this\0"));
             else
             {
@@ -431,6 +470,14 @@ HRESULT WalkStackVars(ICorDebugFrame *pFrame, WalkStackVarsCallback cb)
             if (Status == S_FALSE)
                 break;
 
+            if (thisParam)
+            {
+                Status = HandleSpecialThisParam(pValue, pILFrame, cb);
+                IfFailRet(Status);
+                if (Status == S_OK)
+                    continue;
+            }
+
             IfFailRet(cb(pILFrame, pValue, to_utf8(paramName/*, paramNameLen*/)));
         }
     }