Browse Source

Generate with no hacks correctly sized layouts

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
bug-pass-const-char-star-no-copy
Dimitar Dobrev 7 years ago
parent
commit
d90d3283e4
  1. 7
      src/AST/ClassExtensions.cs
  2. 4
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 2
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  4. 13
      src/Generator/Passes/CheckAbiParameters.cs

7
src/AST/ClassExtensions.cs

@ -5,7 +5,7 @@ using CppSharp.AST.Extensions;
namespace CppSharp.AST namespace CppSharp.AST
{ {
public static class ClassExtensions public static class ClassExtensions
{ {
public static IEnumerable<Function> GetFunctionOverloads(this Class @class, public static IEnumerable<Function> GetFunctionOverloads(this Class @class,
Function function) Function function)
@ -211,6 +211,11 @@ namespace CppSharp.AST
b => b.Class).Any(HasDependentValueFieldInLayout); b => b.Class).Any(HasDependentValueFieldInLayout);
} }
public static int GetSize(this ClassLayout layout) =>
/// There's at least one ABI (System V) that gives to empty structs
/// size 1 in C++ and size 0 in C. The former causes crashes in older versions of Mono.
layout.Size == 1 && layout.DataSize == 0 ? 0 : layout.Size;
private static bool IsValueDependent(Type type) private static bool IsValueDependent(Type type)
{ {
var desugared = type.Desugar(); var desugared = type.Desugar();

4
src/Generator/Generators/CSharp/CSharpSources.cs

@ -524,7 +524,7 @@ namespace CppSharp.Generators.CSharp
{ {
PushBlock(BlockKind.InternalsClass); PushBlock(BlockKind.InternalsClass);
if (!Options.GenerateSequentialLayout || @class.IsUnion) if (!Options.GenerateSequentialLayout || @class.IsUnion)
WriteLine($"[StructLayout(LayoutKind.Explicit, Size = {@class.Layout.Size})]"); WriteLine($"[StructLayout(LayoutKind.Explicit, Size = {@class.Layout.GetSize()})]");
else if (@class.MaxFieldAlignment > 0) else if (@class.MaxFieldAlignment > 0)
WriteLine($"[StructLayout(LayoutKind.Sequential, Pack = {@class.MaxFieldAlignment})]"); WriteLine($"[StructLayout(LayoutKind.Sequential, Pack = {@class.MaxFieldAlignment})]");
@ -2885,7 +2885,7 @@ namespace CppSharp.Generators.CSharp
((Method) method.OriginalFunction).IsConstructor) ((Method) method.OriginalFunction).IsConstructor)
{ {
WriteLine($@"Marshal.AllocHGlobal({ WriteLine($@"Marshal.AllocHGlobal({
((Class) method.OriginalNamespace).Layout.Size});"); ((Class) method.OriginalNamespace).Layout.GetSize()});");
names.Insert(0, Helpers.ReturnIdentifier); names.Insert(0, Helpers.ReturnIdentifier);
} }
WriteLine("{0}({1});", functionName, string.Join(", ", names)); WriteLine("{0}({1});", functionName, string.Join(", ", names));

2
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -100,7 +100,7 @@ namespace CppSharp.Generators.CSharp
return new TypePrinterResult return new TypePrinterResult
{ {
Type = "fixed byte", Type = "fixed byte",
NameSuffix = $"[{array.Size * @class.Layout.Size}]" NameSuffix = $"[{array.Size * @class.Layout.GetSize()}]"
}; };
} }

13
src/Generator/Passes/CheckAbiParameters.cs

@ -25,19 +25,6 @@ namespace CppSharp.Passes
/// </summary> /// </summary>
public class CheckAbiParameters : TranslationUnitPass public class CheckAbiParameters : TranslationUnitPass
{ {
public override bool VisitClassDecl(Class @class)
{
if (!base.VisitClassDecl(@class))
return false;
if (@class.IsDependent || @class.Layout.Fields.Count > 0 || @class.Fields.Count > 0)
return false;
@class.Layout.Size = @class.Layout.DataSize = 0;
return true;
}
public override bool VisitFunctionDecl(Function function) public override bool VisitFunctionDecl(Function function)
{ {
if (!VisitDeclaration(function)) if (!VisitDeclaration(function))

Loading…
Cancel
Save