From 10344dbd096d8e8c44f715c547f1c61b833298bf Mon Sep 17 00:00:00 2001
From: ussrhero <ussrhero@outlook.com>
Date: Mon, 29 Jul 2019 23:34:18 +0300
Subject: [PATCH] added : typeInfo.isTemplate method ( return true if type is
 template ) added : typeInfo.getTemplateArgs method ( return list of template
 args name )

---
 pykd/pymod.cpp      |  8 +++++++-
 pykd/pytypedvar.cpp |  3 +++
 pykd/pytypeinfo.cpp | 23 +++++++++++++++++++++++
 pykd/pytypeinfo.h   |  8 ++++++++
 4 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp
index c712171..33c2332 100644
--- a/pykd/pymod.cpp
+++ b/pykd/pymod.cpp
@@ -191,6 +191,8 @@ void pykd_init()
         "Create memory dump file" );
     python::def( "getLocalProcesses", pykd::getLocalProcesses,
         "Return list of runnng processes on the host system" );
+    python::def("getHostProcessPath", pykd::getHostProcessPath,
+        "Return image path of the process running python interpreter with a pykd");
     python::def( "getDebugOptions", pykd::getDebugOptions,
         "Return debug options" );
     python::def( "changeDebugOptions", pykd::changeDebugOptions,
@@ -931,7 +933,7 @@ void pykd_init()
             "Return method's type by name")
         .def( "method", TypeInfoAdapter::getMethodByIndex,
             "Return method's by index")
-        .def("hasMethod", TypeInfoAdapter::hasMethod,
+        .def( "hasMethod", TypeInfoAdapter::hasMethod,
             "Return True if type has a method with the specified name")
         .def( "methodName", TypeInfoAdapter::getMethodName,
             "Return method's name")
@@ -949,6 +951,8 @@ void pykd_init()
             "Return a base class offset by index")
         .def("baseClasses", TypeInfoAdapter::getBaseClasses,
             "Return list of tuples ( baseClassName, baseClassOffset, baseClassType)")
+        .def( "getTemplateArgs", TypeInfoAdapter::getTemplateArgs,
+            "Return list if template arguments" )
         .def( "deref", TypeInfoAdapter::deref,
             "Return type of pointer" )
         .def( "append", TypeInfoAdapter::appendField,
@@ -979,6 +983,8 @@ void pykd_init()
             "Return true if no type is specified" )
         .def( "isNoType", TypeInfoAdapter::isNoType,
             "Return true if type is virtual table" )
+        .def( "isTemplate", TypeInfoAdapter::isTemplate,
+            "Return true if type is template" )
         .def( "getCallingConvention", TypeInfoAdapter::getCallingConvention,
             "Returns an indicator of a methods calling convention: callingConvention" )
         .def( "getClassParent", TypeInfoAdapter::getClassParent,
diff --git a/pykd/pytypedvar.cpp b/pykd/pytypedvar.cpp
index 2b6d915..bd18692 100644
--- a/pykd/pytypedvar.cpp
+++ b/pykd/pytypedvar.cpp
@@ -118,6 +118,9 @@ python::list TypedVarAdapter::getFields( kdlib::TypedVar& typedVar )
             std::wstring  name = typedVar.getElementName(i);
             kdlib::MEMOFFSET_32  offset = 0;
 
+            if (typedVar.getType()->isConstMember(i))
+                continue;
+
             if (!typedVar.getType()->isStaticMember(i) )
                 offset = typedVar.getElementOffset(i);
 
diff --git a/pykd/pytypeinfo.cpp b/pykd/pytypeinfo.cpp
index 7f02b3b..a3f14fd 100644
--- a/pykd/pytypeinfo.cpp
+++ b/pykd/pytypeinfo.cpp
@@ -211,6 +211,29 @@ python::list TypeInfoAdapter::getBaseClasses(kdlib::TypeInfo &typeInfo)
 
 ///////////////////////////////////////////////////////////////////////////////
 
+python::list TypeInfoAdapter::getTemplateArgs(const kdlib::TypeInfoPtr &typeInfo)
+{
+    std::list<std::wstring>  templateArgs;
+
+    {
+        AutoRestorePyState  pystate;
+
+        for (size_t i = 0; i < typeInfo->getTemplateArgsCount(); ++i)
+        {
+            templateArgs.push_back(typeInfo->getTemplateArg(i));
+        }
+    }
+    
+    python::list pylst;
+
+    for (const auto& arg : templateArgs)
+        pylst.append(arg);
+
+    return pylst;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 kdlib::TypeInfoPtr TypeInfoAdapter::getElementAttr(kdlib::TypeInfo &typeInfo, const std::wstring &name)
 {
     AutoRestorePyState  pystate;
diff --git a/pykd/pytypeinfo.h b/pykd/pytypeinfo.h
index 09b3579..336a974 100644
--- a/pykd/pytypeinfo.h
+++ b/pykd/pytypeinfo.h
@@ -302,6 +302,12 @@ struct TypeInfoAdapter : public kdlib::TypeInfo {
         return typeInfo.isNoType();
     }
 
+    static bool isTemplate(const kdlib::TypeInfoPtr &typeInfo)
+    {
+        AutoRestorePyState  pystate;
+        return typeInfo->isTemplate();
+    }
+
     static void appendField( kdlib::TypeInfo &typeInfo, const std::wstring &fieldName, kdlib::TypeInfoPtr &fieldType )
     {
         AutoRestorePyState  pystate;
@@ -334,6 +340,8 @@ struct TypeInfoAdapter : public kdlib::TypeInfo {
 
     static python::list getBaseClasses(kdlib::TypeInfo &typeInfo);
 
+    static python::list getTemplateArgs(const kdlib::TypeInfoPtr &typeInfo);
+
     static bool isZero(kdlib::TypeInfo &typeInfo) {
         return false;
     }