From b3d42185bac625695caa28deacdbeed575d984c6 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 22 Mar 2013 20:43:24 +0000 Subject: [PATCH 1/4] Declare base type fields before value type fields --- .../Generators/CLI/CLIHeadersTemplate.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index ff524435..eeb355fb 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -277,18 +277,6 @@ namespace Cxxi.Generators.CLI if (!@class.IsValueType) return; - PushIndent(); - foreach (var field in @class.Fields) - { - if (CheckIgnoreField(@class, field)) continue; - - GenerateDeclarationCommon(field); - if (@class.IsUnion) - WriteLine("[FieldOffset({0})]", field.Offset); - WriteLine("{0} {1};", field.Type, SafeIdentifier(field.Name)); - } - PopIndent(); - // Handle the case of struct (value-type) inheritance by adding the base // fields to the managed value subtypes. foreach (var @base in @class.Bases) @@ -306,6 +294,18 @@ namespace Cxxi.Generators.CLI GenerateClassFields(baseClass); } + + PushIndent(); + foreach (var field in @class.Fields) + { + if (CheckIgnoreField(@class, field)) continue; + + GenerateDeclarationCommon(field); + if (@class.IsUnion) + WriteLine("[FieldOffset({0})]", field.Offset); + WriteLine("{0} {1};", field.Type, SafeIdentifier(field.Name)); + } + PopIndent(); } public void GenerateClassEvents(Class @class) From 874ea01b0e64368741c37b760e1e9f2c443cb210 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 22 Mar 2013 20:47:04 +0000 Subject: [PATCH 2/4] Recursive Marshaling of value class fields --- src/Generator/Generators/CLI/CLIMarshal.cs | 59 ++++++++++++++-------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs index 597f232b..6603b52a 100644 --- a/src/Generator/Generators/CLI/CLIMarshal.cs +++ b/src/Generator/Generators/CLI/CLIMarshal.cs @@ -541,34 +541,53 @@ namespace Cxxi.Generators.CLI @class.QualifiedOriginalName); SupportBefore.PushIndent(); - foreach (var field in @class.Fields) - { - var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name, - field.Name); + MarshalValueClassFields(@class, marshalVar); - var marshalCtx = new MarshalContext(Context.Driver) - { - ArgName = fieldRef, - ParameterIndex = Context.ParameterIndex++ - }; + Return.Write(marshalVar); - var marshal = new CLIMarshalManagedToNativePrinter(TypeMapDatabase, - marshalCtx); - field.Visit(marshal); + if (Context.Parameter.Type.IsPointer()) + ArgumentPrefix.Write("&"); + } - Context.ParameterIndex = marshalCtx.ParameterIndex; + private void MarshalValueClassFields(Class @class, string marshalVar) + { + foreach (var @base in @class.Bases) + { + if (!@base.IsClass || @base.Class.Ignore) + continue; - if (!string.IsNullOrWhiteSpace(marshal.SupportBefore)) - SupportBefore.WriteLine(marshal.SupportBefore); + var baseClass = @base.Class; + MarshalValueClassFields(baseClass, marshalVar); + } - SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar, field.OriginalName, - marshal.Return); + foreach (var field in @class.Fields) + { + MarshalValueClassField(field, marshalVar); } + } - Return.Write(marshalVar); + private void MarshalValueClassField(Field field, string marshalVar) + { + var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name, + field.Name); - if (Context.Parameter.Type.IsPointer()) - ArgumentPrefix.Write("&"); + var marshalCtx = new MarshalContext(Context.Driver) + { + ArgName = fieldRef, + ParameterIndex = Context.ParameterIndex++ + }; + + var marshal = new CLIMarshalManagedToNativePrinter(TypeMapDatabase, + marshalCtx); + field.Visit(marshal); + + Context.ParameterIndex = marshalCtx.ParameterIndex; + + if (!string.IsNullOrWhiteSpace(marshal.SupportBefore)) + SupportBefore.WriteLine(marshal.SupportBefore); + + SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar, field.OriginalName, + marshal.Return); } public bool VisitFieldDecl(Field field) From 62fcb0696efd9755a2928a1c2e1b101dad621990 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 22 Mar 2013 20:50:19 +0000 Subject: [PATCH 3/4] Recursive struct fields marshaling --- .../Generators/CLI/CLISourcesTemplate.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 93ee1cac..25cf7290 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -384,9 +384,23 @@ namespace Cxxi.Generators.CLI private void GenerateStructMarshaling(Class @class, string nativePointer) { + GenerateStructMarshalingFields(@class, nativePointer); + } + + private void GenerateStructMarshalingFields(Class @class, string nativePointer) + { + foreach (var @base in @class.Bases) + { + if (!@base.IsClass || @base.Class.Ignore) + continue; + + var baseClass = @base.Class; + GenerateStructMarshalingFields(baseClass, nativePointer); + } + foreach (var field in @class.Fields) { - if (field.Ignore) continue; + if (CheckIgnoreField(@class, field)) continue; var nativeField = string.Format("{0}->{1}", nativePointer, field.OriginalName); From 06cc6ace39912ee9a3380ed20d1baaea697d6367 Mon Sep 17 00:00:00 2001 From: marcos henrich Date: Fri, 22 Mar 2013 20:55:09 +0000 Subject: [PATCH 4/4] Added to value type constructors, native value type initialization and copy from native fields to managed fields. --- .../Generators/CLI/CLISourcesTemplate.cs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 25cf7290..5dcf0ec9 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -479,11 +479,71 @@ namespace Cxxi.Generators.CLI { if (method.Kind != CXXMethodKind.Constructor) GenerateFunctionCall(method, @class); + else + GenerateValueTypeConstructorCall(method, @class); } WriteCloseBraceIndent(); } + private void GenerateValueTypeConstructorCall(Method method, Class @class) + { + var names = new List(); + + foreach (var param in method.Parameters) + { + var ctx = new MarshalContext(Driver) + { + Parameter = param, + ArgName = param.Name, + }; + + var marshal = new CLIMarshalManagedToNativePrinter(Driver.TypeDatabase, + ctx); + param.Visit(marshal); + + if (!string.IsNullOrWhiteSpace(marshal.SupportBefore)) + WriteLine(marshal.SupportBefore); + + names.Add(marshal.Return); + } + + WriteLine("auto _native = ::{0}({1});", @class.QualifiedOriginalName, + string.Join(", ", names)); + + GenerateValueTypeConstructorCallFields(@class); + } + + private void GenerateValueTypeConstructorCallFields(Class @class) + { + foreach (var @base in @class.Bases) + { + if (!@base.IsClass || @base.Class.Ignore) + continue; + + var baseClass = @base.Class; + GenerateValueTypeConstructorCallFields(baseClass); + } + + foreach (var field in @class.Fields) + { + if (CheckIgnoreField(@class, field)) continue; + + var varName = string.Format("_native.{0}", field.OriginalName); + + var ctx = new MarshalContext(Driver) + { + ReturnVarName = varName, + ReturnType = field.Type + }; + + var marshal = new CLIMarshalNativeToManagedPrinter(Driver, ctx); + field.Visit(marshal); + + WriteLine("this->{0} = {1};", field.Name, marshal.Return); + } + } + public void GenerateFunction(Function function, Namespace @namespace) { if (function.Ignore)