From cfeed2619a677cd65588a70653fa06527214201d Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Fri, 3 Jan 2014 11:48:33 +0200 Subject: [PATCH] Extended type maps with the ability to insert custom code instead of a copy ctor invocation. Signed-off-by: Dimitar Dobrev --- src/AST/Class.cs | 22 +++++++++++-- .../Generators/CSharp/CSharpMarshal.cs | 33 ++++++++++++++----- .../Generators/CSharp/CSharpTextTemplate.cs | 9 +++-- src/Generator/Types/TypeMap.cs | 5 +++ 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/AST/Class.cs b/src/AST/Class.cs index 008c8aac..2c49ac32 100644 --- a/src/AST/Class.cs +++ b/src/AST/Class.cs @@ -33,10 +33,26 @@ namespace CppSharp.AST get { Class @class; - if (!Type.IsTagDecl(out @class)) - throw new NotSupportedException(); + if (Type.IsTagDecl(out @class)) + return @class; - return @class; + var type = Type.Desugar() as TemplateSpecializationType; + if (type == null) + { + TypedefType typedef; + if (Type.IsPointerTo(out typedef)) + { + type = (TemplateSpecializationType) typedef.Desugar(); + } + else + { + Type.IsPointerTo(out type); + } + } + var templatedClass = ((ClassTemplate) type.Template).TemplatedClass; + return templatedClass.IsIncomplete + ? (Class) templatedClass.CompleteDeclaration + : templatedClass; } } diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 42723af7..30e4d68f 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -252,10 +252,6 @@ namespace CppSharp.Generators.CSharp if (VarSuffix > 0) instanceName += VarSuffix; - // Allocate memory for a new native object and call the ctor. - Context.SupportBefore.WriteLine("var {0} = Marshal.AllocHGlobal({1});", - instanceName, @class.Layout.Size); - if (@class.HasNonTrivialCopyConstructor) { // Find a valid copy constructor overload. @@ -266,13 +262,27 @@ namespace CppSharp.Generators.CSharp throw new NotSupportedException("Expected a valid copy constructor"); // Call the copy constructor. - Context.SupportBefore.WriteLine("{0}.Internal.{1}({2}, new global::System.IntPtr(&{3}));", - QualifiedIdentifier(@class), - CSharpTextTemplate.GetFunctionNativeIdentifier(copyCtorMethod), - instanceName, instance); + TypeMap typeMap; + if (copyCtorMethod.Ignore && FindTypeMap(ctx.Driver.TypeDatabase, @class, out typeMap)) + { + typeMap.CSharpMarshalCopyCtorToManaged(Context); + } + else + { + // Allocate memory for a new native object and call the ctor. + Context.SupportBefore.WriteLine("var {0} = Marshal.AllocHGlobal({1});", + instanceName, @class.Layout.Size); + Context.SupportBefore.WriteLine("{0}.Internal.{1}({2}, new global::System.IntPtr(&{3}));", + QualifiedIdentifier(@class), + CSharpTextTemplate.GetFunctionNativeIdentifier(copyCtorMethod), + instanceName, instance); + } } else { + // Allocate memory for a new native object and call the ctor. + Context.SupportBefore.WriteLine("var {0} = Marshal.AllocHGlobal({1});", + instanceName, @class.Layout.Size); instance = instance.Trim('*'); Context.SupportBefore.WriteLine( "CppSharp.Runtime.Helpers.memcpy({0}, new IntPtr(&{1}), new UIntPtr({2}));", @@ -291,6 +301,13 @@ namespace CppSharp.Generators.CSharp return true; } + private static bool FindTypeMap(ITypeMapDatabase typeMapDatabase, + Class @class, out TypeMap typeMap) + { + return typeMapDatabase.FindTypeMap(@class, out typeMap) || + (@class.HasBase && FindTypeMap(typeMapDatabase, @class.Bases[0].Class, out typeMap)); + } + public override bool VisitEnumDecl(Enumeration @enum) { Context.Return.Write("{0}", Context.ReturnVarName); diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 6c92d4c8..bd1b6355 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -7,6 +7,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Web.Util; using CppSharp.AST; +using CppSharp.Types; using CppSharp.Utils; using Attribute = CppSharp.AST.Attribute; using Type = CppSharp.AST.Type; @@ -777,13 +778,11 @@ namespace CppSharp.Generators.CSharp { foreach (var @base in @class.Bases) { - if (!@base.IsClass) continue; - var baseClass = @base.Class; - - if (baseClass.Ignore) + TypeMap typeMap; + if (!Driver.TypeDatabase.FindTypeMap(@base.Type, out typeMap) && @base.Class.Ignore) continue; - GenerateClassFields(baseClass, action); + GenerateClassFields(@base.Class, action); } foreach (var field in @class.Fields) diff --git a/src/Generator/Types/TypeMap.cs b/src/Generator/Types/TypeMap.cs index 9b018d93..03fca1c8 100644 --- a/src/Generator/Types/TypeMap.cs +++ b/src/Generator/Types/TypeMap.cs @@ -59,6 +59,11 @@ namespace CppSharp.Types throw new NotImplementedException(); } + public virtual void CSharpMarshalCopyCtorToManaged(MarshalContext ctx) + { + + } + #endregion #region C++/CLI backend