/// <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++; }
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); }
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); }