Files
UnrealEngine/Engine/Extras/ThirdPartyNotUE/crunchersharp/SymbolMemberInfo.cs
2025-05-18 13:04:45 +08:00

197 lines
4.5 KiB
C#

using Dia2Lib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace CruncherSharp
{
public class SymbolMemberInfo
{
public enum MemberCategory
{
VTable = 0,
Base = 1,
Member = 2,
UDT = 3,
Pointer = 4
}
public MemberCategory Category { get; set; }
public string Name { get; set; }
public string DisplayName
{
get
{
switch (Category)
{
case MemberCategory.VTable:
return "vtable";
case MemberCategory.Base:
return $"Base: {Name}";
default:
return Name;
}
}
}
public string TypeName { get; }
public ulong Size { get; set; }
public uint Count { get; }
public uint BitSize { get; }
public ulong Offset { get; }
public uint BitPosition { get; }
public uint PaddingBefore { get; set; }
public uint BitPaddingAfter { get; set; }
public uint MinAlignment
{
get
{
switch (Category)
{
case MemberCategory.VTable:
case MemberCategory.Pointer:
return 8;
default:
if (TypeInfo != null)
return TypeInfo.ComputeMinAlignment();
if (PaddingBefore >= 8)
{
return 16;
}
uint Alignemnt = (uint)Size;
if (Count > 0)
Alignemnt = (uint)(Size / Count);
if (Alignemnt > 16) // impossible, ignore
{
Alignemnt = 1;
}
if (PaddingBefore >= 4 && Alignemnt < 8)
{
Alignemnt = 8;
}
else if (PaddingBefore >= 2 && Alignemnt < 4)
{
Alignemnt = 4;
}
else if (PaddingBefore > 0 && Alignemnt < 2)
{
Alignemnt = 2;
}
return Alignemnt;
}
}
}
public bool AlignWithPrevious { get; set; }
public bool BitField { get; set; }
public bool Volatile { get; set; }
public bool Expanded { get; set; }
public SymbolInfo TypeInfo { get; set; }
public uint? PotentialSaving { get; set; }
public SymbolMemberInfo(MemberCategory category, string name, string typeName, ulong size, uint bitSize, ulong offset, uint bitPosition)
{
Category = category;
Name = name;
TypeName = typeName;
Size = size;
BitSize = bitSize;
Offset = offset;
BitPosition = bitPosition;
AlignWithPrevious = false;
PaddingBefore = 0;
BitPaddingAfter = 0;
BitField = false;
Volatile = false;
Expanded = false;
PotentialSaving = null;
if (TypeName.EndsWith("]"))
{
try
{
string arraySizestring = TypeName.Substring(TypeName.IndexOf('[') + 1, TypeName.IndexOf(']') - TypeName.IndexOf('[') - 1);
Count = UInt32.Parse(arraySizestring);
if (Count == 0)
Count = 1;
}
catch
{
Count = 1;
}
}
else
{
Count = 1;
}
}
public bool IsBase => Category == MemberCategory.Base;
public bool IsExapandable => (Category == MemberCategory.Base || Category == MemberCategory.UDT);
public static int CompareOffsets(SymbolMemberInfo a, SymbolMemberInfo b)
{
if (a.Offset != b.Offset)
{
return a.Offset < b.Offset ? -1 : 1;
}
if (a.IsBase != b.IsBase)
{
return a.IsBase ? -1 : 1;
}
if (a.BitPosition != b.BitPosition)
{
return a.BitPosition < b.BitPosition ? -1 : 1;
}
if (a.Size != b.Size)
{
return a.Size > b.Size ? -1 : 1;
}
return 0;
}
public bool UpdateTypeInfo(SymbolAnalyzer analyzer)
{
if (TypeInfo == null)
{
if (Category != MemberCategory.VTable)
{
TypeInfo = analyzer.FindSymbolInfo(TypeName);
if (TypeInfo != null)
{
if (Size == 0)
{
Size = (uint)TypeInfo.Size;
return true;
}
else if (Size != TypeInfo.Size)
{
TypeInfo = null;
return false;
}
}
else if (TypeName.Contains('['))
{
string typeName = TypeName.Substring(0, TypeName.IndexOf("["));
TypeInfo = analyzer.FindSymbolInfo(TypeName);
}
}
return false;
}
return true;
}
}
}