Skip to content

ClangSharpPInvokeGenerator does not handle unsigned int bitshifts correctly #611

@Exanite

Description

@Exanite

When generating bindings for Vulkan using ClangSharpPInvokeGenerator through Silk.NET 3, the following C code is not converted into compilable C# code due to the bitshifts.

This results in the following error:

/Vulkan/Vulkan.gen.cs(25934,10): error CS0019: Operator '<<' cannot be applied to operands of type 'uint' and 'uint'

Relevant C code: https://github.com/KhronosGroup/Vulkan-Headers/blob/main/include/vulkan/vulkan_core.h

#define VK_MAKE_API_VERSION(variant, major, minor, patch) \
    ((((uint32_t)(variant)) << 29U) | (((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch)))


//#define VK_API_VERSION VK_MAKE_API_VERSION(0, 1, 0, 0) // Patch version should always be set to 0

// Vulkan 1.0 version number
#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0

Code as generated by Silk.NET:

[NativeTypeName("#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)")]
public const uint VK_API_VERSION_1_0 = (
    (((uint)(0)) << 29U) | (((uint)(1)) << 22U) | (((uint)(0)) << 12U) | ((uint)(0))
);

Code as found in TerraFX Vulkan: https://raw.githubusercontent.com/terrafx/terrafx.interop.vulkan/refs/heads/main/sources/Interop/Vulkan/Vulkan/vulkan/vulkan_core/Vulkan.cs

[NativeTypeName("#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)")]
public const uint VK_API_VERSION_1_0 = ((((uint)(0)) << 29) | (((uint)(1)) << 22) | (((uint)(0)) << 12) | ((uint)(0)));

Code when I regenerated the TerraFX Vulkan bindings locally (my Windows SDK version and Vulkan SDK version don't match, but I don't think that affects the code in question):
Note that the output matches Silk.NET, except in formatting, and the right-hand side of the bitshifts are unsigned ints.

[NativeTypeName("#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)")]
public const uint VK_API_VERSION_1_0 = ((((uint)(0)) << 29U) | (((uint)(1)) << 22U) | (((uint)(0)) << 12U) | ((uint)(0)));

I'm guessing the bindings in TerraFX Vulkan are manually modified to fix the unsigned int bitshifts.

If this is a valid issue, I can take a look at contributing a fix.

Also let me know what the expected output should look like.
I'm thinking of casting the right-hand side into a normal signed int.
Alternatively, we can drop the U from the integer literal, but that's a less general solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions