/// <summary> /// Adds the symbol to user type factory and generates the user type. /// </summary> /// <param name="symbol">The non-template symbol.</param> /// <param name="type">The XML type description.</param> /// <param name="nameSpace">The namespace.</param> /// <param name="generationFlags">The user type generation flags.</param> /// <returns>Generated user type for the specified symbol.</returns> internal UserType AddSymbol(Symbol symbol, XmlType type, string nameSpace, UserTypeGenerationFlags generationFlags) { UserType userType; if (symbol.Tag == CodeTypeTag.Enum) { userType = new EnumUserType(symbol, nameSpace, this); } else if (symbol.Tag == CodeTypeTag.ModuleGlobals) { userType = new GlobalsUserType(symbol, type, nameSpace, this); } else if (generationFlags.HasFlag(UserTypeGenerationFlags.GeneratePhysicalMappingOfUserTypes)) { userType = new PhysicalUserType(symbol, type, nameSpace, this); } else { userType = new UserType(symbol, type, nameSpace, this); } symbol.UserType = userType; return(userType); }
/// <summary> /// Adds the symbol to user type factory and generates the user type. /// </summary> /// <param name="symbol">The non-template symbol.</param> /// <param name="type">The XML type description.</param> /// <param name="nameSpace">The namespace.</param> /// <param name="generationFlags">The user type generation flags.</param> /// <returns>Generated user type for the specified symbol.</returns> internal UserType AddSymbol(Symbol symbol, XmlType type, string nameSpace, UserTypeGenerationFlags generationFlags) { UserType userType; if (symbol.Tag == SymTagEnum.SymTagEnum) { userType = new EnumUserType(symbol, nameSpace); } else if (symbol.Tag == SymTagEnum.SymTagExe) { userType = new GlobalsUserType(symbol, type, nameSpace); } else if (generationFlags.HasFlag(UserTypeGenerationFlags.GeneratePhysicalMappingOfUserTypes)) { userType = new PhysicalUserType(symbol, type, nameSpace); } else { userType = new UserType(symbol, type, nameSpace); } symbol.UserType = userType; return userType; }
/// <summary> /// Initializes a new instance of the <see cref="EnumTreeType"/> class. /// </summary> /// <param name="enumUserType">The enumeration user type.</param> public EnumTreeType(EnumUserType enumUserType) : base(enumUserType) { }
/// <summary> /// Gets the type instance for the specified symbol. /// </summary> /// <param name="parentType">The user type from which this symbol comes from (examples: field type, template type...).</param> /// <param name="symbol">The original type.</param> /// <param name="bitLength">Number of bits used for this symbol.</param> internal virtual TypeInstance GetSymbolTypeInstance(UserType parentType, Symbol symbol, int bitLength = 0) { switch (symbol.Tag) { case CodeTypeTag.BuiltinType: if (bitLength == 1) { return(new BasicTypeInstance(CodeNaming, typeof(bool))); } switch (symbol.BasicType) { case BasicType.Bit: case BasicType.Bool: return(new BasicTypeInstance(CodeNaming, typeof(bool))); case BasicType.Char: case BasicType.WChar: case BasicType.Char16: case BasicType.Char32: return(new BasicTypeInstance(CodeNaming, typeof(char))); case BasicType.BSTR: return(new BasicTypeInstance(CodeNaming, typeof(string))); case BasicType.Void: case BasicType.NoType: return(new BasicTypeInstance(CodeNaming, typeof(VoidType))); case BasicType.Float: return(new BasicTypeInstance(CodeNaming, symbol.Size <= 4 ? typeof(float) : typeof(double))); case BasicType.Int: case BasicType.Long: switch (symbol.Size) { case 0: return(new BasicTypeInstance(CodeNaming, typeof(VoidType))); case 1: return(new BasicTypeInstance(CodeNaming, typeof(sbyte))); case 2: return(new BasicTypeInstance(CodeNaming, typeof(short))); case 4: return(new BasicTypeInstance(CodeNaming, typeof(int))); case 8: return(new BasicTypeInstance(CodeNaming, typeof(long))); default: throw new Exception($"Unexpected type length {symbol.Size}"); } case BasicType.UInt: case BasicType.ULong: switch (symbol.Size) { case 0: return(new BasicTypeInstance(CodeNaming, typeof(VoidType))); case 1: return(new BasicTypeInstance(CodeNaming, typeof(byte))); case 2: return(new BasicTypeInstance(CodeNaming, typeof(ushort))); case 4: return(new BasicTypeInstance(CodeNaming, typeof(uint))); case 8: return(new BasicTypeInstance(CodeNaming, typeof(ulong))); default: throw new Exception($"Unexpected type length {symbol.Size}"); } case BasicType.Hresult: return(new BasicTypeInstance(CodeNaming, typeof(uint))); // TODO: Create Hresult type default: throw new Exception($"Unexpected basic type {symbol.BasicType}"); } case CodeTypeTag.Pointer: { Symbol pointerType = symbol.ElementType; UserType pointerUserType; // When exporting pointer from Global Modules, always export types as code pointer. if (parentType is GlobalsUserType && GetUserType(pointerType, out pointerUserType)) { return(new PointerTypeInstance(UserTypeInstance.Create(pointerUserType, this))); } TypeInstance innerType = GetSymbolTypeInstance(parentType, pointerType); if (innerType is TemplateArgumentTypeInstance) { return(new PointerTypeInstance(innerType)); } switch (pointerType.Tag) { case CodeTypeTag.BuiltinType: case CodeTypeTag.Enum: { if ((innerType as BasicTypeInstance)?.BasicType == typeof(VoidType)) { return(new BasicTypeInstance(CodeNaming, typeof(NakedPointer))); } return(new PointerTypeInstance(innerType)); } case CodeTypeTag.Class: case CodeTypeTag.Structure: case CodeTypeTag.Union: return(innerType); default: return(new PointerTypeInstance(innerType)); } } case CodeTypeTag.Enum: case CodeTypeTag.Class: case CodeTypeTag.Structure: case CodeTypeTag.Union: case CodeTypeTag.TemplateArgumentConstant: { // Try to apply transformation on the type UserTypeTransformation transformation = FindTransformation(symbol, parentType); if (transformation != null) { return(new TransformationTypeInstance(CodeNaming, transformation)); } // Try to find user type that represents current type UserType userType; if (GetUserType(symbol, out userType)) { TypeInstance type = UserTypeInstance.Create(userType, this); TemplateTypeInstance genericsTree = type as TemplateTypeInstance; if (genericsTree != null && !genericsTree.CanInstantiate) { return(new VariableTypeInstance(CodeNaming)); } return(type); } // We were unable to find user type. If it is enum, use its basic type if (symbol.Tag == CodeTypeTag.Enum) { return(new BasicTypeInstance(CodeNaming, EnumUserType.GetEnumBasicType(symbol))); } // Is it template argument constant? if (symbol.Tag == CodeTypeTag.TemplateArgumentConstant && symbol.UserType is TemplateArgumentConstantUserType constantArgument) { return(new TemplateArgumentConstantTypeInstance(constantArgument)); } // Fall-back to Variable return(new VariableTypeInstance(CodeNaming)); } case CodeTypeTag.Array: return(new ArrayTypeInstance(GetSymbolTypeInstance(parentType, symbol.ElementType))); case CodeTypeTag.Function: return(new FunctionTypeInstance(CodeNaming)); case CodeTypeTag.BaseClass: { symbol = symbol.Module.GetSymbol(symbol.Name); return(GetSymbolTypeInstance(parentType, symbol, bitLength)); } default: throw new Exception("Unexpected type tag " + symbol.Tag); } }