Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public struct LayoutDesc
public long Size32 { get; set; }
public long Size64 { get; set; }
public long Pack { get; set; }
public string? PackOverride { get; set; }
public long MaxFieldAlignment { get; set; }
public LayoutKind Kind { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -740,13 +740,18 @@ public void BeginStruct(in StructDesc desc)
WriteLine("\"]/*' />");
}

if (desc.LayoutAttribute is not null)
if (desc.LayoutAttribute is not null || desc.Layout.PackOverride is not null)
{
AddUsingDirective("System.Runtime.InteropServices");
WriteIndented("[StructLayout(LayoutKind.");
Write(desc.LayoutAttribute.Value);
Write(desc.LayoutAttribute?.Value ?? LayoutKind.Sequential);

if (desc.LayoutAttribute.Pack != 0)
if (desc.Layout.PackOverride is { } packOverride)
{
Write(", Pack = ");
Write(packOverride);
}
else if (desc.LayoutAttribute!.Pack != 0)
{
Write(", Pack = ");
Write(desc.LayoutAttribute.Pack);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,7 @@ private void VisitRecordDecl(RecordDecl recordDecl)
Size32 = size32,
Size64 = size64,
Pack = alignment < maxAlignm ? alignment : 0,
PackOverride = TryGetRemappedValue(recordDecl, _config.WithPackOverrides, out var packOverride) ? packOverride : null,
MaxFieldAlignment = maxAlignm,
Kind = layoutKind
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public sealed class PInvokeGeneratorConfiguration
private readonly SortedDictionary<string, (string, PInvokeGeneratorTransparentStructKind)> _withTransparentStructs;
private readonly SortedDictionary<string, string> _withTypes;
private readonly SortedDictionary<string, IReadOnlyList<string>> _withUsings;
private readonly SortedDictionary<string, string> _withPackOverrides;

private PInvokeGeneratorConfigurationOptions _options;

Expand Down Expand Up @@ -94,6 +95,7 @@ public PInvokeGeneratorConfiguration(string defaultNamespace, string outputLocat
_withTransparentStructs = new SortedDictionary<string, (string, PInvokeGeneratorTransparentStructKind)>();
_withTypes = new SortedDictionary<string, string>();
_withUsings = new SortedDictionary<string, IReadOnlyList<string>>();
_withPackOverrides = new SortedDictionary<string, string>();

if ((outputMode == PInvokeGeneratorOutputMode.Xml) && !options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles) && (options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsNUnit) || options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsXUnit)))
{
Expand Down Expand Up @@ -528,6 +530,20 @@ public IReadOnlyDictionary<string, IReadOnlyList<string>> WithUsings
}
}

[AllowNull]
public IReadOnlyDictionary<string, string> WithPackOverrides
{
get
{
return _withPackOverrides;
}

init
{
AddRange(_withPackOverrides, value);
}
}

public static AccessSpecifier ConvertStringToAccessSpecifier(string input)
{
if (input.Equals("internal", StringComparison.OrdinalIgnoreCase))
Expand Down
19 changes: 18 additions & 1 deletion sources/ClangSharpPInvokeGenerator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public class Program
private static readonly Option<string[]> s_withTransparentStructNameValuePairs;
private static readonly Option<string[]> s_withTypeNameValuePairs;
private static readonly Option<string[]> s_withUsingNameValuePairs;
private static readonly Option<string[]> s_withPackOverrideNameValuePairs;


private static readonly TwoColumnHelpRow[] s_configOptions = new TwoColumnHelpRow[]
Expand Down Expand Up @@ -161,6 +162,7 @@ static Program()
s_withTransparentStructNameValuePairs = GetWithTransparentStructOption();
s_withTypeNameValuePairs = GetWithTypeOption();
s_withUsingNameValuePairs = GetWithUsingOption();
s_withPackOverrideNameValuePairs = GetWithPackOverrideOption();

s_rootCommand = new RootCommand("ClangSharp P/Invoke Binding Generator")
{
Expand Down Expand Up @@ -198,7 +200,8 @@ static Program()
s_withSuppressGCTransitions,
s_withTransparentStructNameValuePairs,
s_withTypeNameValuePairs,
s_withUsingNameValuePairs
s_withUsingNameValuePairs,
s_withPackOverrideNameValuePairs
};
Handler.SetHandler(s_rootCommand, (Action<InvocationContext>)Run);
}
Expand Down Expand Up @@ -255,6 +258,7 @@ public static void Run(InvocationContext context)
var withTransparentStructNameValuePairs = context.ParseResult.GetValueForOption(s_withTransparentStructNameValuePairs) ?? Array.Empty<string>();
var withTypeNameValuePairs = context.ParseResult.GetValueForOption(s_withTypeNameValuePairs) ?? Array.Empty<string>();
var withUsingNameValuePairs = context.ParseResult.GetValueForOption(s_withUsingNameValuePairs) ?? Array.Empty<string>();
var withPackOverrideNameValuePairs = context.ParseResult.GetValueForOption(s_withPackOverrideNameValuePairs) ?? Array.Empty<string>();

var versionResult = context.ParseResult.FindResultFor(s_versionOption);

Expand Down Expand Up @@ -295,6 +299,7 @@ public static void Run(InvocationContext context)
ParseKeyValuePairs(withTransparentStructNameValuePairs, errorList, out Dictionary<string, (string, PInvokeGeneratorTransparentStructKind)> withTransparentStructs);
ParseKeyValuePairs(withTypeNameValuePairs, errorList, out Dictionary<string, string> withTypes);
ParseKeyValuePairs(withUsingNameValuePairs, errorList, out Dictionary<string, IReadOnlyList<string>> withUsings);
ParseKeyValuePairs(withPackOverrideNameValuePairs, errorList, out Dictionary<string, string> withPackOverrides);

foreach (var key in withTransparentStructs.Keys)
{
Expand Down Expand Up @@ -681,6 +686,7 @@ public static void Run(InvocationContext context)
WithTransparentStructs = withTransparentStructs,
WithTypes = withTypes,
WithUsings = withUsings,
WithPackOverrides = withPackOverrides,
};

if (config.GenerateMacroBindings)
Expand Down Expand Up @@ -1288,4 +1294,15 @@ private static Option<string[]> GetWithUsingOption()
AllowMultipleArgumentsPerToken = true
};
}

private static Option<string[]> GetWithPackOverrideOption()
{
return new Option<string[]>(
aliases: new string[] { "--with-pack-override", "-wpo" },
description: "Overrides the StructLayoutAttribute.Pack property for the given type.",
getDefaultValue: Array.Empty<string>
) {
AllowMultipleArgumentsPerToken = true
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ private static async Task ValidateGeneratedBindingsAsync(string inputContents, s
WithTransparentStructs = withTransparentStructs,
WithTypes = withTypes,
WithUsings = withUsings,
WithPackOverrides = null,
};

using (var pinvokeGenerator = new PInvokeGenerator(config, (path) => outputStream))
Expand Down