Skip to content

Conversation

@mematthias
Copy link
Contributor

Proposal: Explicit return types for funcpointers

Currently, it is not possible to fully analyze function pointer signatures in the Vulkan XML in a purely static way.
While the function arguments and the function name are accessible, the return type is not.
This makes it difficult to parse function pointers reliably in generators and analysis tools.
Additionally, the missing return type makes it very hard to construct a proper topological order of type dependencies, since the dependency chain cannot be resolved statically.

Suggested change

The requires attribute of the <type> element could be used to store the return type explicitly.
At the moment, the requires attribute is only used for redundant information that can already be derived from the function arguments.
Using it consistently for return types instead would remove this redundancy and make the return type available in a static, machine-readable way.

For example:

<type category="funcpointer" requires="VkBool32">typedef VkBool32 (VKAPI_PTR *<name>PFN_vkDebugUtilsMessengerCallbackEXT</name>)(
    <type>VkDebugUtilsMessageSeverityFlagBitsEXT</type>           messageSeverity,
    <type>VkDebugUtilsMessageTypeFlagsEXT</type>                  messageTypes,
    const <type>VkDebugUtilsMessengerCallbackDataEXT</type>*      pCallbackData,
    <type>void</type>*                                            pUserData);
</type>

With this change, the return type, arguments, and function name can all be determined statically and unambiguously.
It would also make it possible to construct a correct topological ordering of all types.

Alternative option

If using requires for return types is considered semantically unclear, a dedicated returns attribute could be introduced to make the intent explicit (at the cost of a schema extension).

Summary

  • Problem: Return types of funcpointers cannot currently be determined statically
  • Proposal: Use requires to specify the return type explicitly
  • Alternative: Introduce a new returns attribute for stronger semantic clarity

@oddhack oddhack self-assigned this Sep 10, 2025
@mematthias
Copy link
Contributor Author

@oddhack Since this draft was assigned but no comments have been made yet, is there anything I should adjust or add?

@oddhack
Copy link
Contributor

oddhack commented Oct 8, 2025

I do not want to use the requires tag for this as it's a semantically different use (and collides with one existing use).

One option is to just add a <type> tag to the base return type which is what the <command> tag already does. We'd have to check if that affects any downstream consumers of the XML but that seems preferable to me and avoids redundancy, which is always a concern for us. Adding a new attribute as you suggest is also workable.

Sorry for delay responding.

@mematthias
Copy link
Contributor Author

mematthias commented Oct 9, 2025

That sounds good to me - using a <type> tag for the base return type seems reasonable and consistent with how <command> already works.

That said, introducing a dedicated return (or returns) attribute shouldn’t cause any compatibility issues either, and it would make the intent a bit clearer from a semantic perspective. I’d be fine with either approach, though I’d slightly lean toward the explicit attribute for clarity.

As an additional suggestion, we could represent function pointers in a structure similar to how commands are currently defined.
This would make the return type explicit without relying on attributes and would also align better with existing XML parsing logic:

<type category="funcpointer">
  <proto><type>VkBool32</type>                                                     <name>PFN_vkDebugUtilsMessengerCallbackEXT</name></proto>
  <param><type>VkDebugUtilsMessageSeverityFlagBitsEXT</type>                       <name>messageSeverity</name></param>
  <param><type>VkDebugUtilsMessageTypeFlagsEXT</type>                              <name>messageTypes</name></param>
  <param depends="true">const <type>VkDebugUtilsMessengerCallbackDataEXT</type>*   <name>pCallbackData</name></param>
  <param><type>void</type>*                                                        <name>pUserData</name></param>
</type>

One small question regarding the current use of the requires attribute - is it primarily meant to ensure forward declarations, since function pointers are defined before the structures that reference them in C code?
If so, it might be clearer to introduce a dedicated attribute such as depends or forward instead:

  • depends="true" would emphasize the type dependency aspect.
  • forward="true" would make the C-specific intent (forward declaration requirement) more explicit.

Either of these would describe the purpose more clearly than reusing requires in this context.

Additionally, separating this purpose from the existing requires attribute would make depends more flexible - allowing it to describe multiple dependencies or relationships without being constrained by its current semantics.

@mematthias
Copy link
Contributor Author

After experimenting, I found the <proto> must be more descriptive. Instead of a minimal form, we should adopt the full C-like function signature inside <proto> (including parentheses and pointer indirection around the name). This keeps it human-readable, preserves pointer binding unambiguously, and remains straightforward to parse by extracting the single <type> and <name>.

<proto>const <type>void</type>* (*<name>PFN_...</name>)</proto>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants