From eeddb6a7bb23c8ee1a0d834a2d451d683f52fce3 Mon Sep 17 00:00:00 2001 From: Arthur Matsur Date: Mon, 16 Feb 2026 12:41:49 +0300 Subject: [PATCH] Allow crossarch merge for structs with attributes other than `[StructLayout]` --- scripts/ChangesSinceLastRelease.txt | 139 ++++++++++++++++++ .../CrossArchSyntaxMap.cs | 51 +++++-- 2 files changed, 178 insertions(+), 12 deletions(-) diff --git a/scripts/ChangesSinceLastRelease.txt b/scripts/ChangesSinceLastRelease.txt index 9d7a74d4a..e0acf00d5 100644 --- a/scripts/ChangesSinceLastRelease.txt +++ b/scripts/ChangesSinceLastRelease.txt @@ -88,3 +88,142 @@ Windows.Win32.System.Threading.AVRT_THREAD_ORDERING_GROUP_HANDLE added # Annotate RasEnumConnections function parameters Windows.Win32.NetworkManagement.Rras.Apis.RasEnumConnectionsA : param0 : [In,Optional,Out] => [In,MemorySize(BytesParamIndex=1),NativeArrayInfo(CountParamIndex=2),Optional,Out] Windows.Win32.NetworkManagement.Rras.Apis.RasEnumConnectionsW : param0 : [In,Optional,Out] => [In,MemorySize(BytesParamIndex=1),NativeArrayInfo(CountParamIndex=2),Optional,Out] +# Allow crossarch merge for structs with attributes other than `[StructLayout]` +Windows.Win32.NetworkManagement.Rras.RASCONNA added +Windows.Win32.NetworkManagement.Rras.RASCONNA(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASCONNA(X86) removed +Windows.Win32.NetworkManagement.Rras.RASCONNW added +Windows.Win32.NetworkManagement.Rras.RASCONNW(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASCONNW(X86) removed +Windows.Win32.NetworkManagement.Rras.RASDEVSPECIFICINFO added +Windows.Win32.NetworkManagement.Rras.RASDEVSPECIFICINFO(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASDEVSPECIFICINFO(X86) removed +Windows.Win32.NetworkManagement.Rras.RASDIALPARAMSA added +Windows.Win32.NetworkManagement.Rras.RASDIALPARAMSA(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASDIALPARAMSA(X86) removed +Windows.Win32.NetworkManagement.Rras.RASDIALPARAMSW added +Windows.Win32.NetworkManagement.Rras.RASDIALPARAMSW(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASDIALPARAMSW(X86) removed +Windows.Win32.NetworkManagement.Rras.RASENTRYDLGA added +Windows.Win32.NetworkManagement.Rras.RASENTRYDLGA(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASENTRYDLGA(X86) removed +Windows.Win32.NetworkManagement.Rras.RASENTRYDLGW added +Windows.Win32.NetworkManagement.Rras.RASENTRYDLGW(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASENTRYDLGW(X86) removed +Windows.Win32.NetworkManagement.Rras.RASIKEV2_PROJECTION_INFO added +Windows.Win32.NetworkManagement.Rras.RASIKEV2_PROJECTION_INFO(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASIKEV2_PROJECTION_INFO(X86) removed +Windows.Win32.NetworkManagement.Rras.RASPBDLGA added +Windows.Win32.NetworkManagement.Rras.RASPBDLGA(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASPBDLGA(X86) removed +Windows.Win32.NetworkManagement.Rras.RASPBDLGW added +Windows.Win32.NetworkManagement.Rras.RASPBDLGW(X64, Arm64) removed +Windows.Win32.NetworkManagement.Rras.RASPBDLGW(X86) removed +Windows.Win32.NetworkManagement.Snmp.AsnObjectIdentifier added +Windows.Win32.NetworkManagement.Snmp.AsnObjectIdentifier(X64, Arm64) removed +Windows.Win32.NetworkManagement.Snmp.AsnObjectIdentifier(X86) removed +Windows.Win32.NetworkManagement.Snmp.AsnOctetString added +Windows.Win32.NetworkManagement.Snmp.AsnOctetString(X64, Arm64) removed +Windows.Win32.NetworkManagement.Snmp.AsnOctetString(X86) removed +Windows.Win32.NetworkManagement.Snmp.SnmpVarBindList added +Windows.Win32.NetworkManagement.Snmp.SnmpVarBindList(X64, Arm64) removed +Windows.Win32.NetworkManagement.Snmp.SnmpVarBindList(X86) removed +Windows.Win32.Storage.Packaging.Appx.PACKAGE_ID added +Windows.Win32.Storage.Packaging.Appx.PACKAGE_ID(X64, Arm64) removed +Windows.Win32.Storage.Packaging.Appx.PACKAGE_ID(X86) removed +Windows.Win32.Storage.Packaging.Appx.PACKAGE_INFO added +Windows.Win32.Storage.Packaging.Appx.PACKAGE_INFO(X64, Arm64) removed +Windows.Win32.Storage.Packaging.Appx.PACKAGE_INFO(X86) removed +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_CALLBACK_INFORMATION added +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_CALLBACK_INFORMATION(X64, Arm64) removed +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_CALLBACK_INFORMATION(X86) removed +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_EXCEPTION_INFORMATION added +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_EXCEPTION_INFORMATION(X64, Arm64) removed +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_EXCEPTION_INFORMATION(X86) removed +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_USER_STREAM added +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_USER_STREAM_INFORMATION added +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_USER_STREAM_INFORMATION(X64, Arm64) removed +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_USER_STREAM_INFORMATION(X86) removed +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_USER_STREAM(X64, Arm64) removed +Windows.Win32.System.Diagnostics.Debug.MINIDUMP_USER_STREAM(X86) removed +Windows.Win32.UI.Controls.RichEdit.CLIPBOARDFORMAT added +Windows.Win32.UI.Controls.RichEdit.CLIPBOARDFORMAT(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.CLIPBOARDFORMAT(X86) removed +Windows.Win32.UI.Controls.RichEdit.EDITSTREAM added +Windows.Win32.UI.Controls.RichEdit.EDITSTREAM(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.EDITSTREAM(X86) removed +Windows.Win32.UI.Controls.RichEdit.ENCORRECTTEXT added +Windows.Win32.UI.Controls.RichEdit.ENCORRECTTEXT(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.ENCORRECTTEXT(X86) removed +Windows.Win32.UI.Controls.RichEdit.ENDCOMPOSITIONNOTIFY added +Windows.Win32.UI.Controls.RichEdit.ENDCOMPOSITIONNOTIFY(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.ENDCOMPOSITIONNOTIFY(X86) removed +Windows.Win32.UI.Controls.RichEdit.ENDROPFILES added +Windows.Win32.UI.Controls.RichEdit.ENDROPFILES(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.ENDROPFILES(X86) removed +Windows.Win32.UI.Controls.RichEdit.ENLINK added +Windows.Win32.UI.Controls.RichEdit.ENLINK(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.ENLINK(X86) removed +Windows.Win32.UI.Controls.RichEdit.ENLOWFIRTF added +Windows.Win32.UI.Controls.RichEdit.ENLOWFIRTF(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.ENLOWFIRTF(X86) removed +Windows.Win32.UI.Controls.RichEdit.ENOLEOPFAILED added +Windows.Win32.UI.Controls.RichEdit.ENOLEOPFAILED(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.ENOLEOPFAILED(X86) removed +Windows.Win32.UI.Controls.RichEdit.ENPROTECTED added +Windows.Win32.UI.Controls.RichEdit.ENPROTECTED(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.ENPROTECTED(X86) removed +Windows.Win32.UI.Controls.RichEdit.ENSAVECLIPBOARD added +Windows.Win32.UI.Controls.RichEdit.ENSAVECLIPBOARD(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.ENSAVECLIPBOARD(X86) removed +Windows.Win32.UI.Controls.RichEdit.FINDTEXTA added +Windows.Win32.UI.Controls.RichEdit.FINDTEXTA(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.FINDTEXTA(X86) removed +Windows.Win32.UI.Controls.RichEdit.FINDTEXTEXA added +Windows.Win32.UI.Controls.RichEdit.FINDTEXTEXA(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.FINDTEXTEXA(X86) removed +Windows.Win32.UI.Controls.RichEdit.FINDTEXTEXW added +Windows.Win32.UI.Controls.RichEdit.FINDTEXTEXW(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.FINDTEXTEXW(X86) removed +Windows.Win32.UI.Controls.RichEdit.FINDTEXTW added +Windows.Win32.UI.Controls.RichEdit.FINDTEXTW(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.FINDTEXTW(X86) removed +Windows.Win32.UI.Controls.RichEdit.FORMATRANGE added +Windows.Win32.UI.Controls.RichEdit.FORMATRANGE(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.FORMATRANGE(X86) removed +Windows.Win32.UI.Controls.RichEdit.GETCONTEXTMENUEX added +Windows.Win32.UI.Controls.RichEdit.GETCONTEXTMENUEX(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.GETCONTEXTMENUEX(X86) removed +Windows.Win32.UI.Controls.RichEdit.GETTEXTEX added +Windows.Win32.UI.Controls.RichEdit.GETTEXTEX(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.GETTEXTEX(X86) removed +Windows.Win32.UI.Controls.RichEdit.HYPHENATEINFO added +Windows.Win32.UI.Controls.RichEdit.HYPHENATEINFO(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.HYPHENATEINFO(X86) removed +Windows.Win32.UI.Controls.RichEdit.MSGFILTER added +Windows.Win32.UI.Controls.RichEdit.MSGFILTER(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.MSGFILTER(X86) removed +Windows.Win32.UI.Controls.RichEdit.OBJECTPOSITIONS added +Windows.Win32.UI.Controls.RichEdit.OBJECTPOSITIONS(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.OBJECTPOSITIONS(X86) removed +Windows.Win32.UI.Controls.RichEdit.PUNCTUATION added +Windows.Win32.UI.Controls.RichEdit.PUNCTUATION(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.PUNCTUATION(X86) removed +Windows.Win32.UI.Controls.RichEdit.REPASTESPECIAL added +Windows.Win32.UI.Controls.RichEdit.REPASTESPECIAL(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.REPASTESPECIAL(X86) removed +Windows.Win32.UI.Controls.RichEdit.REQRESIZE added +Windows.Win32.UI.Controls.RichEdit.REQRESIZE(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.REQRESIZE(X86) removed +Windows.Win32.UI.Controls.RichEdit.RICHEDIT_IMAGE_PARAMETERS added +Windows.Win32.UI.Controls.RichEdit.RICHEDIT_IMAGE_PARAMETERS(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.RICHEDIT_IMAGE_PARAMETERS(X86) removed +Windows.Win32.UI.Controls.RichEdit.SELCHANGE added +Windows.Win32.UI.Controls.RichEdit.SELCHANGE(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.SELCHANGE(X86) removed +Windows.Win32.UI.Controls.RichEdit.TEXTRANGEA added +Windows.Win32.UI.Controls.RichEdit.TEXTRANGEA(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.TEXTRANGEA(X86) removed +Windows.Win32.UI.Controls.RichEdit.TEXTRANGEW added +Windows.Win32.UI.Controls.RichEdit.TEXTRANGEW(X64, Arm64) removed +Windows.Win32.UI.Controls.RichEdit.TEXTRANGEW(X86) removed diff --git a/sources/ClangSharpSourceToWinmd/CrossArchSyntaxMap.cs b/sources/ClangSharpSourceToWinmd/CrossArchSyntaxMap.cs index 691a9afdd..f2a3f993a 100644 --- a/sources/ClangSharpSourceToWinmd/CrossArchSyntaxMap.cs +++ b/sources/ClangSharpSourceToWinmd/CrossArchSyntaxMap.cs @@ -1,20 +1,20 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; +using MetadataUtils; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using MetadataUtils; namespace ClangSharpSourceToWinmd { public class CrossArchSyntaxMap { + private const string StructLayoutAttributeName = "StructLayout"; + private readonly Dictionary> namesToInfos = new(); private readonly Dictionary namesTo64BitStructs = new(); - private readonly HashSet x86StructsNeed64BitAttrs = new(); + private readonly HashSet x86StructsNeed64BitLayoutAttribute = new(); private readonly object syncObj = new(); public CrossArchSyntaxMap() @@ -82,9 +82,20 @@ public StructDeclarationSyntax FixX86Struct(StructDeclarationSyntax x86Node) lock (this.syncObj) { - if (this.x86StructsNeed64BitAttrs.Contains(name)) + if (this.x86StructsNeed64BitLayoutAttribute.Contains(name)) { - return x86Node.AddAttributeLists(this.namesTo64BitStructs[name].AttributeLists.ToArray()); + foreach (var attrList in this.namesTo64BitStructs[name].AttributeLists) + { + foreach (var attr in attrList.Attributes) + { + if (attr.Name.ToString().Contains(StructLayoutAttributeName)) + { + return x86Node.AddAttributeLists( + SyntaxFactory.AttributeList( + SyntaxFactory.SingletonSeparatedList(attr))); + } + } + } } } @@ -97,7 +108,7 @@ public HashSet Get64BitTreesUsedForX86() lock (this.syncObj) { - foreach (var name in this.x86StructsNeed64BitAttrs) + foreach (var name in this.x86StructsNeed64BitLayoutAttribute) { var nonX86Struct = this.namesTo64BitStructs[name]; if (!ret.Contains(nonX86Struct.SyntaxTree.FilePath)) @@ -278,7 +289,7 @@ private static string GetFullSignature(SyntaxNode node) else { ret.Append(','); - } + } var firstVar = field.Declaration.Variables.First(); var typeName = GetTypeName(field.Declaration.Type.ToString(), field.AttributeLists); @@ -321,8 +332,8 @@ private void AddNode(Architecture arch, SyntaxNode node) if (arch == Architecture.X86) { - // If the x86 node doesn't have any attributes, try using the ones cached from the non-x86 version - if (structNode.AttributeLists.Count == 0 && this.namesTo64BitStructs.TryGetValue(name, out var nonX86Node)) + // If the x86 node doesn't have dedicated [StructLayout] attribute, try using the ones cached from the non-x86 version + if (!HasStructLayoutAttribute(structNode) && this.namesTo64BitStructs.TryGetValue(name, out var nonX86Node)) { var tempNode = structNode.WithAttributeLists(nonX86Node.AttributeLists); @@ -342,7 +353,7 @@ private void AddNode(Architecture arch, SyntaxNode node) { if (info.FullSignature == altSignatureForX86) { - this.x86StructsNeed64BitAttrs.Add(name); + this.x86StructsNeed64BitLayoutAttribute.Add(name); info.Arch |= arch; return; } @@ -356,6 +367,22 @@ private void AddNode(Architecture arch, SyntaxNode node) var newInfo = new CrossArchInfo() { Arch = arch, FullSignature = fullSignature }; crossArchInfos.Add(newInfo); + + static bool HasStructLayoutAttribute(StructDeclarationSyntax structDeclaration) + { + foreach (var attrList in structDeclaration.AttributeLists) + { + foreach (var attr in attrList.Attributes) + { + if (attr.Name.ToString().Contains(StructLayoutAttributeName)) + { + return true; + } + } + } + + return false; + } } }