summaryrefslogtreecommitdiff
path: root/src/ToolBox/SOS/Strike/ExpressionNode.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ToolBox/SOS/Strike/ExpressionNode.h')
-rw-r--r--src/ToolBox/SOS/Strike/ExpressionNode.h307
1 files changed, 0 insertions, 307 deletions
diff --git a/src/ToolBox/SOS/Strike/ExpressionNode.h b/src/ToolBox/SOS/Strike/ExpressionNode.h
deleted file mode 100644
index 2f34e5615b..0000000000
--- a/src/ToolBox/SOS/Strike/ExpressionNode.h
+++ /dev/null
@@ -1,307 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-#ifndef _EXPRESSION_NODE_
-#define _EXPRESSION_NODE_
-
-#ifdef FEATURE_PAL
-#error "This file isn't designed to build in PAL"
-#endif
-
-#include "strike.h"
-#include "sos.h"
-#include "util.h"
-
-#define MAX_EXPRESSION 500
-#define MAX_ERROR 500
-
-
-// Represents one node in a tree of expressions and sub-expressions
-// These nodes are used in the !watch expandable expression tree
-// Each node consists of a string based C#-like expression and its
-// evaluation within the current context of the debuggee.
-//
-// These nodes are also intended for eventual use in ClrStack -i expression tree
-// but ClrStack -i hasn't yet been refactored to use them
-//
-// Each node can evaluate to:
-// nothing - if an error occurs during expression parsing or the expression
-// names don't match to anything in the debuggee
-// a debuggee value - these are values that are backed in memory of the debuggee
-// (ICorDebugValue objects) or build time constants which are
-// stored in the assembly metadata.
-// a debuggee type - instead of refering to a particular instance of a type (the
-// value case above), nodes can directly refer to a type definition
-// represented by an ICorDebugType object
-class ExpressionNode
-{
-public:
-
- typedef VOID (*ExpressionNodeVisitorCallback)(ExpressionNode* pExpressionNode, int depth, VOID* pUserData);
-
- // Returns the complete expression being evaluated to get the value for this node
- // The returned pointer is a string interior to this object - once you release
- // all references to this object the string is invalid.
- WCHAR* GetAbsoluteExpression();
-
- // Returns the sub expression that logically indicates how the parent expression
- // was built upon to reach this node. This relative value has no purpose other
- // than an identifier and to convey UI meaning to the user. At present typical values
- // are the name of type, a local, a parameter, a field, an array index, or '<basetype>'
- // for a baseclass casting operation
- // The returned pointer is a string interior to this object - once you release
- // all references to this object the string is invalid.
- WCHAR* GetRelativeExpression();
-
- // Returns a text representation of the type of value that this node refers to
- // It is possible this node doesn't evaluate to anything and therefore has no
- // type
- // The returned pointer is a string interior to this object - once you release
- // all references to this object the string is invalid.
- WCHAR* GetTypeName();
-
- // Returns a text representation of the value for this node. It is possible that
- // this node doesn't evaluate to anything and therefore has no value text.
- // The returned pointer is a string interior to this object - once you release
- // all references to this object the string is invalid.
- WCHAR* GetTextValue();
-
- // If there is any error during the evaluation of this node's expression, it is
- // returned here.
- // The returned pointer is a string interior to this object - once you release
- // all references to this object the string is invalid.
- WCHAR* GetErrorMessage();
-
- // Factory function for creating the expression node at the root of a tree
- static HRESULT CreateExpressionNode(__in_z WCHAR* pExpression, ExpressionNode** ppExpressionNode);
-
- // Performs recursive expansion within the tree for nodes that are along the path to varToExpand.
- // Expansion involves calulating a set of child expressions from the current expression via
- // field dereferencing, array index dereferencing, or casting to a base type.
- // For example if a tree was rooted with expression 'foo.bar' and varToExpand is '(Baz)foo.bar[9]'
- // then 'foo.bar', 'foo.bar[9]', and '(Baz)foo.bar[9]' nodes would all be expanded.
- HRESULT Expand(__in_z WCHAR* varToExpand);
-
- // Standard depth first search tree traversal pattern with a callback
- VOID DFSVisit(ExpressionNodeVisitorCallback pFunc, VOID* pUserData, int depth=0);
-
-private:
- // for nodes that evaluate to a type, this is that type
- // for nodes that evaluate to a debuggee value, this is the type of that
- // value or one of its base types. It represents the type the value should
- // displayed and expanded as.
- ToRelease<ICorDebugType> pTypeCast;
-
- // for nodes that evaluate to a memory backed debuggee value, this is that value
- ToRelease<ICorDebugValue> pValue;
-
- // if this node gets expanded and it has thread-static or context-static sub-fields,
- // this frame disambiguates which thread and context to use.
- ToRelease<ICorDebugILFrame> pILFrame;
-
- // TODO: exactly which metadata is this supposed to be? try to get rid of this
- ToRelease<IMetaDataImport> pMD;
-
- // PERF: this could be a lot more memory efficient
- WCHAR pTextValue[MAX_EXPRESSION];
- WCHAR pErrorMessage[MAX_ERROR];
- WCHAR pAbsoluteExpression[MAX_EXPRESSION];
- WCHAR pRelativeExpression[MAX_EXPRESSION];
- WCHAR pTypeName[MAX_EXPRESSION];
-
- // if this value represents a build time constant debuggee value, this is a pointer
- // to the value data stored in metadata and its size
- UVCP_CONSTANT pDefaultValue;
- ULONG cchDefaultValue;
-
- // Pointer in a linked list of sibling nodes that all share the same parent
- ExpressionNode* pNextSibling;
- // Pointer to the first child node of this node, other children can be found
- // by following the child's sibling list.
- ExpressionNode* pChild;
-
- typedef VOID (*VariableEnumCallback)(ICorDebugValue* pValue, WCHAR* pName, WCHAR* pErrorMessage, VOID* pUserData);
- typedef VOID (*FrameEnumCallback)(ICorDebugFrame* pFrame, VOID* pUserData);
-
- // Indicates how a child node was derived from its parent
- enum ChildKind
- {
- ChildKind_Field,
- ChildKind_Index,
- ChildKind_BaseClass
- };
-
- // Creates a new expression with a given debuggee value and frame
- ExpressionNode(__in_z const WCHAR* pExpression, ICorDebugValue* pValue, ICorDebugILFrame* pFrame);
-
- // Creates a new expression that has an error and no value
- ExpressionNode(__in_z const WCHAR* pExpression, __in_z const WCHAR* pErrorMessage);
-
- // Creates a new child expression
- ExpressionNode(__in_z const WCHAR* pParentExpression, ChildKind ck, __in_z const WCHAR* pRelativeExpression, ICorDebugValue* pValue, ICorDebugType* pType, ICorDebugILFrame* pFrame, UVCP_CONSTANT pDefaultValue = NULL, ULONG cchDefaultValue = 0);
-
- // Common member initialization for the constructors
- VOID Init(ICorDebugValue* pValue, ICorDebugType* pTypeCast, ICorDebugILFrame* pFrame);
-
- // Retreves the correct IMetaDataImport for the type represented in this node and stores it
- // in pMD.
- HRESULT PopulateMetaDataImport();
-
- // Determines the string representation of pType and stores it in typeName
- static HRESULT CalculateTypeName(ICorDebugType * pType, __inout_ecount(typeNameLen) WCHAR* typeName, DWORD typeNameLen);
-
-
- // Appends angle brackets and the generic argument list to a type name
- static HRESULT AddGenericArgs(ICorDebugType * pType, __inout_ecount(typeNameLen) WCHAR* typeName, DWORD typeNameLen);
-
- // Determines the text name for the type of this node and caches it
- HRESULT PopulateType();
-
- // Node expansion helpers
-
- // Inserts a new child at the end of the linked list of children
- // PERF: This has O(N) insert time but these lists should never be large
- VOID AddChild(ExpressionNode* pNewChild);
-
- // Helper that determines if the current node is on the path of nodes represented by
- // expression varToExpand
- BOOL ShouldExpandVariable(__in_z WCHAR* varToExpand);
-
- // Expands this array node by creating child nodes with expressions refering to individual array elements
- HRESULT ExpandSzArray(ICorDebugValue* pInnerValue, __in_z WCHAR* varToExpand);
-
- // Expands this struct/class node by creating child nodes with expressions refering to individual field values
- // and one node for the basetype value
- HRESULT ExpandFields(ICorDebugValue* pInnerValue, __in_z WCHAR* varToExpand);
-
- // Value Population functions
-
- //Helper for unwrapping values
- static HRESULT DereferenceAndUnboxValue(ICorDebugValue * pInputValue, ICorDebugValue** ppOutputValue, BOOL * pIsNull = NULL);
-
- // Returns TRUE if the value derives from System.Enum
- static BOOL IsEnum(ICorDebugValue * pInputValue);
-
- // Calculates the value text for nodes that have enum values
- HRESULT PopulateEnumValue(ICorDebugValue* pEnumValue, BYTE* enumValue);
-
- // Helper that fetches the text value of a string ICorDebugValue
- HRESULT GetDebuggeeStringValue(ICorDebugValue* pInputValue, __inout_ecount(cchBuffer) WCHAR* wszBuffer, DWORD cchBuffer);
-
- // Helper that fetches the text value of a string build-time literal
- HRESULT GetConstantStringValue(__inout_ecount(cchBuffer) WCHAR* wszBuffer, DWORD cchBuffer);
-
- // Helper that caches the textual value for nodes that evaluate to array objects
- HRESULT PopulateSzArrayValue(ICorDebugValue* pInputValue);
-
- // Helper that caches the textual value for nodes of any type
- HRESULT PopulateTextValueHelper();
-
- // Caches the textual value of this node
- HRESULT PopulateTextValue();
-
-
- // Expression parsing and search
-
- // In/Out parameters for the EvaluateExpressionFrameScanCallback
- typedef struct _EvaluateExpressionFrameScanData
- {
- WCHAR* pIdentifier;
- ToRelease<ICorDebugValue> pFoundValue;
- ToRelease<ICorDebugILFrame> pFoundFrame;
- ToRelease<ICorDebugILFrame> pFirstFrame;
- WCHAR* pErrorMessage;
- DWORD cchErrorMessage;
- } EvaluateExpressionFrameScanData;
-
- //Callback that searches a frame to determine if it contains a local variable or parameter of a given name
- static VOID EvaluateExpressionFrameScanCallback(ICorDebugFrame* pFrame, VOID* pUserData);
-
- //Callback checks to see if a given local/parameter has name pName
- static VOID EvaluateExpressionVariableScanCallback(ICorDebugValue* pValue, __in_z WCHAR* pName, __out_z WCHAR* pErrorMessage, VOID* pUserData);
-
- //Factory method that recursively parses pExpression and create an ExpressionNode
- // pExpression - the entire expression being parsed
- // pExpressionRemainder - the portion of the expression that remains to be parsed in this
- // recursive invocation
- // charactersParsed - the number of characters that have been parsed from pExpression
- // so far (todo: this is basically the difference between remainder and
- // full expression, do we need it?)
- // pParsedValue - A debuggee value that should be used as the context for interpreting
- // pExpressionRemainder
- // pParsedType - A debuggee type that should be used as the context for interpreting
- // pExpressionRemainder.
- // pParsedDefaultValue - A fixed value from metadata that should be used as context for
- // interpretting pExpressionRemainder
- // cchParsedDefaultValue- Size of pParsedDefaultValue
- // pFrame - A debuggee IL frame that disambiguates the thread and context needed
- // to evaluate a thread-static or context-static value
- // ppExpressionNode - OUT - the resulting expression node
- //
- //
- static HRESULT CreateExpressionNodeHelper(__in_z WCHAR* pExpression,
- __in_z WCHAR* pExpressionParseRemainder,
- DWORD charactersParsed,
- ICorDebugValue* pParsedValue,
- ICorDebugType* pParsedType,
- UVCP_CONSTANT pParsedDefaultValue,
- ULONG cchParsedDefaultValue,
- ICorDebugILFrame* pFrame,
- ExpressionNode** ppExpressionNode);
-
- // Splits apart a C#-like expression and determines the first identifier in the string and updates expression to point
- // at the remaining unparsed portion
- static HRESULT ParseNextIdentifier(__in_z WCHAR** expression,
- __inout_ecount(cchIdentifierName) WCHAR* identifierName,
- DWORD cchIdentifierName,
- __inout_ecount(cchErrorMessage) WCHAR* errorMessage,
- DWORD cchErrorMessage,
- DWORD* charactersParsed,
- BOOL* isArrayIndex);
-
-
- // Iterate through all parameters in the ILFrame calling the callback function for each of them
- static HRESULT EnumerateParameters(IMetaDataImport * pMD,
- mdMethodDef methodDef,
- ICorDebugILFrame * pILFrame,
- VariableEnumCallback pCallback,
- VOID* pUserData);
-
- // Enumerate all locals in the given ILFrame, calling the callback method for each of them
- static HRESULT EnumerateLocals(IMetaDataImport * pMD,
- mdMethodDef methodDef,
- ICorDebugILFrame * pILFrame,
- VariableEnumCallback pCallback,
- VOID* pUserData);
-
- // Iterates over all frames on the current thread's stack, calling the callback function for each of them
- static HRESULT EnumerateFrames(FrameEnumCallback pCallback, VOID* pUserData);
-
- // Determines the corresponding ICorDebugType for a given primitive type
- static HRESULT FindTypeFromElementType(CorElementType et, ICorDebugType** ppType);
-
- // Gets the appropriate element type encoding for well-known fully qualified type names
- // This doesn't work for arbitrary types, just types that have CorElementType short forms.
- static HRESULT GetCanonicalElementTypeForTypeName(__in_z WCHAR* pTypeName, CorElementType *et);
-
- // Searches the debuggee for any ICorDebugType that matches the given fully qualified name
- // This will search across all AppDomains and Assemblies
- static HRESULT FindTypeByName(__in_z const WCHAR* pTypeName, ICorDebugType** ppType);
-
- // Searches the debuggee for any ICorDebugType that matches the given fully qualified name
- // This will search across all Assemblies in the given AppDomain
- static HRESULT FindTypeByName(ICorDebugAppDomain* pAppDomain, __in_z const WCHAR* pTypeName, ICorDebugType** ppType);
-
- // Searches the assembly for any ICorDebugType that matches the given fully qualified name
- static HRESULT FindTypeByName(ICorDebugAssembly* pAssembly, __in_z const WCHAR* pTypeName, ICorDebugType** ppType);
-
- // Searches a given module for any ICorDebugType that matches the given fully qualified type name
- static HRESULT FindTypeByName(ICorDebugModule* pModule, __in_z const WCHAR* pTypeName, ICorDebugType** ppType);
-
- // Checks whether the given token is or refers to type System.ValueType or System.Enum
- static HRESULT IsTokenValueTypeOrEnum(mdToken token, IMetaDataImport* pMetadata, BOOL* pResult);
-};
-
-#endif