/// <inheritdoc />
        public override void VisitField(CppField cppField)
        {
            AlignAttribute alignmentAttribute = cppField.FieldInfo.GetCustomAttribute <AlignAttribute>();
            string         fieldCodeString    = alignmentAttribute == null
                ? string.Empty
                : $"alignas({alignmentAttribute.Size}) ";

            if (cppField.FieldInfo.IsFixedSizedArray())
            {
                // Field is a fixed size array.
                //
                string cppElementTypeFullName = CppTypeMapper.GetCppFullTypeName(cppField.FieldInfo.FieldType.GetElementType());

                FixedSizeArrayAttribute arrayAttribute = cppField.FieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                fieldCodeString += $"std::array<{cppElementTypeFullName}, {arrayAttribute.Length}> {cppField.FieldInfo.Name} = {{ }};";
            }
            else
            {
                string cppTypeFullName = CppTypeMapper.GetCppFullTypeName(cppField.FieldInfo.FieldType);
                fieldCodeString += $"{cppTypeFullName} {cppField.FieldInfo.Name};";
            }

            WriteLine(fieldCodeString);
            WriteLine();
        }
        /// <inheritdoc />
        public override void BeginVisitType(Type sourceType)
        {
            string cppClassName         = sourceType.Name;
            string cppProxyTypeFullName = CppTypeMapper.GetCppProxyFullTypeName(sourceType);

            AlignAttribute alignmentAttribute      = sourceType.GetCustomAttribute <AlignAttribute>();
            string         structAlignAsCodeString = alignmentAttribute == null
                ? string.Empty
                : $"alignas({alignmentAttribute.Size})";

            WriteBlock($@"
                    struct {structAlignAsCodeString} {cppClassName}
                    {{
                        typedef {cppProxyTypeFullName} ProxyObjectType;");

            IndentationLevel++;
        }
Exemple #3
0
        private bool IsValidAlignmentSizeAttribute(FieldInfo fieldInfo, out uint alignment)
        {
            alignment = 0;
            AlignAttribute alignmentSizeAttribute = fieldInfo.GetCustomAttribute <AlignAttribute>();

            if (alignmentSizeAttribute == null)
            {
                return(true);
            }

            bool isValid = IsPowerOfTwo(alignmentSizeAttribute.Size);

            if (isValid)
            {
                alignment = alignmentSizeAttribute.Size;
            }

            return(isValid);
        }
Exemple #4
0
        private void DefineCppType(Type sourceType, bool hasVariableSerializableLength, out List <CppField> cppFields)
        {
            cppFields = new List <CppField>();

            // Build list of structure properties.
            // Calculate fields offsets for flatten structure.
            //
            uint cppStructOffset = 0;

            // Calculate the type alignment, this is required when type is used as inner type in other types.
            //
            uint alignment = 1;

            // Export public instance fields.
            //
            foreach (FieldInfo fieldInfo in sourceType.GetPublicInstanceFields())
            {
                if (sourceType.IsCodegenConfigType() && !fieldInfo.IsScalarSetting())
                {
                    AddUntaggedOrNoneScalarPublicSettingRegistryField(sourceType, fieldInfo);
                    continue;
                }

                if (!IsSupportedFieldType(fieldInfo, out CppType cppFieldType))
                {
                    AddUnsupportedFieldTypeError(sourceType, fieldInfo);
                    continue;
                }

                if (!IsValidAlignmentSizeAttribute(fieldInfo, out uint customFieldAlignment))
                {
                    AddInvalidAlignmentSizeError(sourceType, fieldInfo);
                    continue;
                }

                // Align the field offset and update type aligment.
                //
                uint fieldAlignment = customFieldAlignment == 0
                    ? cppFieldType.Alignment
                    : customFieldAlignment;

                if (fieldAlignment != 0)
                {
                    cppStructOffset = CppTypeMapper.AlignSize(cppStructOffset, fieldAlignment);

                    alignment = Math.Max(alignment, fieldAlignment);
                }

                // Calculate type size.
                //
                uint typeSize = cppFieldType.TypeSize;

                // Calculate field size in case when we have an array.
                //
                if (fieldInfo.IsFixedSizedArray())
                {
                    if (!fieldInfo.IsInitOnly)
                    {
                        AddMissingFieldReadonlyModifierError(sourceType, fieldInfo);
                    }

                    if (!sourceType.IsClass)
                    {
                        AddIncorrectDefinitionError(sourceType, fieldInfo);
                    }

                    FixedSizeArrayAttribute arrayAttribute = fieldInfo.GetCustomAttribute <FixedSizeArrayAttribute>();

                    // Adjust the structure size.
                    //
                    typeSize += typeSize * (arrayAttribute.Length - 1);
                }

                cppFields.Add(
                    new CppField
                {
                    CppStructOffset = cppStructOffset,
                    FieldInfo       = fieldInfo,
                    CppType         = cppFieldType,
                });

                cppStructOffset += typeSize;
            }

            if (CodeGenErrors.Any())
            {
                // We are unable to generate code, return early.
                //
                return;
            }

            uint paddingSize = 0;

            // Align structure size unless it has explicitly defined size.
            //
            if (sourceType.StructLayoutAttribute.Size == 0)
            {
                cppStructOffset = CppTypeMapper.AlignSize(cppStructOffset, alignment);
            }
            else
            {
                // Explicitly defined size, calculate padding.
                //
                paddingSize      = (uint)sourceType.StructLayoutAttribute.Size - cppStructOffset;
                cppStructOffset += paddingSize;
            }

            // Check the final structure alignment.
            //
            AlignAttribute alignmentAttribute = sourceType.GetCustomAttribute <AlignAttribute>();

            if (alignmentAttribute != null)
            {
                alignment = alignmentAttribute.Size;
            }

            // Define a new Cpp type.
            //
            CppTypeMapper.DefineType(
                sourceType,
                cppTypeSize: cppStructOffset,
                aligment: alignment,
                paddingSize: paddingSize,
                hasVariableSerializableLength: hasVariableSerializableLength);
        }