public Symbol(Module module, IDiaSymbol symbol)
{
this.symbol = symbol;
Module = module;
Tag = (SymTagEnum)symbol.symTag;
BasicType = (BasicType)symbol.baseType;
Id = symbol.symIndexId;
if (Tag != SymTagEnum.SymTagExe)
Name = TypeToString.GetTypeString(symbol);
else
Name = "";
Name = Name.Replace("<enum ", "<").Replace(",enum ", ",");
Offset = symbol.offset;
var size = symbol.length;
if (size > int.MaxValue)
throw new ArgumentException("Symbol size is unexpected");
Size = (int)size;
// Initialize caches
fields = SimpleCache.Create(() => symbol.GetChildren(SymTagEnum.SymTagData).Select(s => new SymbolField(this, s)).Where(f => f.Type != null).ToArray());
baseClasses = SimpleCache.Create(() => symbol.GetChildren(SymTagEnum.SymTagBaseClass).Select(s => Module.GetSymbol(s)).ToArray());
elementType = SimpleCache.Create(() =>
{
if (Tag == SymTagEnum.SymTagPointerType || Tag == SymTagEnum.SymTagArrayType)
{
IDiaSymbol type = symbol.type;
if (type != null)
{
var result = Module.GetSymbol(type);
if (Tag == SymTagEnum.SymTagPointerType)
result.pointerType.Value = this;
return result;
}
}
return null;
});
pointerType = SimpleCache.Create(() =>
{
var result = Module.GetSymbol(symbol.objectPointerType);
result.elementType.Value = this;
return result;
});
userType = SimpleCache.Create(() => (UserType)null);
enumValues = SimpleCache.Create(() =>
{
List<Tuple<string, string>> result = new List<Tuple<string, string>>();
if (Tag == SymTagEnum.SymTagEnum)
{
foreach (var enumValue in symbol.GetChildren())
{
result.Add(Tuple.Create(enumValue.name, enumValue.value.ToString()));
}
}
return result.ToArray();
});
namespaces = SimpleCache.Create(() => SymbolNameHelper.GetSymbolNamespaces(Name));
}