-
-
Notifications
You must be signed in to change notification settings - Fork 461
[3.0] Add generator docs #2578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
Exanite
wants to merge
95
commits into
develop/3.0
Choose a base branch
from
feature/generator-docs
base: develop/3.0
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
[3.0] Add generator docs #2578
Changes from all commits
Commits
Show all changes
95 commits
Select commit
Hold shift + click to select a range
2af78a6
Add WIP documentation for using the Silk 3 generator
Exanite ceb883a
Merge branch 'feature/generator-usage-docs' into feature/generator-docs
Exanite 669c235
Add for-contributors/Generator folder
Exanite 5fd22ad
Work on an outline for two new generator docs pages
Exanite 696f110
Work on high-level overview section
Exanite d7cc707
Edit the overview section and begin writing about PrettifyNames
Exanite f3a941f
Work on PrettifyNames section
Exanite a95d882
Omit the name processor parameters since they don't provide much addi…
Exanite 4b12126
Edit wording
Exanite de11ee5
Work on Name Splitting and Name Prettification sections
Exanite 5a13c26
Revise the name processing docs
Exanite 236eb5a
More editing
Exanite c08b634
Write the Acronym Indeterminate Inputs section
Exanite 46a844e
Finish writing the Name Prettification section
Exanite 5d18b9e
Work on name affixes section
Exanite 883faf2
Add PrettifyNames - Notable Decisions section
Exanite f86dbe4
Write the Referenced Affixes section
Exanite 28f2d93
Add Name Affixes - Metadata Format section
Exanite 6c5d46d
Add Referenced Affixes - Metadata Format section
Exanite d3c4cf2
Remove completed todo
Exanite 5c98078
Add test cases to cover ID3D12Device shared prefix identification beh…
Exanite 4cbab9f
Write the Symbol-based Renamer section
Exanite f028db8
Edit name processing docs
Exanite e38248d
Reflow the text
Exanite 2a1c66a
Add note on where the referenced affix example comes from
Exanite cc1688f
Add example where only one of the two consecutive acronyms is preserved
Exanite f40196a
Begin working on generator mods docs
Exanite 1586f89
Write the Mod Configuration section
Exanite 52ee73c
Add empty sections for each mod
Exanite ad2cb1f
Clarify what information will go in the Available Mods section
Exanite 5462a83
List out the name affix categories and work on outlining the rest of …
Exanite 5f11df5
Add information about usage recommendations section
Exanite 0edb2bd
Work on docs and write the AddApiProfiles section
Exanite 2798760
Work on docs and attempt to write AddVTables usage recommendation
Exanite adae6d9
Remove the WIP usage recommendations for AddVTables since I don't kno…
Exanite e6021c7
Work on mods docs
Exanite 1a10b65
Add light docs for ClangScraper mod
Exanite 0c506f0
Add docs for ExtractHandles and add ExtractHandlesTests matching the …
Exanite b856a50
Document that the example has a matching test case
Exanite f24fe8e
Change ModUtils.RelativePath() to work when no project path is available
Exanite 3295b3e
Add TestUtils.VerifyDocumentsAsync
Exanite 3c07a6b
Use Single instead of First since we expect one matching doc
Exanite 8484427
Work on ExtractNestedTyping docs and add SuccessfullyExtractsNestedIn…
Exanite df72367
Work on docs and add SuccessfullyExtractsFunctionPointer test case
Exanite 10884e9
Add SuccessfullyExtractsCStyleEnumConstants test case
Exanite 0ee21a0
Add passing SuccessfullyExtractsCStyleEnumConstants_Pointer and faili…
Exanite f34b4ee
Add SuccessfullyExtractsCStyleEnumConstants_Field test case
Exanite 44fbd40
Rename snapshot to match renamed test
Exanite ce5187e
Write the IdentifySharedPrefixes section
Exanite 67498fe
Add note about IdentifySharedPrefixes's history
Exanite 3befc1c
Fix incorrect test document name
Exanite dccfa75
Add more information to the IdentifySharedPrefixes section
Exanite 5c07807
Fix and edit wording
Exanite 13594fc
Add InterceptNativeFunctionsTests
Exanite 27f6d5b
Write the InterceptNativeFunctions section
Exanite de9704b
Work on docs for MarkNativeNames
Exanite 52508ef
Work on MixKhronosData docs
Exanite b7ec820
Work on documenting the name affixes used by MixKhronosData
Exanite 40727fc
Write docs for KhronosNonExclusiveVendor
Exanite 7707f64
Finish writing the name affix docs for MixKhronosData
Exanite aaa4605
Finish up the MixKhronosData section
Exanite 5e8d600
Write the PrettifyNames section
Exanite 7c4ddee
Write the StripAttributes section
Exanite b5e012b
Write the TransformEnums section and add note about ClangScraper plat…
Exanite 5cf5076
Edit wording
Exanite cfce994
Attempt to write some docs for TransformFunctions
Exanite 8e65ee6
Work on TransformHandles docs
Exanite 2d6b899
Write docs for TransformProperties and finish the first pass of the g…
Exanite dc3e855
Adjust wording
Exanite 01331cf
Merge branch 'develop/3.0' into feature/generator-docs
Exanite f934db0
Add OpenAL and Vulkan to changelog
Exanite 4118069
Remove todos relating to PR #2574
Exanite a607fc0
Document ClangScraper platform-specific differences and edit generato…
Exanite 0b747d0
Add Library-Specific Notes doc
Exanite ef389ed
Add link for more information
Exanite 2609ccc
Add link from ClangScraper section to Library-Specific Notes doc
Exanite c6c952b
Fix incorrect title for Static vs Instance Bindings doc
Exanite 8354bf9
Add link from AddVTables section to Static vs Instance Bindings doc
Exanite 923ab0d
Prefer referring to native APIs using the term "API" rather than "lib…
Exanite c74bf1a
Add links to Using the Generator and remap-stdint.rsp to generator-mo…
Exanite e126b97
Work on Using the Generator docs
Exanite 4298a39
Continue editing the Using the Generator docs
Exanite 7416996
Don't surround ClangSharpPInvokeGenerator in backticks
Exanite 259e214
Cleanup section on general eng/silktouch folder structure
Exanite 30974ba
Finish editing the Using the Generator docs
Exanite a407c96
Cleanup
Exanite 79dbfde
Update test cases to use TestUtils.VerifyDocumentsAsync
Exanite 06db7c8
Cleanup
Exanite f5d26a1
Edit the intro to the Using the Generator docs
Exanite cb14c95
Edit docs and avoid using inline code snippets in headers
Exanite 21f1289
Add <see> reference to ClangScraper
Exanite bb7448d
Change ExtractHandlesTests to not filter the verified documents list
Exanite b9198f4
Add some spacing to the KhronosNonExclusiveVendor section
Exanite f7fe127
Edit Generator Mods docs
Exanite 4a80c25
Edit MarkNativeNames to clarify who is responsible for adding NativeN…
Exanite File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # API-Specific Notes | ||
|
|
||
| This document's purpose is to note down any decisions or quirks that are specific to a library that Silk is generating | ||
| bindings for. | ||
|
|
||
| This is meant to be a living document. Please update this as new work is being done on the generator. | ||
|
|
||
| ## OpenAL | ||
|
|
||
| Currently empty. | ||
|
|
||
| ## OpenGL | ||
|
|
||
| Currently empty. | ||
|
|
||
| ## SDL | ||
|
|
||
| Currently empty. | ||
|
|
||
| ## Vulkan | ||
|
|
||
| There will be the following errors in the generation log. This is expected. These types are part of the XML | ||
| specification, but not part of the main `vulkan.h` header. | ||
|
|
||
| For more information: https://github.com/dotnet/Silk.NET/pull/2457#issuecomment-2910293716 | ||
|
|
||
| ``` | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkFullScreenExclusiveEXT" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkFaultLevel" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkFaultType" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkFaultQueryBehavior" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkPipelineMatchControl" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkSciSyncClientTypeNV" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkSciSyncPrimitiveTypeNV" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkPipelineCacheValidationVersion" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkDisplacementMicromapFormatNV" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| fail: Silk.NET.SilkTouch.Mods.MixKhronosData[0] Enum "VkCompressedTriangleFormatAMDX" has no base type. Please add TypeMap entry to the configuration. This enum group will be skipped. | ||
| ``` |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,231 @@ | ||
| # Using the Generator | ||
|
|
||
| **Warning: The generator is still in heavy development and will likely be subject to frequent breaking changes.** | ||
| This will likely be the case until we are a few previews in. | ||
|
|
||
| SilkTouch is Silk 3's bindings generator, which works by taking the output of ClangSharpPInvokeGenerator, which itself | ||
| is its own bindings generator, and modifying the output with a set of mods. These mods apply transformations such as | ||
| renaming identifiers, creating types such as handle structs or enums, and adding method overloads. | ||
|
|
||
| In other words, ClangSharpPInvokeGenerator acts as the input to the SilkTouch generator and SilkTouch works to improve | ||
| on that input. Other inputs to the SilkTouch generator will likely be available in the future to cover APIs such as | ||
| Metal. | ||
|
|
||
| **Also note that only C bindings are supported right now. COM will be available later.** | ||
|
|
||
| ## Generator Overview | ||
|
|
||
| There are two main things to configure: | ||
|
|
||
| 1. Silk 3 - This is the [`generator.json`](https://github.com/dotnet/Silk.NET/blob/develop/3.0/generator.json) file. | ||
|
|
||
| 2. ClangSharpPInvokeGenerator - This is the [`eng/silktouch`](https://github.com/dotnet/Silk.NET/tree/develop/3.0/eng/silktouch) folder. | ||
|
|
||
| Both are organized by native API. | ||
|
|
||
| Note: For the average C API, SDL's generator configuration would be the best configuration to reference. Most options | ||
| used for the SDL bindings should be applicable after replacing the SDL-specific paths and values to suit the C API that | ||
| you are binding. | ||
|
|
||
| ## SilkTouch Configuration | ||
|
|
||
| Silk defines the configuration for SilkTouch in the | ||
| [`generator.json`](https://github.com/dotnet/Silk.NET/blob/develop/3.0/generator.json) file. This file defines the | ||
| different bindings jobs and the list of mods to run for each job. | ||
|
|
||
| For example, when binding to a C API: | ||
|
|
||
| - `AddIncludes` tells `ClangScraper` where to find the system header files. You likely want to include this. | ||
|
|
||
| - `ClangScraper` runs ClangSharpPInvokeGenerator. Including this mod on its own is equivalent to running | ||
| ClangSharpPInvokeGenerator directly. | ||
|
|
||
| - The rest of the mods apply different transformations to the output of `ClangScraper`. Documentation for the other mods | ||
| can be found in the [Generator Mods](generator-mods.md) documentation. | ||
|
|
||
| Aside from reading documentation, some other ways to learn about the mods are to: | ||
|
|
||
| - Read through the tests. The tests act as examples for specific behaviors expected by each mod, with configurations, | ||
| inputs, and expected outputs provided for each case. | ||
|
|
||
| - Add them one by one. Mods run in the order you define them and work off the output of the previous mod. | ||
|
|
||
| (TODO: Not sure how to set up bindings test projects. This refers to the `TestProject` property in `generator.json`.) | ||
|
|
||
| ## ClangSharpPInvokeGenerator Configuration | ||
|
|
||
| Due to SilkTouch using ClangSharpPInvokeGenerator as an input, ClangSharpPInvokeGenerator must also be configured. | ||
| Silk stores its configuration for ClangSharpPInvokeGenerator in the | ||
| [`eng/silktouch`](https://github.com/dotnet/Silk.NET/tree/develop/3.0/eng/silktouch) folder as `.rsp` files (response | ||
| files). These response files store command line arguments to be passed into ClangSharpPInvokeGenerator. | ||
|
|
||
| Note that these files can be stored anywhere since the SilkTouch configuration lets you configure where the SilkTouch | ||
| generator looks for these response files. | ||
|
|
||
| > To read more about ClangSharpPInvokeGenerator's command line arguments, a good option is to install the tool directly | ||
| > and use `--help` to display its command line documentation. | ||
| > | ||
| > ```sh | ||
| > dotnet tool install --global ClangSharpPInvokeGenerator | ||
| > ClangSharpPInvokeGenerator --help | ||
| > ClangSharpPInvokeGenerator --config help | ||
| > ``` | ||
|
|
||
| Aside from simply storing the command line arguments to be passed into ClangSharpPInvokeGenerator, response files can | ||
| also import other response files using the `@path` syntax. For example: `@../settings.rsp`. | ||
|
|
||
| Silk commonly uses these import paths to share settings between different sets of bindings, such as the | ||
| [common.rsp](https://github.com/dotnet/Silk.NET/blob/develop/3.0/eng/silktouch/common.rsp) file for general shared | ||
| settings and the [remap-stdint.rsp](https://github.com/dotnet/Silk.NET/blob/develop/3.0/eng/silktouch/remap-stdint.rsp) | ||
| file used to ensure that the `stdint.h` types behave consistently between Windows and Linux. | ||
|
|
||
| Please note that these paths are relative to the response file specified in the generator and **not** relative to the | ||
| response file the `@path` directive is actually defined in. | ||
|
|
||
| For example, Silk's SDL bindings sets `ClangSharpResponseFiles` to be `eng/silktouch/sdl/**/generate.rsp`. Therefore, | ||
| any import paths used in the response files, including transitively imported response files, must be relative to | ||
| the matched `generate.rsp` file. | ||
|
|
||
| ### Example Response File Folder Structure | ||
|
|
||
| This is the general structure of the `eng/silktouch` folder: | ||
|
|
||
| ``` | ||
| eng | ||
| - silktouch | ||
| - opengl <-- This level contains folders per native API. | ||
| - glcompat <-- This level contains folders for each "profile", which represent variants of the API. | ||
| - glcore | ||
| - gles1 | ||
| - gles2 | ||
| - sdl | ||
| - SDL3 | ||
| ``` | ||
|
|
||
| Profiles likely will not be relevent for most C APIs, so the examples here will keep focusing on the SDL case. | ||
|
|
||
| The following is the folder structure used for Silk's SDL bindings. You do not have to structure it the way Silk does. | ||
| Silk's structure focuses on keeping consistency in its response file organization, regardless of whether the API makes | ||
| use of profiles or not. | ||
|
|
||
| ``` | ||
| eng | ||
| - silktouch | ||
| - sdl | ||
| - SDL3 | ||
| - generate.rsp <-- The main settings file. Used as the entrypoint. All import paths must be relative to this file. | ||
| - header.txt | ||
| - sdl-SDL.h <-- Handwritten header file that #includes the relevant headers of the library you want to bind. | ||
| - remap.rsp | ||
| - settings.rsp <-- Shared settings for all profiles. | ||
| ``` | ||
|
|
||
| ### Example ClangSharpPInvokeGenerator Configuration | ||
|
|
||
| This section will now focus on how to actually create the response files, starting with the `sdl-SDL.h`, `generate.rsp`, | ||
| and `settings.rsp` files. The snippets below will only contain the most important sections of those files for brevity. | ||
|
|
||
| `sdl-SDL.h`: | ||
| ```h | ||
| #include <SDL3/SDL.h> | ||
| #include <SDL3/SDL_main.h> | ||
| #include <SDL3/SDL_vulkan.h> | ||
| ``` | ||
|
|
||
| `generate.rsp`: | ||
| ```rsp | ||
| @../settings.rsp | ||
| @../remap.rsp | ||
| --exclude | ||
| SDL_SetX11EventHook | ||
| SDL_SetWindowsMessageHook | ||
| SDL_FILE | ||
| SDL_LINE | ||
| --file | ||
| sdl-SDL.h | ||
| --methodClassName | ||
| Sdl | ||
| --namespace | ||
| Silk.NET.SDL | ||
| --output | ||
| ../../../../sources/SDL/SDL3 | ||
| --traverse | ||
| ../../../submodules/sdl/include/SDL3/SDL_assert.h | ||
| ../../../submodules/sdl/include/SDL3/SDL_atomic.h | ||
| ../../../submodules/sdl/include/SDL3/SDL_audio.h | ||
| ``` | ||
|
|
||
| `settings.rsp`: | ||
| ```rsp | ||
| @../../common.rsp | ||
| --define-macro | ||
| TODO_DEFINE_MACROS=HERE | ||
| --headerFile | ||
| header.txt | ||
| --include-directory | ||
| ../../../submodules/sdl/include | ||
| --with-callconv | ||
| *=Winapi | ||
| --with-librarypath | ||
| *=SDL3 | ||
| ``` | ||
|
|
||
| #### Relevant Options from `generate.rsp`: | ||
|
|
||
| - `--file` specifies the header file to use as the entrypoint. This should be the custom header you defined. | ||
|
|
||
| - `--traverse` specifies which header files contribute towards the output. | ||
|
|
||
| This separation is because while header files, such as system headers, may be required to compile the library, we do not | ||
| want to include those headers as part of the final set of generated bindings. | ||
|
|
||
| - `--output` should point to the same `Jobs.JOB_NAME.SourceProject` path you defined in `generator.json`. | ||
|
|
||
| - `--methodClassName` specifies which C# class contains the generated methods/constants. | ||
|
|
||
| - `--namespace` specifies the C# namespace of the generated files. | ||
|
|
||
| - `--exclude` allows you exclude types/functions/constants from the output. These usually are APIs that are not useful, | ||
| do not generate correctly, or are platform-specific. | ||
|
|
||
| #### Relevant options from `settings.rsp`: | ||
|
|
||
| - `--headerFile` specifies the header file appended to the top of every generated file. Silk uses this to inject its | ||
| copyright headers. | ||
|
|
||
| - `--include-directory` specifies the include directories to be used. This affects all headers included, such as | ||
| `sdl-SDL.h`. | ||
|
|
||
| - `--with-librarypath` is the name of the native library without prefixes/suffixes. If the library name differs outside | ||
| of the usual `lib` prefix or `.dll`/`.so`/`.dylib` suffixes, the way to handle this is to add `UseAlternativeName` in | ||
| the generated bindings. An example with Vulkan can be found in | ||
| [`sources/Vulkan/Vulkan/Vk.cs`](https://github.com/dotnet/Silk.NET/blob/develop/3.0/sources/Vulkan/Vulkan/Vk.cs), | ||
| which is a manually written file. | ||
|
|
||
| ```cs | ||
| static Vk() | ||
| { | ||
| LoaderInterface.RegisterHook(Assembly.GetExecutingAssembly()); | ||
| LoaderInterface.RegisterAlternativeName("vulkan", "vulkan-1"); | ||
| LoaderInterface.RegisterAlternativeName("vulkan", "MoltenVK"); | ||
| } | ||
| ``` | ||
|
|
||
| ### Generated Bindings Output | ||
|
|
||
| All generated binding will be output to the `Jobs.JOB_NAME.SourceProject` path defined in `generator.json`. | ||
|
|
||
| These generated files all have the `.gen.cs` suffix and most of them are partial type declarations. | ||
| This means by creating a similarly named `.cs` file and using the `partial` C# keyword, you can add to the type. | ||
|
|
||
| Do not modify the `.gen.cs` files since running the generator again will overwrite those changes. | ||
|
|
||
| ### Packing the Generated Bindings | ||
|
|
||
| (TODO: This section needs verification.) | ||
|
|
||
| `dotnet pack` should simply work here. | ||
|
|
||
| If you are contributing to Silk's repository, Silk automatically packs and pushes changes made during a pull request | ||
| to its experimental NuGet feed. More information on how to access this feed is available in the | ||
| [Experimental Feed](../../silk.net/experimental-feed.md) documentation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| # Static vs Input Bindings | ||
| # Static vs Instance Bindings | ||
|
|
||
| ## Overview | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this since these aren't actually Pfn-prefixed and simply use the native name of the function pointer type.