Skip to content

Commit 1fe801a

Browse files
Merge pull request #271 from tannergooding/improvements
Adding support for generating unmanaged constants
2 parents 83d82f0 + 98d8b67 commit 1fe801a

29 files changed

+1184
-335
lines changed

sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,32 @@ public bool? IsStatic
200200

201201
public bool NeedsReturnFixup
202202
{
203-
get => (Flags & FunctionOrDelegateFlags.NeedsReturnFixup) != 0;
204-
set => Flags = value
205-
? Flags | FunctionOrDelegateFlags.NeedsReturnFixup
206-
: Flags & ~FunctionOrDelegateFlags.NeedsReturnFixup;
203+
get
204+
{
205+
return (Flags & FunctionOrDelegateFlags.NeedsReturnFixup) != 0;
206+
}
207+
208+
set
209+
{
210+
Flags = value
211+
? Flags | FunctionOrDelegateFlags.NeedsReturnFixup
212+
: Flags & ~FunctionOrDelegateFlags.NeedsReturnFixup;
213+
}
207214
}
208215

209216
public bool IsCxxConstructor
210217
{
211-
get => (Flags & FunctionOrDelegateFlags.IsCxxConstructor) != 0;
212-
set => Flags = value
213-
? Flags | FunctionOrDelegateFlags.IsCxxConstructor
214-
: Flags & ~FunctionOrDelegateFlags.IsCxxConstructor;
218+
get
219+
{
220+
return (Flags & FunctionOrDelegateFlags.IsCxxConstructor) != 0;
221+
}
222+
223+
set
224+
{
225+
Flags = value
226+
? Flags | FunctionOrDelegateFlags.IsCxxConstructor
227+
: Flags & ~FunctionOrDelegateFlags.IsCxxConstructor;
228+
}
215229
}
216230

217231
public Action<TCustomAttrGeneratorData> WriteCustomAttrs { get; set; }
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
22

3+
using System;
4+
35
namespace ClangSharp.Abstractions
46
{
57
internal partial interface IOutputBuilder
@@ -8,7 +10,7 @@ internal partial interface IOutputBuilder
810
void SuppressDivider();
911

1012
void WriteCustomAttribute(string attribute);
11-
void WriteIid(string iidName, string iidValue);
13+
void WriteIid(string name, Guid value);
1214
void EmitUsingDirective(string directive);
1315
}
1416
}

sources/ClangSharp.PInvokeGenerator/Abstractions/IOutputBuilder.VisitDecl.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ namespace ClangSharp.Abstractions
44
{
55
internal partial interface IOutputBuilder
66
{
7+
bool IsUncheckedContext { get; }
8+
79
void BeginInnerValue();
810
void EndInnerValue();
911

@@ -14,12 +16,10 @@ internal partial interface IOutputBuilder
1416
void BeginUnchecked();
1517
void EndUnchecked();
1618

17-
void BeginConstant(in ConstantDesc desc);
18-
void BeginConstantValue(bool isGetOnlyProperty = false);
19+
void BeginValue(in ValueDesc desc);
1920
void WriteConstantValue(long value);
2021
void WriteConstantValue(ulong value);
21-
void EndConstantValue();
22-
void EndConstant(bool isConstant);
22+
void EndValue(in ValueDesc desc);
2323

2424
void BeginEnum(in EnumDesc desc);
2525
void EndEnum();
@@ -29,8 +29,7 @@ internal partial interface IOutputBuilder
2929
void WriteRegularField(string typeName, string escapedName);
3030
void EndField(bool isBodyless = true);
3131

32-
void BeginFunctionOrDelegate<TCustomAttrGeneratorData>(in FunctionOrDelegateDesc<TCustomAttrGeneratorData> info,
33-
ref bool isMethodClassUnsafe);
32+
void BeginFunctionOrDelegate<TCustomAttrGeneratorData>(in FunctionOrDelegateDesc<TCustomAttrGeneratorData> info, ref bool isMethodClassUnsafe);
3433
void BeginFunctionInnerPrototype(string escapedName);
3534
void BeginParameter<TCustomAttrGeneratorData>(in ParameterDesc<TCustomAttrGeneratorData> info);
3635
void BeginParameterDefault();

sources/ClangSharp.PInvokeGenerator/Abstractions/StructDesc.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,15 @@ public bool HasVtbl
4646

4747
public bool IsUnion
4848
{
49-
get => (Flags & StructFlags.IsUnion) != 0;
50-
set => Flags = value ? Flags | StructFlags.IsUnion : Flags & ~StructFlags.IsUnion;
49+
get
50+
{
51+
return (Flags & StructFlags.IsUnion) != 0;
52+
}
53+
54+
set
55+
{
56+
Flags = value ? Flags | StructFlags.IsUnion : Flags & ~StructFlags.IsUnion;
57+
}
5158
}
5259

5360
public Action<TCustomAttrGeneratorData> WriteCustomAttrs { get; set; }

sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantDesc.cs renamed to sources/ClangSharp.PInvokeGenerator/Abstractions/ValueDesc.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@
44

55
namespace ClangSharp.Abstractions
66
{
7-
internal struct ConstantDesc
7+
internal struct ValueDesc
88
{
99
public AccessSpecifier AccessSpecifier { get; set; }
1010
public string TypeName { get; set; }
1111
public string EscapedName { get; set; }
1212
public string NativeTypeName { get; set; }
13-
public ConstantKind Kind { get; set; }
13+
public ValueKind Kind { get; set; }
14+
public ValueFlags Flags { get; set; }
1415
public CXSourceLocation? Location { get; set; }
16+
17+
public bool HasInitializer => Flags.HasFlag(ValueFlags.Initializer);
18+
public bool IsArray => Flags.HasFlag(ValueFlags.Array);
19+
public bool IsConstant => Flags.HasFlag(ValueFlags.Constant);
20+
public bool IsCopy => Flags.HasFlag(ValueFlags.Copy);
1521
}
1622
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
2+
3+
namespace ClangSharp.Abstractions
4+
{
5+
internal enum ValueKind
6+
{
7+
Unknown,
8+
Primitive,
9+
Enumerator,
10+
Unmanaged,
11+
String,
12+
}
13+
}

sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantKind.cs renamed to sources/ClangSharp.PInvokeGenerator/Abstractions/ValueModifiers.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
namespace ClangSharp.Abstractions
66
{
77
[Flags]
8-
internal enum ConstantKind
8+
internal enum ValueFlags
99
{
1010
None = 0,
11-
ReadOnly = 1 << 0,
12-
Enumerator = 1 << 1,
13-
PrimitiveConstant = 1 << 2,
14-
NonPrimitiveConstant = 1 << 3
11+
Initializer = 1 << 0,
12+
Constant = 1 << 1,
13+
Copy = 1 << 2,
14+
Array = 1 << 3,
1515
}
1616
}

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

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information.
22

3+
using System;
4+
using System.Runtime.CompilerServices;
5+
36
namespace ClangSharp.CSharp
47
{
58
internal partial class CSharpOutputBuilder
@@ -49,13 +52,72 @@ public void WriteDivider(bool force = false)
4952

5053
public void SuppressDivider() => NeedsNewline = false;
5154

52-
public void WriteIid(string iidName, string iidValue)
55+
public void WriteIid(string name, Guid value)
56+
{
57+
if (_config.GenerateUnmanagedConstants)
58+
{
59+
AddUsingDirective("System");
60+
AddUsingDirective("System.Diagnostics");
61+
AddUsingDirective("System.Runtime.CompilerServices");
62+
AddUsingDirective("System.Runtime.InteropServices");
63+
64+
WriteIndented("public static ref readonly Guid ");
65+
WriteLine(name);
66+
WriteBlockStart();
67+
68+
WriteIndentedLine("get");
69+
WriteBlockStart();
70+
71+
WriteIndentedLine("ReadOnlySpan<byte> data = new byte[] {");
72+
IncreaseIndentation();
73+
WriteIndentation();
74+
75+
WriteValueAsBytes(Unsafe.As<Guid, uint>(ref value), 4);
76+
77+
WriteLine(',');
78+
WriteIndentation();
79+
80+
WriteValueAsBytes(Unsafe.As<Guid, ushort>(ref Unsafe.AddByteOffset(ref value, (nint)4)), 2);
81+
82+
WriteLine(',');
83+
WriteIndentation();
84+
85+
WriteValueAsBytes(Unsafe.As<Guid, ushort>(ref Unsafe.AddByteOffset(ref value, (nint)6)), 2);
86+
87+
for (var i = 8; i < 16; i++)
88+
{
89+
WriteLine(',');
90+
WriteIndentation();
91+
92+
WriteValueAsBytes(Unsafe.As<Guid, ushort>(ref Unsafe.AddByteOffset(ref value, (nint)i)), 1);
93+
}
94+
95+
WriteNewline();
96+
DecreaseIndentation();
97+
WriteIndentedLine("};");
98+
99+
NeedsNewline = true;
100+
101+
WriteIndentedLine("Debug.Assert(data.Length == Unsafe.SizeOf<Guid>());");
102+
WriteIndentedLine("return ref Unsafe.As<byte, Guid>(ref MemoryMarshal.GetReference(data));");
103+
104+
WriteBlockEnd();
105+
WriteBlockEnd();
106+
}
107+
else
108+
{
109+
var valueString = value.ToString("X").ToUpperInvariant().Replace("{", "").Replace("}", "").Replace('X', 'x').Replace(",", ", ");
110+
WriteIid(name, valueString);
111+
}
112+
}
113+
114+
public void WriteIid(string name, string value)
53115
{
54116
AddUsingDirective("System");
55117
WriteIndented("public static readonly Guid ");
56-
Write(iidName);
118+
Write(name);
57119
Write(" = new Guid(");
58-
Write(iidValue);
120+
Write(value);
59121
Write(")");
60122
WriteSemicolon();
61123
WriteNewline();

0 commit comments

Comments
 (0)