public override void Process()

in SharpGen/Transform/StructTransform.cs [89:251]


        public override void Process(CsStruct csStruct)
        {
            // TODO: this mapping must be robust. Current calculation for field offset is not always accurate for union.
            // TODO: need to handle align/packing correctly.

            // If a struct was already mapped, then return immediately
            // The method MapStruct can be called recursively
            if (csStruct.IsFullyMapped)
                return;

            // Set IsFullyMappy in order to avoid recursive mapping
            csStruct.IsFullyMapped = true;

            // Get the associated CppStruct and CSharpTag
            var cppStruct = (CppStruct)csStruct.CppElement;

            // If this structure need to me moved to another container, move it now
            foreach (var keyValuePair in _mapMoveStructToInner)
            {
                if (keyValuePair.Key.Match(csStruct.CppElementName).Success)
                {
                    string cppName = keyValuePair.Key.Replace(csStruct.CppElementName, keyValuePair.Value);
                    var destSharpStruct = (CsStruct)TypeRegistry.FindBoundType(cppName);
                    // Remove the struct from his container
                    csStruct.Parent.Remove(csStruct);
                    // Add this struct to the new container struct
                    destSharpStruct.Add(csStruct);
                }
            }

            // Current offset of a field
            uint currentFieldAbsoluteOffset = 0;

            // Last field offset
            int previousFieldOffsetIndex = -1;

            // Size of the last field
            uint previousFieldSize = 0;

            uint maxSizeOfField = 0;

            bool isNonSequential = false;

            int cumulatedBitOffset = 0;

            var inheritedStructs = new Stack<CppStruct>();
            var currentStruct = cppStruct;
            while (currentStruct != null && currentStruct.Base != currentStruct.Name)
            {
                inheritedStructs.Push(currentStruct);
                currentStruct = TypeRegistry.FindBoundType(currentStruct.Base)?.CppElement as CppStruct;
            }

            while (inheritedStructs.Count > 0)
            {
                currentStruct = inheritedStructs.Pop();

                var fields = currentStruct.Fields.ToArray();
                int fieldCount = fields.Length;
                var fieldNames = NamingRules.Rename(fields);

                // -------------------------------------------------------------------------------
                // Iterate on all fields and perform mapping
                // -------------------------------------------------------------------------------
                for (int fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++)
                {
                    var cppField = fields[fieldIndex];
                    var fieldName = fieldNames[fieldIndex];
                    Logger.RunInContext(
                        cppField.ToString(),
                        () =>
                        {
                            var csField = factory.Create(cppField, fieldName);
                            csStruct.Add(csField);

                            // If last field has same offset, then it's a union
                            // CurrentOffset is not moved
                            if (isNonSequential && previousFieldOffsetIndex != cppField.Offset)
                            {
                                previousFieldSize = maxSizeOfField;
                                maxSizeOfField = 0;
                                isNonSequential = false;
                            }

                            currentFieldAbsoluteOffset += previousFieldSize;

                            // If field alignment is null, then we have a pointer somewhere so we can't align
                            if (csField.MarshalType.Alignment is { } fieldAlignment)
                            {
                                // otherwise, align the field on the alignment requirement of the field
                                var delta = currentFieldAbsoluteOffset % fieldAlignment;
                                if (delta != 0)
                                    currentFieldAbsoluteOffset += fieldAlignment - delta;
                            }

                            // Get correct offset (for handling union)
                            csField.Offset = currentFieldAbsoluteOffset;

                            // Handle bit fields : calculate BitOffset and BitMask for this field
                            if (previousFieldOffsetIndex != cppField.Offset)
                                cumulatedBitOffset = 0;

                            if (cppField.IsBitField)
                            {
                                var lastCumulatedBitOffset = cumulatedBitOffset;
                                cumulatedBitOffset += cppField.BitOffset;
                                csField.BitMask = (1 << cppField.BitOffset) - 1;
                                csField.BitOffset = lastCumulatedBitOffset;
                            }

                            var nextFieldIndex = fieldIndex + 1;
                            if (previousFieldOffsetIndex == cppField.Offset
                             || nextFieldIndex < fieldCount && fields[nextFieldIndex].Offset == cppField.Offset)
                            {
                                if (previousFieldOffsetIndex != cppField.Offset)
                                    maxSizeOfField = 0;

                                maxSizeOfField = Math.Max(csField.Size, maxSizeOfField);
                                isNonSequential = true;
                                csStruct.ExplicitLayout = true;
                                previousFieldSize = 0;
                            }
                            else
                            {
                                previousFieldSize = csField.Size;
                            }

                            previousFieldOffsetIndex = cppField.Offset;
                        }
                    );
                }
            }

            // In case of explicit layout, check that we can safely generate it on both x86 and x64 (in case of an union
            // using pointers, we can't)
            if (!csStruct.HasCustomMarshal && csStruct.ExplicitLayout && !cppStruct.IsUnion)
            {
                var fieldList = csStruct.Fields;
                for (var i = 0; i < fieldList.Count; i++)
                {
                    var field = fieldList[i];
                    var fieldAlignment = field.MarshalType.Alignment;

                    if (fieldAlignment.HasValue)
                        continue;

                    // If pointer field is not the last one, than we can't handle it
                    if (i + 1 >= fieldList.Count)
                        continue;

                    Logger.Error(
                        LoggingCodes.NonPortableAlignment,
                        "The field [{0}] in structure [{1}] has pointer alignment within a structure that requires explicit layout. This situation cannot be handled on both 32-bit and 64-bit architectures. This structure needs manual layout (remove fields from definition) and write them manually in xml mapping files",
                        field.CppElementName,
                        csStruct.CppElementName
                    );

                    break;
                }
            }

            csStruct.StructSize = currentFieldAbsoluteOffset + previousFieldSize;
        }