dotnet / ClangSharp

Clang bindings for .NET written in C#
MIT License
951 stars 148 forks source link

[bug] ClangSharp Pinvoke Gen: local variable reassignment leads to bad codegen (`.operator=`) #298

Open jasonswearingen opened 3 years ago

jasonswearingen commented 3 years ago

I am seeing some bad output in generating code for header libraries, regarding local variable reassignment. the cardinalAxis.operator=(tmp); line below:

        public static Vector3 Vector3Perpendicular(Vector3 v)
        {
            Vector3 result = new Vector3
            {
                X = 0,
            };
            float min = (float)(MathF.Abs(v.X));
            Vector3 cardinalAxis = new Vector3
            {
                X = 1.0f,
                Y = 0.0f,
                Z = 0.0f,
            };

            if (MathF.Abs(v.Y) < min)
            {
                min = (float)(MathF.Abs(v.Y));
                Vector3 tmp = new Vector3
                {
                    X = 0.0f,
                    Y = 1.0f,
                    Z = 0.0f,
                };

                cardinalAxis.operator=(tmp);
            }

            result.X = v.Y * cardinalAxis.Z - v.Z * cardinalAxis.Y;
            result.Y = v.Z * cardinalAxis.X - v.X * cardinalAxis.Z;
            result.Z = v.X * cardinalAxis.Y - v.Y * cardinalAxis.X;
            return result;
        }

The original cpp code in the .h file shows pretty normal stuff:

    Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};

    if (fabs(v.y) < min)
    {
        min = (float) fabs(v.y);
        Vector3 tmp = {0.0f, 1.0f, 0.0f};
        cardinalAxis = tmp;
    }

using latest commit on github

jasonswearingen commented 3 years ago

my current ultra-hacky workaround is to use a post-codegen search replace script, in powershell

##hack: replace malformed autogen content
$replaceFile = '../Raylib-CsLo/autogen/bindings/RayMath.cs'
(Get-Content $replaceFile).replace('.operator=', '=') | Set-Content $replaceFile

That workaround is sufficient so this is not a critical issue for me.

tannergooding commented 3 years ago

This is somewhat expected. Not all C/C++ code has a direct equivalent in C# and so they have to be special cased with alternatives and there are tons of patterns that simply aren't handled today.

operator = for example would need to be converted to some helper op_Assign method.