Missing C definitions in Swift interface

Hi, Swift newbie here. I previously asked for help with wrapping a C library with Swift (specifically SDL). Now I have ran into another issue, while mapping the C API to Swift I have noticed that in the .swiftinterface file that is generated by the Swift compiler/package manager several definitions are missing.

It's not like the entire header is missing and the file isn't being parsed. Most of the header is mapped and only some of the #defines are missing.

SDL_video.h snippet

/**
 * The flags on a window.
 *
 * These cover a lot of true/false, or on/off, window state. Some of it is
 * immutable after being set through SDL_CreateWindow(), some of it can be
 * changed on existing windows by the app, and some of it might be altered by
 * the user or system outside of the app's control.
 *
 * \since This datatype is available since SDL 3.2.0.
 *
 * \sa SDL_GetWindowFlags
 */
typedef Uint64 SDL_WindowFlags;

#define SDL_WINDOW_FULLSCREEN           SDL_UINT64_C(0x0000000000000001)
#define SDL_WINDOW_OPENGL               SDL_UINT64_C(0x0000000000000002)
#define SDL_WINDOW_OCCLUDED             SDL_UINT64_C(0x0000000000000004)
#define SDL_WINDOW_HIDDEN               SDL_UINT64_C(0x0000000000000008)
#define SDL_WINDOW_BORDERLESS           SDL_UINT64_C(0x0000000000000010)
#define SDL_WINDOW_RESIZABLE            SDL_UINT64_C(0x0000000000000020)
#define SDL_WINDOW_MINIMIZED            SDL_UINT64_C(0x0000000000000040)
#define SDL_WINDOW_MAXIMIZED            SDL_UINT64_C(0x0000000000000080)
#define SDL_WINDOW_MOUSE_GRABBED        SDL_UINT64_C(0x0000000000000100)
#define SDL_WINDOW_INPUT_FOCUS          SDL_UINT64_C(0x0000000000000200)
#define SDL_WINDOW_MOUSE_FOCUS          SDL_UINT64_C(0x0000000000000400)
#define SDL_WINDOW_EXTERNAL             SDL_UINT64_C(0x0000000000000800)
#define SDL_WINDOW_MODAL                SDL_UINT64_C(0x0000000000001000)
#define SDL_WINDOW_HIGH_PIXEL_DENSITY   SDL_UINT64_C(0x0000000000002000)
#define SDL_WINDOW_MOUSE_CAPTURE        SDL_UINT64_C(0x0000000000004000)
#define SDL_WINDOW_MOUSE_RELATIVE_MODE  SDL_UINT64_C(0x0000000000008000)
#define SDL_WINDOW_ALWAYS_ON_TOP        SDL_UINT64_C(0x0000000000010000)
#define SDL_WINDOW_UTILITY              SDL_UINT64_C(0x0000000000020000)
#define SDL_WINDOW_TOOLTIP              SDL_UINT64_C(0x0000000000040000)
#define SDL_WINDOW_POPUP_MENU           SDL_UINT64_C(0x0000000000080000)
#define SDL_WINDOW_KEYBOARD_GRABBED     SDL_UINT64_C(0x0000000000100000)
#define SDL_WINDOW_VULKAN               SDL_UINT64_C(0x0000000010000000)
#define SDL_WINDOW_METAL                SDL_UINT64_C(0x0000000020000000)
#define SDL_WINDOW_TRANSPARENT          SDL_UINT64_C(0x0000000040000000)
#define SDL_WINDOW_NOT_FOCUSABLE        SDL_UINT64_C(0x0000000080000000)

/**
 * A magic value used with SDL_WINDOWPOS_UNDEFINED.
 *
 * Generally this macro isn't used directly, but rather through
 * SDL_WINDOWPOS_UNDEFINED or SDL_WINDOWPOS_UNDEFINED_DISPLAY.
 *
 * \since This macro is available since SDL 3.2.0.
 */
#define SDL_WINDOWPOS_UNDEFINED_MASK    0x1FFF0000u

Corresponding section in the .swiftinterface file

/**
 * The flags on a window.
 *
 * These cover a lot of true/false, or on/off, window state. Some of it is
 * immutable after being set through SDL_CreateWindow(), some of it can be
 * changed on existing windows by the app, and some of it might be altered by
 * the user or system outside of the app's control.
 *
 * \since This datatype is available since SDL 3.2.0.
 *
 * \sa SDL_GetWindowFlags
 */
public typealias SDL_WindowFlags = Uint64

public var SDL_WINDOWPOS_UNDEFINED_MASK: UInt32 { get }

As you can see it is missing all of the SDL_WINDOW_* definitions as well as the comment for SDL_WINDOWPOS_UNDEFINED_MASK which as far as I can tell should also have been copied over. There are other missing definitions too, but these ones are pretty critical to map correctly.

Anyone have any idea what's going on?

Doing some extra digging, I have found that the missing definitions are any Macro or definition that uses a macro e.g. #define SDL_WINDOW_FULLSCREEN SDL_UINT64_C(0x0000000000000001) uses the SDL_UINT64_C macro and is skipped. Only the #defines that explicitly define a concrete value are included.

Is this an intended limitation of the C wrapping system?

Yes, the clang importer only accepts a subset of C syntax in macro definitions when creating Swift symbols. The way I most often see code work around this is by declaring a C function that returns the value of the macro, then calling that from Swift.

1 Like

Yes, this is a known limitation of ClangImporter. Here are related tickets:

1 Like

Damn, that's a shame. I could understand the more complex macros that use things like stringify not being imported because the context isn't clear. But most of the missing macros in SDL3 that I have come across have all been #define NAME (some constant express) when you expand them.

Hopefully this is something that gets improved upon so I don't have to maintain additional C code that might end up out of date with the core SDL3 library.