Skip to content

Commit 3710e44

Browse files
committed
Add preview support for the InlineArray attribute
1 parent 646034e commit 3710e44

File tree

10 files changed

+71
-1025
lines changed

10 files changed

+71
-1025
lines changed

sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ public void WriteCustomAttribute(string attribute, Action? callback = null)
2222
{
2323
AddUsingDirective("System.Diagnostics.CodeAnalysis");
2424
}
25+
else if (attribute.StartsWith("InlineArray("))
26+
{
27+
AddUsingDirective("System.Runtime.CompilerServices");
28+
}
2529
else if (attribute.StartsWith("Guid(")|| attribute.Equals("Optional") || attribute.StartsWith("Optional, DefaultParameterValue("))
2630
{
2731
AddUsingDirective("System.Runtime.InteropServices");

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2868,6 +2868,11 @@ void VisitConstantOrIncompleteArrayFieldDecl(RecordDecl recordDecl, FieldDecl co
28682868
AddDiagnostic(DiagnosticLevel.Info, $"{escapedName} (constant array field) has a size of 0", constantOrIncompleteArray);
28692869
}
28702870

2871+
if (!_config.GeneratePreviewCode || (totalSize <= 1) || isUnsafeElementType)
2872+
{
2873+
totalSizeString = null;
2874+
}
2875+
28712876
var desc = new StructDesc {
28722877
AccessSpecifier = accessSpecifier,
28732878
EscapedName = escapedName,
@@ -2884,18 +2889,23 @@ void VisitConstantOrIncompleteArrayFieldDecl(RecordDecl recordDecl, FieldDecl co
28842889
Location = constantOrIncompleteArray.Location,
28852890
IsNested = true,
28862891
WriteCustomAttrs = static context => {
2887-
(var fieldDecl, var outputBuilder, var generator, var totalSizeString) = ((FieldDecl, IOutputBuilder, PInvokeGenerator, string))context;
2892+
(var fieldDecl, var outputBuilder, var generator, var totalSizeString) = ((FieldDecl, IOutputBuilder, PInvokeGenerator, string?))context;
28882893

28892894
generator.WithAttributes(fieldDecl);
28902895
generator.WithUsings(fieldDecl);
2896+
2897+
if (totalSizeString is not null)
2898+
{
2899+
outputBuilder.WriteCustomAttribute($"InlineArray({totalSizeString})");
2900+
}
28912901
},
28922902
CustomAttrGeneratorData = (constantOrIncompleteArray, _outputBuilder, this, totalSizeString),
28932903
};
28942904

28952905
_outputBuilder.BeginStruct(in desc);
28962906

28972907
var firstFieldName = "";
2898-
var numFieldsToEmit = totalSize;
2908+
var numFieldsToEmit = (totalSizeString is not null) ? Math.Min(totalSize, 1) : totalSize;
28992909

29002910
for (long i = 0; i < numFieldsToEmit; i++)
29012911
{
@@ -2982,7 +2992,7 @@ void VisitConstantOrIncompleteArrayFieldDecl(RecordDecl recordDecl, FieldDecl co
29822992
_outputBuilder.EndBody();
29832993
_outputBuilder.EndIndexer();
29842994
}
2985-
else
2995+
else if (totalSizeString is null)
29862996
{
29872997
_outputBuilder.BeginIndexer(AccessSpecifier.Public, isUnsafe: false, needsUnscopedRef: _config.GenerateLatestCode);
29882998
_outputBuilder.WriteIndexer($"ref {arrayTypeName}");

tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/StructDeclarationTest.cs

Lines changed: 10 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -590,9 +590,7 @@ struct MyOtherStruct
590590
}};
591591
";
592592

593-
var expectedOutputContents = $@"using System;
594-
using System.Diagnostics.CodeAnalysis;
595-
using System.Runtime.InteropServices;
593+
var expectedOutputContents = $@"using System.Runtime.CompilerServices;
596594
597595
namespace ClangSharp.Test
598596
{{
@@ -606,23 +604,10 @@ public partial struct MyOtherStruct
606604
[NativeTypeName(""MyStruct[3]"")]
607605
public _c_e__FixedBuffer c;
608606
607+
[InlineArray(3)]
609608
public partial struct _c_e__FixedBuffer
610609
{{
611610
public MyStruct e0;
612-
public MyStruct e1;
613-
public MyStruct e2;
614-
615-
[UnscopedRef]
616-
public ref MyStruct this[int index]
617-
{{
618-
get
619-
{{
620-
return ref AsSpan()[index];
621-
}}
622-
}}
623-
624-
[UnscopedRef]
625-
public Span<MyStruct> AsSpan() => MemoryMarshal.CreateSpan(ref e0, 3);
626611
}}
627612
}}
628613
}}
@@ -644,9 +629,7 @@ struct MyOtherStruct
644629
}};
645630
";
646631

647-
var expectedOutputContents = $@"using System;
648-
using System.Diagnostics.CodeAnalysis;
649-
using System.Runtime.InteropServices;
632+
var expectedOutputContents = $@"using System.Runtime.CompilerServices;
650633
651634
namespace ClangSharp.Test
652635
{{
@@ -660,55 +643,10 @@ public partial struct MyOtherStruct
660643
[NativeTypeName(""MyStruct[2][1][3][4]"")]
661644
public _c_e__FixedBuffer c;
662645
646+
[InlineArray(2 * 1 * 3 * 4)]
663647
public partial struct _c_e__FixedBuffer
664648
{{
665649
public MyStruct e0_0_0_0;
666-
public MyStruct e1_0_0_0;
667-
668-
public MyStruct e0_0_1_0;
669-
public MyStruct e1_0_1_0;
670-
671-
public MyStruct e0_0_2_0;
672-
public MyStruct e1_0_2_0;
673-
674-
public MyStruct e0_0_0_1;
675-
public MyStruct e1_0_0_1;
676-
677-
public MyStruct e0_0_1_1;
678-
public MyStruct e1_0_1_1;
679-
680-
public MyStruct e0_0_2_1;
681-
public MyStruct e1_0_2_1;
682-
683-
public MyStruct e0_0_0_2;
684-
public MyStruct e1_0_0_2;
685-
686-
public MyStruct e0_0_1_2;
687-
public MyStruct e1_0_1_2;
688-
689-
public MyStruct e0_0_2_2;
690-
public MyStruct e1_0_2_2;
691-
692-
public MyStruct e0_0_0_3;
693-
public MyStruct e1_0_0_3;
694-
695-
public MyStruct e0_0_1_3;
696-
public MyStruct e1_0_1_3;
697-
698-
public MyStruct e0_0_2_3;
699-
public MyStruct e1_0_2_3;
700-
701-
[UnscopedRef]
702-
public ref MyStruct this[int index]
703-
{{
704-
get
705-
{{
706-
return ref AsSpan()[index];
707-
}}
708-
}}
709-
710-
[UnscopedRef]
711-
public Span<MyStruct> AsSpan() => MemoryMarshal.CreateSpan(ref e0_0_0_0, 24);
712650
}}
713651
}}
714652
}}
@@ -732,9 +670,7 @@ struct MyOtherStruct
732670
}};
733671
";
734672

735-
var expectedOutputContents = $@"using System;
736-
using System.Diagnostics.CodeAnalysis;
737-
using System.Runtime.InteropServices;
673+
var expectedOutputContents = $@"using System.Runtime.CompilerServices;
738674
739675
namespace ClangSharp.Test
740676
{{
@@ -748,23 +684,10 @@ public partial struct MyOtherStruct
748684
[NativeTypeName(""MyBuffer"")]
749685
public _c_e__FixedBuffer c;
750686
687+
[InlineArray(3)]
751688
public partial struct _c_e__FixedBuffer
752689
{{
753690
public MyStruct e0;
754-
public MyStruct e1;
755-
public MyStruct e2;
756-
757-
[UnscopedRef]
758-
public ref MyStruct this[int index]
759-
{{
760-
get
761-
{{
762-
return ref AsSpan()[index];
763-
}}
764-
}}
765-
766-
[UnscopedRef]
767-
public Span<MyStruct> AsSpan() => MemoryMarshal.CreateSpan(ref e0, 3);
768691
}}
769692
}}
770693
}}
@@ -786,9 +709,7 @@ struct MyOtherStruct
786709
}};
787710
";
788711

789-
var expectedOutputContents = $@"using System;
790-
using System.Diagnostics.CodeAnalysis;
791-
using System.Runtime.InteropServices;
712+
var expectedOutputContents = $@"using System.Runtime.CompilerServices;
792713
793714
namespace ClangSharp.Test
794715
{{
@@ -803,23 +724,10 @@ public partial struct MyOtherStruct
803724
[NativeTypeName(""MyStruct[3]"")]
804725
public _c_e__FixedBuffer c;
805726
727+
[InlineArray(3)]
806728
public partial struct _c_e__FixedBuffer
807729
{{
808730
public MyStruct e0;
809-
public MyStruct e1;
810-
public MyStruct e2;
811-
812-
[UnscopedRef]
813-
public ref MyStruct this[int index]
814-
{{
815-
get
816-
{{
817-
return ref AsSpan()[index];
818-
}}
819-
}}
820-
821-
[UnscopedRef]
822-
public Span<MyStruct> AsSpan() => MemoryMarshal.CreateSpan(ref e0, 3);
823731
}}
824732
}}
825733
}}
@@ -1135,6 +1043,7 @@ struct MyStruct
11351043

11361044
var expectedOutputContents = $@"using System;
11371045
using System.Diagnostics.CodeAnalysis;
1046+
using System.Runtime.CompilerServices;
11381047
using System.Runtime.InteropServices;
11391048
11401049
namespace ClangSharp.Test
@@ -1273,24 +1182,10 @@ public partial struct _Anonymous2_e__Union
12731182
public {expectedManagedType} value2;
12741183
}}
12751184
1185+
[InlineArray(4)]
12761186
public partial struct _buffer2_e__FixedBuffer
12771187
{{
12781188
public MyUnion e0;
1279-
public MyUnion e1;
1280-
public MyUnion e2;
1281-
public MyUnion e3;
1282-
1283-
[UnscopedRef]
1284-
public ref MyUnion this[int index]
1285-
{{
1286-
get
1287-
{{
1288-
return ref AsSpan()[index];
1289-
}}
1290-
}}
1291-
1292-
[UnscopedRef]
1293-
public Span<MyUnion> AsSpan() => MemoryMarshal.CreateSpan(ref e0, 4);
12941189
}}
12951190
}}
12961191
}}

0 commit comments

Comments
 (0)