Skip to content

Ensure SAL/C++ attributes on fields generate a CppAttributeList#743

Merged
tannergooding merged 3 commits into
dotnet:mainfrom
tannergooding:tannergooding-fix-sal-field-attributes
Jul 13, 2026
Merged

Ensure SAL/C++ attributes on fields generate a CppAttributeList#743
tannergooding merged 3 commits into
dotnet:mainfrom
tannergooding:tannergooding-fix-sal-field-attributes

Conversation

@tannergooding

Copy link
Copy Markdown
Member

Under generate-cpp-attributes, a C++ attribute on a parameter was surfaced as [CppAttributeList("...")], but the same attribute on a struct field was silently dropped. CppAttributes was only ever wired for ParameterDesc/BeginParameter, never for FieldDesc/BeginField, so SAL buffer annotations (e.g. _Field_size_full_, _Field_size_) surfaced as annotate attributes never reached the field's CppAttributeList.

This mirrors the existing parameter path for fields:

  • Abstractions/FieldDesc.cs — add IEnumerable<string>? CppAttributes.
  • PInvokeGenerator.VisitDecl.cs VisitFieldDecl — populate it from fieldDecl.Attrs when GenerateCppAttributes is set (identical shape to the parameter path).
  • CSharp/CSharpOutputBuilder.VisitDecl.cs BeginField — emit it via AddCppAttributes, right after the NativeTypeName block so ordering matches parameters (CppAttributeList before NativeAnnotation).

CppAttributeList is the opt-in, full-fidelity dump of the raw C++ attribute list (all kinds, ^-joined, gated on generate-cpp-attributes), distinct from the always-on NativeAnnotation that surfaces only annotate spellings. Only the former was missing on fields.

Example (field now matches the equivalent parameter):

#define _Field_size_full_(x) __attribute__((annotate("_Field_size_full_(" #x ")")))
struct MyStruct { int count; _Field_size_full_(count) int* data; };
[CppAttributeList("_Field_size_full_(count)")]
[NativeAnnotation("_Field_size_full_(count)")]
public int* data;

Adds a standalone regression test (SalFieldAttributeTest, [Platform("win")]) under generate-cpp-attributes asserting the field's CppAttributeList. No existing goldens changed (no prior test enabled generate-cpp-attributes). Full ClangSharp.PInvokeGenerator.UnitTests run: 3725 passed, 0 failed, 0 warnings.

The indirect-field accessor path (nested-anonymous accessor properties) is intentionally left out of scope.

Fixes #444

Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com

tannergooding and others added 3 commits July 13, 2026 01:27
Under generate-cpp-attributes, C++ attributes on a parameter were surfaced as a CppAttributeList but the same attribute on a struct field was dropped, since CppAttributes was only wired for ParameterDesc/BeginParameter. Mirror the parameter path for fields so SAL buffer annotations (e.g. _Field_size_full_) surfaced as annotate attributes are emitted.

Fixes dotnet#444

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@tannergooding tannergooding merged commit a5de4ec into dotnet:main Jul 13, 2026
14 checks passed
@tannergooding tannergooding deleted the tannergooding-fix-sal-field-attributes branch July 13, 2026 15:15
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.

SAL annotations on structs like field_size_full aren't generating a CppAttributeList

1 participant