diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 25ddf6b0..9e2cc211 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -219,10 +219,24 @@ namespace Cxxi.Generators.CLI public void GenerateClassConstructors(Class @class, string nativeType) { - // Output a default constructor that takes the native pointer. PushIndent(); + + // Output a default constructor that takes the native pointer. WriteLine("{0}({1} native);", SafeIdentifier(@class.Name), nativeType); WriteLine("{0}({1} native);", SafeIdentifier(@class.Name), "System::IntPtr"); + + foreach (var ctor in @class.Constructors) + { + if (ctor.IsCopyConstructor || ctor.IsMoveConstructor) + continue; + + // Default constructors are not supported in .NET value types. + if (ctor.Parameters.Count == 0 && @class.IsValueType) + continue; + + GenerateMethod(ctor); + } + PopIndent(); } @@ -242,6 +256,23 @@ namespace Cxxi.Generators.CLI 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) + { + Class baseClass; + if (!@base.Type.IsTagDecl(out baseClass)) + continue; + + if (!baseClass.IsValueType || baseClass.Ignore) + { + Console.WriteLine("Ignored base class of value type '{0}'", baseClass.Name); + continue; + } + + GenerateClassFields(baseClass); + } } public void GenerateClassMethods(Class @class) @@ -254,6 +285,9 @@ namespace Cxxi.Generators.CLI if (CheckIgnoreMethod(@class, method)) continue; + if (method.IsConstructor) + continue; + if (method.IsStatic) { staticMethods.Add(method); @@ -426,6 +460,7 @@ namespace Cxxi.Generators.CLI WriteLine(","); } PopIndent(); + NewLine(); WriteLine("};"); } diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index bdb6d6eb..1386bb85 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -136,29 +136,64 @@ namespace Cxxi.Generators.CLI var nativeType = string.Format("::{0}*", @class.OriginalName); WriteLine("{0} native)", isIntPtr ? "System::IntPtr" : nativeType); - WriteLine("{"); - PushIndent(); + + var hasBase = GenerateClassConstructorBase(@class); + + WriteStartBraceIndent(); if (@class.IsRefType) { - Write("NativePtr = "); - if (isIntPtr) - Write("({0})", nativeType); - Write("native"); - if (isIntPtr) - Write(".ToPointer()"); - WriteLine(";"); + if (!hasBase) + { + Write("NativePtr = "); + + if (isIntPtr) + Write("({0})", nativeType); + Write("native"); + if (isIntPtr) + Write(".ToPointer()"); + WriteLine(";"); + } } else { WriteLine("// TODO: Struct marshaling"); } - PopIndent(); - WriteLine("}"); + WriteCloseBraceIndent(); NewLine(); } + private void GenerateStructMarshaling(Class @class) + { + foreach (var field in @class.Fields) + { + + WriteLine("{0} = {1}"); + } + } + + private bool GenerateClassConstructorBase(Class @class, Method method = null) + { + var hasBase = @class.HasBase && !@class.Bases[0].Class.Ignore; + + if (hasBase && !@class.IsValueType) + { + PushIndent(); + Write(": {0}(", @class.Bases[0].Class.Name); + + if (method != null) + Write("nullptr"); + else + Write("native"); + + WriteLine(")"); + PopIndent(); + } + + return hasBase; + } + public void GenerateMethod(Method method, Class @class) { GenerateDeclarationCommon(method); @@ -172,17 +207,23 @@ namespace Cxxi.Generators.CLI GenerateMethodParameters(method); WriteLine(")"); - WriteLine("{"); - PushIndent(); + + if (method.Kind == CXXMethodKind.Constructor) + GenerateClassConstructorBase(@class, method); + + WriteStartBraceIndent(); if (@class.IsRefType) { if (method.Kind == CXXMethodKind.Constructor) { - var @params = GenerateFunctionParamsMarshal(method); - Write("NativePtr = new ::{0}(", method.QualifiedOriginalName); - GenerateFunctionParams(method, @params); - WriteLine(");"); + if (!@class.IsAbstract) + { + var @params = GenerateFunctionParamsMarshal(method); + Write("NativePtr = new ::{0}(", method.QualifiedOriginalName); + GenerateFunctionParams(method, @params); + WriteLine(");"); + } } else { @@ -195,8 +236,7 @@ namespace Cxxi.Generators.CLI GenerateFunctionCall(method, @class); } - PopIndent(); - WriteLine("}"); + WriteCloseBraceIndent(); } public void GenerateFunction(Function function, string className)