Exemple #1
0
        private static void InternalConvertFromPInvokeFunction(
            CodeTextWriter tw,
            IMethodInformation method,
            PInvokeInfo pinvokeInfo)
        {
            tw.WriteLine("///////////////////////////////////////");
            tw.WriteLine("// [6] P/Invoke: {0}", method.FriendlyName);
            tw.SplitLine();

            tw.WriteLine(method.CLanguageFunctionPrototype);
            tw.WriteLine("{");

            using (var _ = tw.Shift())
            {
                var arguments = string.Join(
                    ", ",
                    method.Parameters.
                    Select(parameter => parameter.GetMarshaledInExpression()));

                if (method.ReturnType.IsVoidType)
                {
                    tw.WriteLine("{0}({1});", pinvokeInfo.EntryPoint, arguments);
                }
                else
                {
                    tw.WriteLine("return {0}({1});", pinvokeInfo.EntryPoint, arguments);
                }
            }

            tw.WriteLine("}");
            tw.SplitLine();
        }
        public void WriteCodeComment(CodeTextWriter tw)
        {
            switch (mode)
            {
            case DebugInformationOptions.CommentOnly:
                if (canWriteSequencePoint && (debug != null))
                {
                    // Write debugging information (opcode and line information)
                    tw.WriteLine(
                        "/* {0,-40} : {1}({2}) */",
                        ci,
                        Path.GetFileName(debug.Path),
                        debug.Line);
                    canWriteSequencePoint = false;
                }
                else
                {
                    // Write debugging information (only opcode information)
                    tw.WriteLine(
                        "/* {0} */",
                        ci);
                }
                break;

            case DebugInformationOptions.Full:
                // (Full debug information write at the WriteInformationBeforeCode.)
                tw.WriteLine(
                    "/* {0} */",
                    ci);
                break;
            }
        }
Exemple #3
0
        private static void InternalConvertFromAbstractFunction(
            CodeTextWriter tw,
            IMethodInformation method)
        {
            tw.WriteLine("///////////////////////////////////////");
            tw.WriteLine("// [5] Abstract: {0}", method.FriendlyName);
            tw.SplitLine();

            tw.WriteLine(method.CLanguageFunctionPrototype);
            tw.WriteLine("{");

            using (var _ = tw.Shift())
            {
                tw.WriteLine(
                    "// WARNING: Pure virtual function called.");
                tw.WriteLine(
                    "// TODO: throw : assert(0);");

                if (method.ReturnType.IsVoidType == false)
                {
                    tw.WriteLine(
                        "return ({0}){1};",
                        method.ReturnType.CLanguageTypeName,
                        method.ReturnType.IsNumericPrimitive ? "0" : "NULL");
                }
            }

            tw.WriteLine("}");
            tw.SplitLine();
        }
        public static void WriteBoxedValueType(CodeTextWriter Writer, TypeDefinition Type)
        {
            if (!Type.IsValueType)
            {
                return;
            }
            var    solved     = Type.InterfacesSolved();
            string Interfaces = string.Join(',', solved.Select(a => $"public {a.InterfaceType.CXXTypeName()}"));

            // [H2004] Boxed ValueType
            if (Type.HasGenericParameters)
            {
                Writer.WriteLine($"template<{Type.CXXTemplateParam()}>");
            }
            string classDef = $"struct {Type.CXXShortTypeName()}_V : public RTCLI::System::ValueType{(solved.Count == 0 ? "" : "," + Interfaces)}";

            using (var classScope = new CXXScopeDisposer(Writer, classDef, true,
                                                         $"// [H2004] Boxed ValueType {Type.CXXTypeName()}_V ",
                                                         $"// [H2004] Exit Boxed ValueType {Type.CXXTypeName()}_V"))
            {
                Writer.unindent().WriteLine("public:").indent();
                Writer.WriteLine($"using ValueType = {Type.CXXShortTypeName()};");
                //Writer.WriteLine($"using ValueType = struct {type.CXXShortTypeName()};");
                Writer.WriteLine($"{Type.CXXShortTypeName()} value;");
                WriteMethodSignatures(Writer, Type, false);
            }
        }
Exemple #5
0
        private static void InternalConvertFromInternalCallFunction(
            CodeTextWriter tw,
            IMethodInformation method)
        {
            Debug.Assert(method.IsExtern);

            tw.WriteLine("///////////////////////////////////////");
            tw.WriteLine(
                "// [6] {0}: {1}",
                (method.PInvokeInformation != null) ? "P/Invoke" : "IL2C/Invoke",
                method.FriendlyName);
            tw.SplitLine();

            // P/Invoke linkage doesn't verify the C header declarations.
            // It will lookp up by the library symbol name.
            if (method.PInvokeInformation != null)
            {
                tw.WriteLine(
                    "extern {0};",
                    method.CLanguagePInvokePrototype);
                tw.SplitLine();
            }

            if (method.IsPrivate)
            {
                tw.WriteLine("static inline {0}", method.CLanguageFunctionPrototype);
            }
            else
            {
                tw.WriteLine(method.CLanguageFunctionPrototype);
            }

            tw.WriteLine("{");

            using (var _ = tw.Shift())
            {
                var arguments = string.Join(
                    ", ",
                    method.Parameters.Select(GetMarshaledInExpression));

                if (method.ReturnType.IsVoidType)
                {
                    tw.WriteLine(
                        "{0}({1});",
                        method.CLanguageInteropName,
                        arguments);
                }
                else
                {
                    tw.WriteLine(
                        "return {0}({1});",
                        method.CLanguageInteropName,
                        arguments);
                }
            }

            tw.WriteLine("}");
            tw.SplitLine();
        }
Exemple #6
0
 public static void WriteTypePreDefinitions(
     CodeTextWriter twHeader,
     ITypeInformation targetType,
     IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring)
 {
     InternalWriteTypePreDefinitions(twHeader, targetType, typesByDeclaring);
     InternalWriteVTableTypePreDefinitions(twHeader, targetType, typesByDeclaring);
 }
Exemple #7
0
 public CXXScopeDisposer(CodeTextWriter parent, string Scope, bool bEndWithSemicolon = false)
 {
     this.parent           = parent;
     this.EndWithSemicolon = bEndWithSemicolon;
     parent.WriteLine(Scope);
     parent.WriteLine("{");
     parent.indent();
 }
Exemple #8
0
        private static void InternalConvertSetupExecutionFrame(
            CodeTextWriter tw,
            IExtractContextHost extractContext,
            PreparedMethodInformation preparedMethod,
            ILocalVariableInformation[] objRefEntries,
            ILocalVariableInformation[] valueEntries,
            DebugInformationWriteController debugInformationController)
        {
            tw.WriteLine("//-------------------");
            tw.WriteLine("// [3-5] Setup execution frame:");
            tw.SplitLine();

            // Important NULL assigner (p = NULL):
            //   Because these variables are pointer (of object reference 'O' type).
            //   So GC will traverse these variables just setup the stack frame.
            debugInformationController.WriteInformationBeforeCode(tw);
            tw.WriteLine(
                "{0}_EXECUTION_FRAME__ frame__ =",
                preparedMethod.Method.CLanguageFunctionName);
            using (var __ = tw.Shift())
            {
                if (valueEntries.Length >= 1)
                {
                    tw.WriteLine(
                        "{{ NULL, {0}, {1}, {2} }};",
                        objRefEntries.Length,
                        valueEntries.Length,
                        string.Join(
                            ", ",
                            objRefEntries.Select(___ => "NULL").
                            Concat(valueEntries.
                                   Select(valueEntry =>
                                          string.Format(
                                              "il2c_typeof({0}), NULL",
                                              valueEntry.TargetType.MangledUniqueName)))));
                }
                else
                {
                    // Make short initializer expression if value type not included,
                    // maybe C compiler makes better code.
                    tw.WriteLine(
                        "{{ NULL, {0} }};",
                        objRefEntries.Length);
                }
            }

            foreach (var valueEntry in valueEntries)
            {
                debugInformationController.WriteInformationBeforeCode(tw);
                tw.WriteLine(
                    "frame__.{0}_value_ptr__ = &{0};",
                    extractContext.GetSymbolName(valueEntry));
            }

            debugInformationController.WriteInformationBeforeCode(tw);
            tw.WriteLine("il2c_link_execution_frame(&frame__);");
            tw.SplitLine();
        }
 public static void IncludeUberHeaders(CodeTextWriter Writer, TypeDefinition Type)
 {
     Writer.WriteLine("// [S1000] Include Uber Headers.");
     Writer.WriteLine($"#include <{Type.CXXUberHeaderPath()}>");
     foreach (var assemblyReference in Type.Module.AssemblyReferences)
     {
         Writer.WriteLine($"#include <{assemblyReference.CXXUberHeaderPath()}>");
     }
 }
Exemple #10
0
        private static void EndMain(CodeTextWriter writer, TestRunnerGeneratorOptions options)
        {
            if (!String.IsNullOrEmpty(options.EndMarker))
            {
                writer.WriteLine("Console.WriteLine(\"{0}\");", options.EndMarker);
            }

            EndMethod(writer);
        }
Exemple #11
0
 public void Dispose()
 {
     if (parent != null)
     {
         parent.unindent();
         parent.WriteLine("}" + (EndWithSemicolon?";":""));
         parent = null;
     }
 }
Exemple #12
0
        private static void InternalConvertExecutionFrame(
            CodeTextWriter tw,
            IExtractContextHost extractContext,
            PreparedMethodInformation preparedMethod,
            ILocalVariableInformation[] objRefEntries,
            ILocalVariableInformation[] valueEntries)
        {
            tw.WriteLine("//-------------------");
            tw.WriteLine("// [3-7] Declare execution frame:");
            tw.SplitLine();

            tw.WriteLine(
                "typedef struct {0}_EXECUTION_FRAME_DECL",
                preparedMethod.Method.CLanguageFunctionName);
            tw.WriteLine("{");

            using (var _ = tw.Shift())
            {
                tw.WriteLine("const IL2C_EXECUTION_FRAME* pNext__;");
                tw.WriteLine("const uint16_t objRefCount__;");
                tw.WriteLine("const uint16_t valueCount__;");

                if (objRefEntries.Length >= 1)
                {
                    tw.WriteLine("//-------------------- objref");
                    foreach (var objRefEntry in objRefEntries)
                    {
                        tw.WriteLine(
                            "{0} {1};",
                            objRefEntry.TargetType.CLanguageTypeName,
                            extractContext.GetSymbolName(objRefEntry));
                    }
                }

                if (valueEntries.Length >= 1)
                {
                    tw.WriteLine("//-------------------- value type");
                    foreach (var valueEntry in valueEntries)
                    {
                        var name = extractContext.GetSymbolName(valueEntry);
                        tw.WriteLine(
                            "const IL2C_RUNTIME_TYPE {0}_type__;",
                            name);
                        tw.WriteLine(
                            "const {0}* {1}_value_ptr__;",
                            valueEntry.TargetType.CLanguageTypeName,
                            name);
                    }
                }
            }

            tw.WriteLine(
                "}} {0}_EXECUTION_FRAME__;",
                preparedMethod.Method.CLanguageFunctionName);
            tw.SplitLine();
        }
Exemple #13
0
 public CXXTypeScope(CodeTextWriter parent, TypeDefinition type)
     : base(parent,
            type.IsValueType ? CXXHeaderRules.StructDeclaration(type) :    // [C0001]
            type.IsInterface ? CXXHeaderRules.InterfaceDeclaration(type) : // [C0002]
            CXXHeaderRules.ClassDeclaration(type),                         //[C0003]
            true,
            $"// [H2000] TypeScope {type.CXXTypeName()} ",
            $"// [H2000] Exit TypeScope {type.CXXTypeName()}")
 {
 }
Exemple #14
0
        public static void WriteMethodSignatures(CodeTextWriter Writer, TypeDefinition Type, bool ValueType)
        {
            if (Type.Methods != null & Type.Methods.Count != 0)
            {
                Writer.WriteLine("// [H2001] Method Signatures");
                List <MethodDefinition> overrided = new List <MethodDefinition>();
                foreach (var method in Type.Methods)
                {
                    if (!ValueType && method.HasOverrides && method.IsVirtual)
                    {
                        foreach (var od in method.Overrides)
                        {
                            var odd = od.Resolve();
                            overrided.Add(odd);
                            Writer.WriteLine($"{odd.CXXMethodSignature()} override{CondStr(method.IsAbstract, "= 0")}{CondStr(method.IsFinal, " final")};");
                        }
                    }
                    else if (!ValueType && method.IsVirtual)
                    {
                        if (method.IsNewSlot)
                        {
                            Writer.WriteLine($"virtual {method.CXXMethodSignature()}{CondStr(method.IsAbstract, " = 0")}{CondStr(method.IsFinal, " final")};");
                        }
#if ENABLE_EXPLICT_OVERIDE
                        if (!Type.IsInterface && !method.IsAbstract)
                        {
                            Writer.WriteLine($"{method.CXXRetType()} {method.CXXRowName()}_Impl{method.CXXParamSequence(true)};");
                            foreach (var i in Type.Interfaces)
                            {
                                var itype = i.InterfaceType.Resolve();
                                foreach (var mtdd in itype.Methods)
                                {
                                    if (mtdd.Name == method.Name && !overrided.Contains(mtdd))
                                    {
                                        Writer.WriteLine($"virtual {mtdd.CXXMethodSignature()}{CondStr(method.IsAbstract, " = 0")}{CondStr(method.IsFinal, " final")};");
                                    }
                                }
                            }
                        }
#endif
                    }
                    else
                    {
                        if (method.HasGenericParameters)
                        {
                            Writer.WriteLine($"template<{method.CXXTemplateParam()}>");
                        }

                        Writer.WriteLine($"{method.CXXMethodSignature()};");
                    }
                }
                Writer.WriteLine();
            }
        }
        public void WriteInformationBeforeCode(CodeTextWriter tw)
        {
            if ((mode == DebugInformationOptions.Full) && (debug != null))
            {
                tw.WriteLineIgnoreIndent(
                    "#line {0} \"{1}\"",
                    debug.Line,
                    debug.Path.Replace("\\", "\\\\"));
            }

            canWriteSequencePoint = true;
        }
Exemple #16
0
 public static void WriteStaticFieldImplementation(CodeTextWriter Writer, TypeDefinition Type)
 {
     Writer.WriteLine("// [S2001] Static Field Implementation");
     foreach (var Field in Type.Fields)
     {
         if (Field.IsStatic)
         {
             Writer.WriteLine($"{Field.FieldType.CXXTypeName()} " +
                              $"{Type.CXXTypeName()}::{Utilities.GetCXXValidTokenString(Field.Name)};");
         }
     }
 }
Exemple #17
0
 public static void WriteFieldDeclaration(CodeTextWriter Writer, TypeDefinition Type)
 {
     if (Type.Fields != null & Type.Fields.Count != 0)
     {
         Writer.WriteLine("// [H2005] Field Declarations");
         foreach (var field in Type.Fields)
         {
             Writer.WriteLine(field.CXXFieldDeclaration());
         }
         Writer.WriteLine();
     }
 }
Exemple #18
0
 public ScopeNoUnusedWarning(CodeTextWriter writer)
 {
     Writer = writer;
     Writer.WriteLine("");
     Writer.WriteLine("// [S0001] Close Unused-Label Warnings.");
     Writer.WriteLine($"#if defined(RTCLI_COMPILER_CLANG)");
     Writer.WriteLine($"#pragma clang diagnostic push");
     Writer.WriteLine($"#pragma clang diagnostic ignored \"-Wunused-label\"");
     Writer.WriteLine($"#elif defined(RTCLI_COMPILER_MSVC)");
     Writer.WriteLine($"#pragma warning(push)");
     Writer.WriteLine($"#pragma warning(disable: 4102)");
     Writer.WriteLine($"#endif");
 }
Exemple #19
0
        public void WriteResult(CodeTextStorage storage)
        {
            var            assemblyInformation = translateContext.MetadataContext.Assemblies[translateContext.FocusedAssembly];
            CodeTextWriter writer = storage.Wirter(
                assemblyInformation.IdentName + ".json"
                );

            writer.WriteLine(
                JsonConvert.SerializeObject(
                    translateContext.MetadataContext.Assemblies[translateContext.FocusedAssembly],
                    Formatting.Indented)
                );
        }
 public CXXScopeDisposer(CodeTextWriter parent, string Scope, bool bEndWithSemicolon = false, string onEnter = null, string onExit = null)
 {
     this.parent           = parent;
     this.EndWithSemicolon = bEndWithSemicolon;
     this.onExit           = onExit;
     if (onEnter != null)
     {
         parent.WriteLine(onEnter);
     }
     parent.WriteLine(Scope);
     parent.WriteLine("{");
     parent.indent();
 }
Exemple #21
0
        public static void IncludeWeakReferences(CodeTextWriter Writer, TypeDefinition Type)
        {
            Writer.WriteLine("// [S1001] Include Uber Headers.");
            Writer.WriteLine($"#include <{Type.CXXHeaderPath()}>");
            var rs = Type.WeakReferences();

            foreach (var r in rs)
            {
                if (!r.IsImplementedByVM())
                {
                    Writer.WriteLine($"#include <{r.CXXHeaderPath()}>");
                }
            }
        }
Exemple #22
0
        private static void BeginProgram(CodeTextWriter writer, IType testSuite)
        {
            writer.WriteLine("using System;");
            //writer.WriteLine("using NUnit.Framework;");
            if (!String.IsNullOrEmpty(testSuite.Namespace))
            {
                writer.WriteLine("using {0};", testSuite.Namespace);
            }
            writer.WriteLine();

            writer.WriteLine("class Program");
            writer.WriteLine("{");
            writer.Indent();
        }
Exemple #23
0
        private static void InternalWriteVTableTypePreDefinitions(
            CodeTextWriter twHeader,
            ITypeInformation targetType,
            IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring)
        {
            if (typesByDeclaring.TryGetValue(targetType, out var types))
            {
                if (types.Length >= 1)
                {
                    twHeader.WriteLine("////////////////////////////////////////////////////////////");
                    twHeader.WriteLine("// [2-1-2] VTable types:");
                    twHeader.SplitLine();

                    foreach (var type in types)
                    {
                        // The nested types have to declare before outer types.
                        if (!type.Equals(targetType))
                        {
                            InternalWriteVTableTypePreDefinitions(
                                twHeader,
                                type,
                                typesByDeclaring);
                        }

                        // If virtual method collection doesn't contain newslot method at this declared type:
                        if (!type.NewSlotMethods.Any(method => method.DeclaringType.Equals(type)))
                        {
                            twHeader.WriteLine(
                                "typedef {0}_VTABLE_DECL__ {1}_VTABLE_DECL__;",
                                type.BaseType.MangledUniqueName,
                                type.MangledUniqueName);
                        }
                        // Require new vtable layout.
                        else
                        {
                            // Important: The vtable structure definition marked for "const",
                            //    because these vtables place into the ".rdata" section or same location.
                            //    Many small system have very tiny space for RAM (writable memory),
                            //    IL2C has to efficient memory space, vtable can place into ROM location.
                            twHeader.WriteLine(
                                "typedef const struct {0}_VTABLE_DECL___ {0}_VTABLE_DECL__;",
                                type.MangledUniqueName);
                        }
                    }

                    twHeader.SplitLine();
                }
            }
        }
Exemple #24
0
        public static void IncludeStrongReferences(CodeTextWriter Writer, TypeDefinition Type)
        {
            var StrongRefernces = Type.StrongRefernces();

            if (StrongRefernces.Count != 0)
            {
                Writer.WriteLine("// [H1001] Strong Referenced Types Headers");
                foreach (var R in StrongRefernces)
                {
                    if (!R.IsImplementedByVM())
                    {
                        Writer.WriteLine($"#include <{R.CXXHeaderPath()}>");
                    }
                }
            }
        }
Exemple #25
0
 private static void InternalWriteAssemblyReferences(
     CodeTextWriter tw,
     TranslateContext translateContext,
     IExtractContext extractContext,
     ITypeInformation declaringType)
 {
     foreach (var assembly in extractContext.EnumerateRegisteredTypesByDeclaringType(declaringType).
              Distinct().
              OrderByDependant(declaringType.DeclaringModule.DeclaringAssembly).
              Select(type => type.DeclaringModule.DeclaringAssembly).
              Where(assembly => !assembly.Equals(translateContext.Assembly)).
              Distinct().
              OrderBy(assembly => assembly.Name))
     {
         tw.WriteLine("#include <{0}.h>", assembly.Name);
     }
     tw.SplitLine();
 }
Exemple #26
0
        public static void WriteForwardDeclaration(CodeTextWriter Writer, TypeDefinition Type)
        {
            Writer.WriteLine("// [H0001] Forward Declaration");
            var rs = Type.WeakReferences();

            foreach (var r in rs)
            {
                if (r.HasGenericParameters || r.IsGenericInstance)
                {
                }
                else if (!r.IsImplementedByVM())
                {
                    Writer.WriteLine(
                        $"namespace {r.CXXNamespace()} " + "{ "
                        + $"struct {r.CXXShortTypeName()}; "
                        + "}");
                }
            }
        }
Exemple #27
0
        private static void InternalWriteHeader(
            CodeTextWriter twHeader,
            PreparedInformations prepared,
            ITypeInformation targetType,
            MemberScopes memberScope,
            IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring)
        {
            if (typesByDeclaring.TryGetValue(targetType, out var types))
            {
                foreach (var type in types)
                {
                    // The nested types have to declare before outer types.
                    if (!type.Equals(targetType))
                    {
                        InternalWriteHeader(
                            twHeader,
                            prepared,
                            type,
                            memberScope,
                            typesByDeclaring);
                    }

                    // Write value type and object reference type.
                    TypeWriter.WriteTypeDefinitions(
                        twHeader,
                        type);

                    // Write type members.
                    TypeWriter.WriteMemberDefinitions(
                        twHeader,
                        type,
                        field => true,
                        method =>
                        // Except type initializer
                        !(method.IsConstructor && method.IsStatic) &&
                        prepared.Functions.ContainsKey(method));

                    // TODO: The internal or private members can separate into the internal headers.
                    //field => field.CLanguageMemberScope == memberScope,
                    //method => (method.CLanguageMemberScope == memberScope) && prepared.Functions.ContainsKey(method));
                }
            }
        }
Exemple #28
0
        private static void WriteRunnerCode(this IMethod test, CodeTextWriter writer, TestRunnerGeneratorOptions options)
        {
            if (options == null)
            {
                options = new TestRunnerGeneratorOptions {
                    Protect = true
                }
            }
            ;

            var testSuite = test.DeclaringType;

            BeginProgram(writer, testSuite);

            BeginMain(writer);

            RunTest(writer, options, test);

            EndMain(writer, options);

            EndProgram(writer);
        }
        private void WriteTypeRecursively(CodeTextWriter codeWriter, TypeDefinition type)
        {
            if (type.IsEnum)
            {
                CXXHeaderRules.WriteEnumType(codeWriter, type);
                return;
            }

            // [C0004] generic
            if (type.HasGenericParameters)
            {
                codeWriter.WriteLine(CXXHeaderRules.GenericDeclaration(type));
            }

            // [H2000] Type Scope
            using (var typeScope = new CXXTypeScope(codeWriter, type))
            {
                codeWriter.unindent().WriteLine("public:").indent();
                foreach (var nested in type.NestedTypes)
                {
                    // [H2002] Inner Types
                    codeWriter.WriteLine($"// [H2002] Inner Types {nested.CXXShortTypeName()}");
                    WriteTypeRecursively(codeWriter, nested);
                }
                // [H2001] Method Signatures
                CXXHeaderRules.WriteMethodSignatures(codeWriter, type, type.IsValueType);

                // [H2005] Field Declaration
                CXXHeaderRules.WriteFieldDeclaration(codeWriter, type);
            }

            // [H2004] Boxed ValueType
            if (!type.IsValueType)
            {
                return;
            }
            CXXHeaderRules.WriteBoxedValueType(codeWriter, type);
        }
Exemple #30
0
        public static void WriteEnumType(CodeTextWriter Writer, TypeDefinition Type)
        {
            if (!Type.IsEnum)
            {
                return;
            }
            Writer.WriteLine($"using {Type.CXXShortTypeName()} = {Type.Fields.First().FieldType.CXXTypeName()};");
            string classDef = $"struct {Type.CXXShortTypeName()}_V : public RTCLI::System::Enum";

            using (var classScope = new CXXScopeDisposer(Writer, classDef, true,
                                                         $"// [H2004] Boxed ValueType {Type.CXXTypeName()}_V ",
                                                         $"// [H2004] Exit Boxed ValueType {Type.CXXTypeName()}_V"))
            {
                Writer.unindent().WriteLine("public:").indent();
                Writer.WriteLine($"using ValueType = {Type.CXXShortTypeName()};");
                //Writer.WriteLine($"using ValueType = struct {type.CXXShortTypeName()};");
                Writer.WriteLine($"{Type.CXXShortTypeName()} value;");
                foreach (var Field in Type.Fields.Skip(1))
                {
                    Writer.WriteLine($"static constexpr {Type.CXXShortTypeName()} {Field.Name} = {Field.Constant};");
                }
            }
        }