Skip to content

Commit d90d328

Browse files
committed
Generate with no hacks correctly sized layouts
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent 153a4d0 commit d90d328

File tree

4 files changed

+9
-17
lines changed

4 files changed

+9
-17
lines changed

src/AST/ClassExtensions.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace CppSharp.AST
77
{
8-
public static class ClassExtensions
8+
public static class ClassExtensions
99
{
1010
public static IEnumerable<Function> GetFunctionOverloads(this Class @class,
1111
Function function)
@@ -211,6 +211,11 @@ public static bool HasDependentValueFieldInLayout(this Class @class)
211211
b => b.Class).Any(HasDependentValueFieldInLayout);
212212
}
213213

214+
public static int GetSize(this ClassLayout layout) =>
215+
/// There's at least one ABI (System V) that gives to empty structs
216+
/// size 1 in C++ and size 0 in C. The former causes crashes in older versions of Mono.
217+
layout.Size == 1 && layout.DataSize == 0 ? 0 : layout.Size;
218+
214219
private static bool IsValueDependent(Type type)
215220
{
216221
var desugared = type.Desugar();

src/Generator/Generators/CSharp/CSharpSources.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ public void GenerateClassInternals(Class @class)
524524
{
525525
PushBlock(BlockKind.InternalsClass);
526526
if (!Options.GenerateSequentialLayout || @class.IsUnion)
527-
WriteLine($"[StructLayout(LayoutKind.Explicit, Size = {@class.Layout.Size})]");
527+
WriteLine($"[StructLayout(LayoutKind.Explicit, Size = {@class.Layout.GetSize()})]");
528528
else if (@class.MaxFieldAlignment > 0)
529529
WriteLine($"[StructLayout(LayoutKind.Sequential, Pack = {@class.MaxFieldAlignment})]");
530530

@@ -2885,7 +2885,7 @@ public void GenerateFunctionCall(string functionName, List<Parameter> parameters
28852885
((Method) method.OriginalFunction).IsConstructor)
28862886
{
28872887
WriteLine($@"Marshal.AllocHGlobal({
2888-
((Class) method.OriginalNamespace).Layout.Size});");
2888+
((Class) method.OriginalNamespace).Layout.GetSize()});");
28892889
names.Insert(0, Helpers.ReturnIdentifier);
28902890
}
28912891
WriteLine("{0}({1});", functionName, string.Join(", ", names));

src/Generator/Generators/CSharp/CSharpTypePrinter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public override TypePrinterResult VisitArrayType(ArrayType array,
100100
return new TypePrinterResult
101101
{
102102
Type = "fixed byte",
103-
NameSuffix = $"[{array.Size * @class.Layout.Size}]"
103+
NameSuffix = $"[{array.Size * @class.Layout.GetSize()}]"
104104
};
105105
}
106106

src/Generator/Passes/CheckAbiParameters.cs

-13
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,6 @@ namespace CppSharp.Passes
2525
/// </summary>
2626
public class CheckAbiParameters : TranslationUnitPass
2727
{
28-
public override bool VisitClassDecl(Class @class)
29-
{
30-
if (!base.VisitClassDecl(@class))
31-
return false;
32-
33-
if (@class.IsDependent || @class.Layout.Fields.Count > 0 || @class.Fields.Count > 0)
34-
return false;
35-
36-
@class.Layout.Size = @class.Layout.DataSize = 0;
37-
38-
return true;
39-
}
40-
4128
public override bool VisitFunctionDecl(Function function)
4229
{
4330
if (!VisitDeclaration(function))

0 commit comments

Comments
 (0)