Skip to content

Commit ec8c7a5

Browse files
Merge pull request #389 from tannergooding/main
Adding support for decltype
2 parents 7a7aea2 + 4d1cac8 commit ec8c7a5

File tree

14 files changed

+377
-0
lines changed

14 files changed

+377
-0
lines changed

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,6 +2092,10 @@ private CallingConvention GetCallingConvention(Cursor? cursor, Cursor? context,
20922092
}
20932093
}
20942094
}
2095+
else if (type is DecltypeType decltypeType)
2096+
{
2097+
return GetCallingConvention(cursor, context, decltypeType.UnderlyingType, ref wasRemapped);
2098+
}
20952099
else if (type is FunctionType functionType)
20962100
{
20972101
var callingConv = functionType.CallConv;
@@ -3021,6 +3025,10 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type
30213025
}
30223026
}
30233027
}
3028+
else if (type is DecltypeType decltypeType)
3029+
{
3030+
result.typeName = GetTypeName(cursor, context, rootType, decltypeType.UnderlyingType, ignoreTransparentStructsWhereRequired, out _);
3031+
}
30243032
else if (type is DeducedType deducedType)
30253033
{
30263034
result.typeName = GetTypeName(cursor, context, rootType, deducedType.CanonicalType, ignoreTransparentStructsWhereRequired, out _);
@@ -3536,6 +3544,10 @@ private void GetTypeSize(Cursor cursor, Type type, ref long alignment32, ref lon
35363544
}
35373545
}
35383546
}
3547+
else if (type is DecltypeType decltypeType)
3548+
{
3549+
GetTypeSize(cursor, decltypeType.UnderlyingType, ref alignment32, ref alignment64, ref has8BytePrimitiveField, out size32, out size64);
3550+
}
35393551
else if (type is ElaboratedType elaboratedType)
35403552
{
35413553
GetTypeSize(cursor, elaboratedType.NamedType, ref alignment32, ref alignment64, ref has8BytePrimitiveField, out size32, out size64);
@@ -4465,6 +4477,10 @@ private bool IsFixedSize(Cursor cursor, Type type)
44654477
{
44664478
return true;
44674479
}
4480+
else if (type is DecltypeType decltypeType)
4481+
{
4482+
return IsFixedSize(cursor, decltypeType.UnderlyingType);
4483+
}
44684484
else if (type is ElaboratedType elaboratedType)
44694485
{
44704486
return IsFixedSize(cursor, elaboratedType.NamedType);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public abstract class StructDeclarationTest : PInvokeGeneratorTest
3737
[Test]
3838
public Task BitfieldTest() => BitfieldTestImpl();
3939

40+
[Test]
41+
public Task DeclTypeTest() => DeclTypeTestImpl();
42+
4043
[Test]
4144
public Task ExcludeTest() => ExcludeTestImpl();
4245

@@ -216,6 +219,8 @@ public abstract class StructDeclarationTest : PInvokeGeneratorTest
216219

217220
protected abstract Task BitfieldTestImpl();
218221

222+
protected abstract Task DeclTypeTestImpl();
223+
219224
protected abstract Task ExcludeTestImpl();
220225

221226
protected abstract Task FixedSizedBufferNonPrimitiveTestImpl(string nativeType, string expectedManagedType);

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,37 @@ public uint o0_b1_1
320320
return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
321321
}
322322

323+
protected override Task DeclTypeTestImpl()
324+
{
325+
var inputContents = @"extern ""C"" void MyFunction();
326+
327+
typedef struct
328+
{
329+
decltype(&MyFunction) _callback;
330+
} MyStruct;
331+
";
332+
333+
var expectedOutputContents = @"using System;
334+
using System.Runtime.InteropServices;
335+
336+
namespace ClangSharp.Test
337+
{
338+
public partial struct MyStruct
339+
{
340+
[NativeTypeName(""decltype(&MyFunction)"")]
341+
public IntPtr _callback;
342+
}
343+
344+
public static partial class Methods
345+
{
346+
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
347+
public static extern void MyFunction();
348+
}
349+
}
350+
";
351+
return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
352+
}
353+
323354
protected override Task ExcludeTestImpl()
324355
{
325356
var inputContents = "typedef struct MyStruct MyStruct;";

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,37 @@ public uint o0_b1_1
324324
return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
325325
}
326326

327+
protected override Task DeclTypeTestImpl()
328+
{
329+
var inputContents = @"extern ""C"" void MyFunction();
330+
331+
typedef struct
332+
{
333+
decltype(&MyFunction) _callback;
334+
} MyStruct;
335+
";
336+
337+
var expectedOutputContents = @"using System;
338+
using System.Runtime.InteropServices;
339+
340+
namespace ClangSharp.Test
341+
{
342+
public partial struct MyStruct
343+
{
344+
[NativeTypeName(""decltype(&MyFunction)"")]
345+
public IntPtr _callback;
346+
}
347+
348+
public static partial class Methods
349+
{
350+
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
351+
public static extern void MyFunction();
352+
}
353+
}
354+
";
355+
return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
356+
}
357+
327358
protected override Task ExcludeTestImpl()
328359
{
329360
var inputContents = "typedef struct MyStruct MyStruct;";

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,36 @@ public uint o0_b1_1
320320
return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
321321
}
322322

323+
protected override Task DeclTypeTestImpl()
324+
{
325+
var inputContents = @"extern ""C"" void MyFunction();
326+
327+
typedef struct
328+
{
329+
decltype(&MyFunction) _callback;
330+
} MyStruct;
331+
";
332+
333+
var expectedOutputContents = @"using System.Runtime.InteropServices;
334+
335+
namespace ClangSharp.Test
336+
{
337+
public unsafe partial struct MyStruct
338+
{
339+
[NativeTypeName(""decltype(&MyFunction)"")]
340+
public delegate* unmanaged[Cdecl]<void> _callback;
341+
}
342+
343+
public static partial class Methods
344+
{
345+
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
346+
public static extern void MyFunction();
347+
}
348+
}
349+
";
350+
return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents);
351+
}
352+
323353
protected override Task ExcludeTestImpl()
324354
{
325355
var inputContents = "typedef struct MyStruct MyStruct;";

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,36 @@ public uint o0_b1_1
324324
return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
325325
}
326326

327+
protected override Task DeclTypeTestImpl()
328+
{
329+
var inputContents = @"extern ""C"" void MyFunction();
330+
331+
typedef struct
332+
{
333+
decltype(&MyFunction) _callback;
334+
} MyStruct;
335+
";
336+
337+
var expectedOutputContents = @"using System.Runtime.InteropServices;
338+
339+
namespace ClangSharp.Test
340+
{
341+
public unsafe partial struct MyStruct
342+
{
343+
[NativeTypeName(""decltype(&MyFunction)"")]
344+
public delegate* unmanaged[Cdecl]<void> _callback;
345+
}
346+
347+
public static partial class Methods
348+
{
349+
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
350+
public static extern void MyFunction();
351+
}
352+
}
353+
";
354+
return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents);
355+
}
356+
327357
protected override Task ExcludeTestImpl()
328358
{
329359
var inputContents = "typedef struct MyStruct MyStruct;";

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,36 @@ public uint o0_b1_1
320320
return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents);
321321
}
322322

323+
protected override Task DeclTypeTestImpl()
324+
{
325+
var inputContents = @"extern ""C"" void MyFunction();
326+
327+
typedef struct
328+
{
329+
decltype(&MyFunction) _callback;
330+
} MyStruct;
331+
";
332+
333+
var expectedOutputContents = @"using System.Runtime.InteropServices;
334+
335+
namespace ClangSharp.Test
336+
{
337+
public unsafe partial struct MyStruct
338+
{
339+
[NativeTypeName(""decltype(&MyFunction)"")]
340+
public delegate* unmanaged[Cdecl]<void> _callback;
341+
}
342+
343+
public static partial class Methods
344+
{
345+
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
346+
public static extern void MyFunction();
347+
}
348+
}
349+
";
350+
return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents);
351+
}
352+
323353
protected override Task ExcludeTestImpl()
324354
{
325355
var inputContents = "typedef struct MyStruct MyStruct;";

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,36 @@ public uint o0_b1_1
324324
return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents);
325325
}
326326

327+
protected override Task DeclTypeTestImpl()
328+
{
329+
var inputContents = @"extern ""C"" void MyFunction();
330+
331+
typedef struct
332+
{
333+
decltype(&MyFunction) _callback;
334+
} MyStruct;
335+
";
336+
337+
var expectedOutputContents = @"using System.Runtime.InteropServices;
338+
339+
namespace ClangSharp.Test
340+
{
341+
public unsafe partial struct MyStruct
342+
{
343+
[NativeTypeName(""decltype(&MyFunction)"")]
344+
public delegate* unmanaged[Cdecl]<void> _callback;
345+
}
346+
347+
public static partial class Methods
348+
{
349+
[DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
350+
public static extern void MyFunction();
351+
}
352+
}
353+
";
354+
return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents);
355+
}
356+
327357
protected override Task ExcludeTestImpl()
328358
{
329359
var inputContents = "typedef struct MyStruct MyStruct;";

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,35 @@ struct MyStruct3
296296
return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
297297
}
298298

299+
protected override Task DeclTypeTestImpl()
300+
{
301+
var inputContents = @"extern ""C"" void MyFunction();
302+
303+
typedef struct
304+
{
305+
decltype(&MyFunction) _callback;
306+
} MyStruct;
307+
";
308+
309+
var expectedOutputContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>
310+
<bindings>
311+
<namespace name=""ClangSharp.Test"">
312+
<struct name=""MyStruct"" access=""public"">
313+
<field name=""_callback"" access=""public"">
314+
<type native=""decltype(&amp;MyFunction)"">IntPtr</type>
315+
</field>
316+
</struct>
317+
<class name=""Methods"" access=""public"" static=""true"">
318+
<function name=""MyFunction"" access=""public"" lib=""ClangSharpPInvokeGenerator"" convention=""Cdecl"" static=""true"">
319+
<type>void</type>
320+
</function>
321+
</class>
322+
</namespace>
323+
</bindings>
324+
";
325+
return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
326+
}
327+
299328
protected override Task ExcludeTestImpl()
300329
{
301330
var inputContents = "typedef struct MyStruct MyStruct;";

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,35 @@ struct MyStruct3
302302
return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
303303
}
304304

305+
protected override Task DeclTypeTestImpl()
306+
{
307+
var inputContents = @"extern ""C"" void MyFunction();
308+
309+
typedef struct
310+
{
311+
decltype(&MyFunction) _callback;
312+
} MyStruct;
313+
";
314+
315+
var expectedOutputContents = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>
316+
<bindings>
317+
<namespace name=""ClangSharp.Test"">
318+
<struct name=""MyStruct"" access=""public"">
319+
<field name=""_callback"" access=""public"">
320+
<type native=""decltype(&amp;MyFunction)"">IntPtr</type>
321+
</field>
322+
</struct>
323+
<class name=""Methods"" access=""public"" static=""true"">
324+
<function name=""MyFunction"" access=""public"" lib=""ClangSharpPInvokeGenerator"" convention=""Cdecl"" static=""true"">
325+
<type>void</type>
326+
</function>
327+
</class>
328+
</namespace>
329+
</bindings>
330+
";
331+
return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
332+
}
333+
305334
protected override Task ExcludeTestImpl()
306335
{
307336
var inputContents = "typedef struct MyStruct MyStruct;";

0 commit comments

Comments
 (0)