/// <summary> /// Get the variable assignment expression as a string. Returns null if the value is /// constant or invalid. /// </summary> public static string GetVariableAssignExpression(this RemoteValue remoteValue) { var valueType = remoteValue.GetValueType(); if (valueType == ValueType.Invalid) { return(null); } if (valueType == ValueType.Register) { return($"${remoteValue.GetName()}"); } TypeFlags?typeFlags = remoteValue.GetTypeInfo()?.GetTypeFlags(); if (typeFlags.HasValue && typeFlags.Value.HasFlag(TypeFlags.IS_ARRAY)) { return(null); } string variableExpression = remoteValue.GetFullName(); if (variableExpression == null) { variableExpression = remoteValue.GetMemoryAddressAssignExpression(); } return(variableExpression); }
/// <summary> /// Returns the address to be used as memory context. This is used to get an address /// from an expression entered into Visual Studio's memory view's address text box. /// </summary> public static ulong?GetMemoryContextAddress(this RemoteValue remoteValue) { if (!IsValidValue(remoteValue)) { return(null); } TypeFlags GetTypeFlags(RemoteValue value) => remoteValue.GetTypeInfo().GetCanonicalType().GetTypeFlags(); // If the value is an array, try to obtain its address. TypeFlags flags = GetTypeFlags(remoteValue); if (flags.HasFlag(TypeFlags.IS_ARRAY)) { remoteValue = remoteValue.AddressOf(); if (!IsValidValue(remoteValue)) { return(null); } flags = GetTypeFlags(remoteValue); } // Only interpret pointers, references and integers as addresses. if (!flags.HasFlag(TypeFlags.IS_REFERENCE) && !flags.HasFlag(TypeFlags.IS_POINTER) && !flags.HasFlag(TypeFlags.IS_INTEGER)) { return(null); } return(remoteValue.GetValueAsUnsigned()); }
static IEnumerable <RemoteValue> GetPointerChildren(RemoteValue value, int offset, int count) { var result = new List <RemoteValue>(); SbType pointeeType = value.GetTypeInfo()?.GetPointeeType(); if (pointeeType == null) { // If we cannot get the pointee type, just return the empty list. return(result); } ulong byteSize = pointeeType.GetByteSize(); ulong baseAddress = value.GetValueAsUnsigned() + (ulong)offset * byteSize; for (int n = 0; n < count; ++n) { ulong address = baseAddress + (ulong)n * byteSize; RemoteValue childValue = value.CreateValueFromAddress($"[{offset + n}]", address, pointeeType); if (childValue != null) { result.Add(childValue); } } return(result); }
private GrpcValueInfo CreateValueInfoAndUpdateStores(RemoteValue remoteValue) { if (remoteValue == null) { return(null); } string expressionPath; var hasExpressionPath = remoteValue.GetExpressionPath(out expressionPath); var valueInfo = new GrpcValueInfo { ExpressionPath = expressionPath ?? "", HasExpressionPath = hasExpressionPath, NumChildren = remoteValue.GetNumChildren(), Summary = remoteValue.GetSummary() ?? "", TypeName = remoteValue.GetTypeName() ?? "", Value = remoteValue.GetValue() ?? "", ValueType = EnumUtil.ConvertTo <Debugger.Common.ValueType>( remoteValue.GetValueType()), IsPointerType = remoteValue.TypeIsPointerType(), ByteSize = remoteValue.GetByteSize(), }; var typeInfo = remoteValue.GetTypeInfo(); if (typeInfo != null) { valueInfo.Type = GrpcFactoryUtils.CreateType( typeInfo, typeStore.AddObject(typeInfo)); } return(valueInfo); }
public virtual string FormatExpressionForAssignment( RemoteValue remoteValue, string expression) { if (remoteValue.GetTypeInfo().GetTypeFlags().HasFlag(TypeFlags.IS_FLOAT)) { return(FloatRadixConversionHelper.TryConvertToFloatFromNumberString( expression, new System.Lazy <int>(() => (int)remoteValue.GetByteSize()))); } return(expression); }
public virtual string FormatValueAsAddress(RemoteValue remoteValue) { TypeFlags flags = remoteValue?.GetTypeInfo()?.GetTypeFlags() ?? 0; if (flags.HasFlag(TypeFlags.IS_REFERENCE) || flags.HasFlag(TypeFlags.IS_POINTER)) { return($"0x{remoteValue.GetValueAsUnsigned():x16}"); } return(string.Empty); }
public IEnumerable <string> GetAllInheritedTypes() { SbType typeInfo = _remoteValue.GetTypeInfo(); if (typeInfo == null) { yield break; } TypeFlags typeFlags = typeInfo.GetTypeFlags(); if (typeFlags.HasFlag(TypeFlags.IS_POINTER) || typeFlags.HasFlag(TypeFlags.IS_REFERENCE)) { typeInfo = typeInfo.GetPointeeType(); if (typeInfo == null) { yield break; } } var typeQueue = new Queue <SbType>(); typeQueue.Enqueue(typeInfo); while (typeQueue.Count > 0) { SbType curType = typeQueue.Dequeue(); yield return(curType.GetName()); uint numDirectBaseClasses = curType.GetNumberOfDirectBaseClasses(); for (uint i = 0; i < numDirectBaseClasses; i++) { typeQueue.Enqueue(curType.GetDirectBaseClassAtIndex(i).GetTypeInfo()); } } }
public override string FormatValueAsAddress(RemoteValue remoteValue) { TypeFlags flags = remoteValue?.GetTypeInfo()?.GetTypeFlags() ?? 0; if (flags.HasFlag(TypeFlags.IS_REFERENCE) || flags.HasFlag(TypeFlags.IS_POINTER)) { if (ValueFormat == ValueFormat.HexUppercase) { return($"{remoteValue.GetValueAsUnsigned():X16}"); } else { return($"{remoteValue.GetValueAsUnsigned():x16}"); } } return(string.Empty); }
/// <summary> /// Returns a casted raw address expression that can be used to build a value assign /// expression. /// /// Can return null. /// </summary> public static string GetMemoryAddressAssignExpression(this RemoteValue remoteValue) { if (!IsValidValue(remoteValue)) { return(null); } var flags = remoteValue.GetTypeInfo().GetTypeFlags(); if (flags.HasFlag(TypeFlags.IS_REFERENCE)) { // NOTE: This works for references implemented as a pointer. It is not known how // this will work for other implementations. var typeName = remoteValue.GetTypeName(); typeName = typeName.Replace("&", ""); return($"(*(({typeName}*){remoteValue.GetDefaultValue()}))"); } RemoteValue addressOfValue; if (!TryGetAddressOf(remoteValue, out addressOfValue)) { return(null); } if (flags.HasFlag(TypeFlags.IS_POINTER)) { return($"(({remoteValue.GetTypeName()}){remoteValue.GetDefaultValue()})"); } if (flags.HasFlag(TypeFlags.IS_ARRAY)) { return(null); } return($"(*(({remoteValue.GetTypeName()}*){addressOfValue.GetDefaultValue()}))"); }
/// <summary> /// Determines if a RemoteValue is a valid value. i.e. has correct type information and /// isn't an error. /// </summary> /// <param name="remoteValue"></param> /// <returns></returns> private static bool IsValidValue(RemoteValue remoteValue) { return(remoteValue != null && remoteValue.GetTypeInfo() != null && !remoteValue.GetError().Fail()); }
public virtual SbType GetTypeInfo() { return(value.GetTypeInfo()); }