/// <summary> /// Initializes a new instance of the <see cref="PdbSymbol"/> class. /// </summary> /// <param name="module">Module that contains this symbol.</param> /// <param name="typeIndex">Type index of the simple build-in type.</param> public PdbSymbol(PdbModule module, TypeIndex typeIndex) : base(module) { PdbModule = module; Id = typeIndex.Index; Initialize(typeIndex); }
/// <summary> /// Gets user type fields. /// </summary> protected override IEnumerable <SymbolField> GetFields() { TypeIndex fieldListIndex = TypeIndex.None; if (typeRecord is ClassRecord classRecord) { fieldListIndex = classRecord.FieldList; } else if (typeRecord is UnionRecord unionRecord) { fieldListIndex = unionRecord.FieldList; } foreach (TypeRecord field in EnumerateFieldList(fieldListIndex)) { if (field is DataMemberRecord dataMember) { yield return(new PdbSymbolField(this, dataMember)); } else if (field is StaticDataMemberRecord staticDataMember) { yield return(new PdbSymbolField(this, staticDataMember)); } } }
/// <summary> /// Gets PDB symbol for the specified type index. /// </summary> /// <param name="index">Type index.</param> public PdbSymbol GetSymbol(TypeIndex index) { if (index.IsSimple) { return(builtinSymbolsCache[index]); } return(definedSymbolsCache[(int)index.ArrayIndex]); }
/// <summary> /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. /// </summary> /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> /// <returns> /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. /// </returns> public override bool Equals(object obj) { if (obj.GetType() != typeof(TypeIndex)) { return(false); } TypeIndex ti = (TypeIndex)obj; return(Index == ti.Index); }
/// <summary> /// Enumerates type records from field list type index. /// </summary> /// <param name="fieldListIndex">Type index of the field list type record.</param> private IEnumerable <TypeRecord> EnumerateFieldList(TypeIndex fieldListIndex) { while (fieldListIndex != TypeIndex.None) { TypeIndex nextFieldListIndex = TypeIndex.None; TypeRecord fieldList = PdbModule.PdbFile.TpiStream[fieldListIndex]; if (fieldList is FieldListRecord fieldListRecord) { foreach (TypeRecord field in fieldListRecord.Fields) { if (field is ListContinuationRecord listContinuation) { nextFieldListIndex = listContinuation.ContinuationIndex; } else { yield return(field); } } } fieldListIndex = nextFieldListIndex; } }
/// <summary> /// Creates new <see cref="PdbSymbol"/> for the specified type index. /// </summary> /// <param name="index">Type index in the TPI stream.</param> private PdbSymbol CreateSymbol(int index) { TypeIndex typeIndex = TypeIndex.FromArrayIndex(index); return(new PdbSymbol(this, typeIndex.Index, PdbFile.TpiStream[typeIndex])); }
/// <summary> /// Creates new <see cref="PdbSymbol"/> for the specified built-in type index. /// </summary> /// <param name="index">Built-in type index.</param> private PdbSymbol CreateBuiltinSymbol(TypeIndex typeIndex) { return(new PdbSymbol(this, typeIndex)); }
/// <summary> /// Gets all types defined in the symbol. /// </summary> public override IEnumerable <Symbol> GetAllTypes() { TypeLeafKind[] kinds = new TypeLeafKind[] { TypeLeafKind.LF_CLASS, TypeLeafKind.LF_STRUCTURE, TypeLeafKind.LF_INTERFACE, TypeLeafKind.LF_UNION, TypeLeafKind.LF_ENUM }; List <Symbol> selectedSymbols = new List <Symbol>(); // Find all symbols that will be returned and populate symbolsByUniqueName. symbolsByUniqueName = new Dictionary <string, PdbSymbol>(); foreach (TypeLeafKind kind in kinds) { foreach (TypeIndex typeIndex in PdbFile.TpiStream.GetIndexes(kind)) { PdbSymbol symbol = allSymbolsCache[(int)typeIndex.ArrayIndex] = CreateSymbol((int)typeIndex.ArrayIndex), oldSymbol; if (string.IsNullOrEmpty(symbol.UniqueName)) { selectedSymbols.Add(symbol); } else if (!symbolsByUniqueName.TryGetValue(symbol.UniqueName, out oldSymbol)) { symbolsByUniqueName.Add(symbol.UniqueName, symbol); } else if (oldSymbol.IsForwardReference && !symbol.IsForwardReference) { symbolsByUniqueName[symbol.UniqueName] = symbol; } } } selectedSymbols.AddRange(symbolsByUniqueName.Values); // Now that we have symbolsByUniqueName, we can search for defined symbols. symbolsByName = new Dictionary <string, PdbSymbol>(); foreach (TypeLeafKind kind in kinds) { foreach (TypeIndex typeIndex in PdbFile.TpiStream.GetIndexes(kind)) { PdbSymbol symbol = definedSymbolsCache[(int)typeIndex.ArrayIndex]; if (!string.IsNullOrEmpty(symbol.Name) && !symbolsByName.ContainsKey(symbol.Name)) { symbolsByName.Add(symbol.Name, symbol); } } } // Add all known built-in types into symbolsByName foreach (TypeIndex typeIndex in TypeIndex.BuiltinTypes) { PdbSymbol symbol = builtinSymbolsCache[typeIndex]; if (!string.IsNullOrEmpty(symbol.Name) && !symbolsByName.ContainsKey(symbol.Name)) { symbolsByName.Add(symbol.Name, symbol); } } // Add pointer to all known built-in types into symbolsByName foreach (TypeIndex t in TypeIndex.BuiltinTypes) { TypeIndex typeIndex = new TypeIndex(t.SimpleKind, SimpleTypeMode.NearPointer); PdbSymbol symbol = builtinSymbolsCache[typeIndex]; if (!string.IsNullOrEmpty(symbol.Name) && !symbolsByName.ContainsKey(symbol.Name)) { symbolsByName.Add(symbol.Name, symbol); } } return(selectedSymbols); }
/// <summary> /// Initializes data based on the simple built-in type. /// </summary> private void Initialize(TypeIndex typeIndex) { Name = typeIndex.SimpleTypeName; Tag = typeIndex.SimpleMode != SimpleTypeMode.Direct ? Engine.CodeTypeTag.Pointer : Engine.CodeTypeTag.BuiltinType; switch (typeIndex.SimpleKind) { case SimpleTypeKind.None: BasicType = DIA.BasicType.NoType; Size = 0; break; case SimpleTypeKind.Void: BasicType = DIA.BasicType.Void; Size = 0; break; case SimpleTypeKind.HResult: BasicType = DIA.BasicType.Hresult; Size = 4; break; case SimpleTypeKind.UnsignedCharacter: BasicType = DIA.BasicType.UInt; Size = 1; break; case SimpleTypeKind.NarrowCharacter: case SimpleTypeKind.SignedCharacter: BasicType = DIA.BasicType.Char; Size = 1; break; case SimpleTypeKind.WideCharacter: BasicType = DIA.BasicType.WChar; Size = 2; break; case SimpleTypeKind.Character16: BasicType = DIA.BasicType.Char16; Size = 2; break; case SimpleTypeKind.Character32: BasicType = DIA.BasicType.Char32; Size = 4; break; case SimpleTypeKind.SByte: BasicType = DIA.BasicType.Int; Size = 1; break; case SimpleTypeKind.Byte: BasicType = DIA.BasicType.UInt; Size = 1; break; case SimpleTypeKind.Int16Short: case SimpleTypeKind.Int16: BasicType = DIA.BasicType.Int; Size = 2; break; case SimpleTypeKind.UInt16: case SimpleTypeKind.UInt16Short: BasicType = DIA.BasicType.UInt; Size = 2; break; case SimpleTypeKind.Int32Long: case SimpleTypeKind.Int32: BasicType = DIA.BasicType.Int; Size = 4; break; case SimpleTypeKind.UInt32Long: case SimpleTypeKind.UInt32: BasicType = DIA.BasicType.UInt; Size = 4; break; case SimpleTypeKind.Int64Quad: case SimpleTypeKind.Int64: BasicType = DIA.BasicType.Long; Size = 8; break; case SimpleTypeKind.UInt64Quad: case SimpleTypeKind.UInt64: BasicType = DIA.BasicType.ULong; Size = 8; break; case SimpleTypeKind.Int128Oct: case SimpleTypeKind.Int128: BasicType = DIA.BasicType.Long; Size = 16; break; case SimpleTypeKind.UInt128Oct: case SimpleTypeKind.UInt128: BasicType = DIA.BasicType.ULong; Size = 16; break; case SimpleTypeKind.Float16: BasicType = DIA.BasicType.Float; Size = 2; break; case SimpleTypeKind.Float32: case SimpleTypeKind.Float32PartialPrecision: BasicType = DIA.BasicType.Float; Size = 4; break; case SimpleTypeKind.Float48: BasicType = DIA.BasicType.Float; Size = 6; break; case SimpleTypeKind.Float64: BasicType = DIA.BasicType.Float; Size = 8; break; case SimpleTypeKind.Float80: BasicType = DIA.BasicType.Float; Size = 10; break; case SimpleTypeKind.Float128: BasicType = DIA.BasicType.Float; Size = 12; break; case SimpleTypeKind.Complex16: BasicType = DIA.BasicType.Complex; Size = 2; break; case SimpleTypeKind.Complex32: case SimpleTypeKind.Complex32PartialPrecision: BasicType = DIA.BasicType.Complex; Size = 4; break; case SimpleTypeKind.Complex48: BasicType = DIA.BasicType.Complex; Size = 6; break; case SimpleTypeKind.Complex64: BasicType = DIA.BasicType.Complex; Size = 8; break; case SimpleTypeKind.Complex80: BasicType = DIA.BasicType.Complex; Size = 10; break; case SimpleTypeKind.Complex128: BasicType = DIA.BasicType.Complex; Size = 16; break; case SimpleTypeKind.Boolean8: BasicType = DIA.BasicType.Bool; Size = 1; break; case SimpleTypeKind.Boolean16: BasicType = DIA.BasicType.Bool; Size = 2; break; case SimpleTypeKind.Boolean32: BasicType = DIA.BasicType.Bool; Size = 4; break; case SimpleTypeKind.Boolean64: BasicType = DIA.BasicType.Bool; Size = 8; break; case SimpleTypeKind.Boolean128: BasicType = DIA.BasicType.Bool; Size = 16; break; case SimpleTypeKind.NotTranslated: BasicType = DIA.BasicType.NoType; Size = 0; break; default: throw new NotImplementedException($"Unexpected simple type: {typeIndex.SimpleKind}, from type index: {typeIndex}"); } if (typeIndex.SimpleMode != SimpleTypeMode.Direct) { ElementType = PdbModule.GetSymbol(new TypeIndex(typeIndex.SimpleKind)); ElementType.PointerType = this; } }