Skip to content

Proposal: Replace autoTypes.json DECLARE_HANDLE entries with header annotations#2256

Draft
jevansaks wants to merge 2 commits intomainfrom
user/jevansa/handle-annotations
Draft

Proposal: Replace autoTypes.json DECLARE_HANDLE entries with header annotations#2256
jevansaks wants to merge 2 commits intomainfrom
user/jevansa/handle-annotations

Conversation

@jevansaks
Copy link
Copy Markdown
Member

Summary

Adds a validated proposal to shift the ~166 DECLARE_HANDLE entries from autoTypes.json into header annotations, mirroring the conditional-declaration pattern from the enum remapping proposal (#2247).

The approach defines DECLARE_HANDLE_WIN32METADATA(name, ...) plus _Close_handle_with_ / _Invalid_handle_ / _Also_usable_for_ macros. Under -D_WIN32METADATA_=1, DECLARE_HANDLE expands to a wrapper struct that ClangSharp v18 emits directly with [NativeAnnotation] attributes; MetadataSyntaxTreeCleaner translates them into the existing [RAIIFree], [InvalidHandleValue], [AlsoUsableFor], and [NativeTypedef]. The winmd output is byte-identical to today.

Validated end-to-end with ClangSharp v18.1.0.4 (test files in obj/handle-annotation-test/).

What's in the proposal

  • Core mechanism — annotated DECLARE_HANDLE redefinition + SAL-style annotation macros
  • Empirical evidence — 11 patterns tested through ClangSharp v18; only the struct [[attr]] NAME { ... } shape preserves annotations on the right declaration. C++11 attributes cannot precede struct at namespace scope, which is why we need a macro that takes attributes via __VA_ARGS__.
  • Projection behavior — confirmed by reading CsWin32 and windows-rs source: both projections read the attributes by name, generate conversion code (implicit operators / From + CanInto) for [NativeTypedef] structs, and require no projection-side changes.
  • Scope — explicitly DECLARE_HANDLE-only; sibling DECLARE_TYPEDEF_WIN32METADATA(name, type, ...) macro sketched for the remaining ~83 typedef-style handles and value wrappers (BCRYPT, EVT, MSI, BOOL, HRESULT, NTSTATUS, BSTR, etc.) as a follow-up.
  • One drop — recommend deleting DEVPROPKEY=[AlsoUsableFor("PROPERTYKEY")] from emitter.settings.rsp; both CsWin32 and windows-rs only generate AlsoUsableFor code for [NativeTypedef]-shaped structs, so this entry is dormant.

Open questions called out in the proposal

  1. [InvalidHandleValueAttribute] constructor takes long — annotation strings need the right parsing
  2. Where to host the same-namespace validation that NativeTypedefStructsCreator does today
  3. Empty-namespace handle entries (~38) — namespace currently derived from CloseApi's namespace; with shift-left it comes from header partition placement
  4. Overlay headers vs. in-place SDK header patches for prototyping (matches the approach used in Proposal: Replace enums.json with conditional C++ enum declarations #2247)

Companion changes

Also updates annotation-validation-results.md with a summary table of the remaining shift-left categories after the enum proposal landed, so future readers can see where this fits in the larger workstream.

jevansaks and others added 2 commits May 5, 2026 11:40
…nnotations

Adds docs/copilot/plans/handle-annotation-proposal.md: a validated
proposal to shift ~166 DECLARE_HANDLE entries from autoTypes.json into
header annotations using the same conditional pattern as the enum
proposal (PR #2247).

The approach defines DECLARE_HANDLE_WIN32METADATA(name, ...) and
sibling _Close_handle_with_/_Invalid_handle_/_Also_usable_for_ macros.
Under -D_WIN32METADATA_=1, DECLARE_HANDLE expands to a wrapper struct
ClangSharp v18 emits directly with [NativeAnnotation] attributes the
emitter translates into the existing [RAIIFree], [InvalidHandleValue],
[AlsoUsableFor], and [NativeTypedef]. Validated end-to-end with
ClangSharp v18.1.0.4; test files in obj/handle-annotation-test/.

Includes:
- Projection-behavior section confirming both CsWin32 and windows-rs
  read these attributes and require no projection-side changes
- Out-of-scope section sketching DECLARE_TYPEDEF_WIN32METADATA for the
  ~80 remaining typedef-style handles and value wrappers (BCRYPT,
  EVT, MSI, BOOL, HRESULT, NTSTATUS, BSTR, etc.) with concrete
  per-header examples
- Recommendation to drop the dormant DEVPROPKEY=[AlsoUsableFor(...)]
  entry from emitter.settings.rsp

Also updates annotation-validation-results.md with a summary of the
remaining shift-left categories after the enum proposal landed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- handle-annotation-proposal.md: expand to cover ALL ~280 entries in
  autoTypes.json (5 categories), not just DECLARE_HANDLE-style. Both
  macros (DECLARE_HANDLE_WIN32METADATA and DECLARE_TYPEDEF_WIN32METADATA)
  are now first-class. Migration removes autoTypes.json,
  NativeTypedefStructsCreator.cs, AutoType.cs, and PrepSettingsForAutoTypes.cs.
- Resolve all open questions inline:
  - Phasing: land as one proposal (avoids dual-pipeline transition state)
  - Overlay headers in Phase 1, SDK patches in Phase 2 (matches enum proposal)
  - Keep both macros distinct: their #else branches preserve different SDK forms
- Caveat 2 (HRESULT/NTSTATUS SAL): resolved — pipeline already drops typedef
  SAL; success contracts come from emitter.settings.rsp per-function entries.
- spec.md: update typedef-style handles section to describe full removal,
  not follow-up.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

1 participant