Browse Source

Moved the C# generation of internal names of template specialisations to the C# type printer.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/337/merge
Dimitar Dobrev 9 years ago
parent
commit
cf7813d8d6
  1. 5
      src/AST/ASTVisitor.cs
  2. 57
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  3. 177
      src/Generator/Generators/CSharp/CSharpSources.cs
  4. 18
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs

5
src/AST/ASTVisitor.cs

@ -22,6 +22,7 @@ namespace CppSharp.AST
public bool VisitClassFields = true; public bool VisitClassFields = true;
public bool VisitClassProperties = true; public bool VisitClassProperties = true;
public bool VisitClassMethods = true; public bool VisitClassMethods = true;
public bool VisitClassTemplateSpecializations { get; set; } = true;
public bool VisitNamespaceEnums = true; public bool VisitNamespaceEnums = true;
public bool VisitNamespaceTemplates = true; public bool VisitNamespaceTemplates = true;
@ -325,6 +326,10 @@ namespace CppSharp.AST
VisitMethodDecl(method); VisitMethodDecl(method);
} }
if (@class.IsDependent && VisitOptions.VisitClassTemplateSpecializations)
foreach (var specialization in @class.Specializations)
VisitClassTemplateSpecializationDecl(specialization);
return true; return true;
} }

57
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -331,6 +331,12 @@ namespace CppSharp.Generators.CSharp
return true; return true;
} }
public override bool VisitTemplateParameterSubstitutionType(TemplateParameterSubstitutionType param, TypeQualifiers quals)
{
Context.Return.Write("({0}) (object) ", param.ReplacedParameter.Parameter.Name);
return base.VisitTemplateParameterSubstitutionType(param, quals);
}
private string HandleReturnedPointer(Class @class, string qualifiedClass) private string HandleReturnedPointer(Class @class, string qualifiedClass)
{ {
var originalClass = @class.OriginalClass ?? @class; var originalClass = @class.OriginalClass ?? @class;
@ -495,22 +501,34 @@ namespace CppSharp.Generators.CSharp
if (!VisitType(pointer, quals)) if (!VisitType(pointer, quals))
return false; return false;
var pointee = pointer.Pointee.Desugar();
if (Context.Function != null && pointer.IsPrimitiveTypeConvertibleToRef() && if (Context.Function != null && pointer.IsPrimitiveTypeConvertibleToRef() &&
Context.Kind != CSharpMarshalKind.VTableReturnValue) Context.Kind != CSharpMarshalKind.VTableReturnValue)
{ {
var refParamPtr = string.Format("__refParamPtr{0}", Context.ParameterIndex); var refParamPtr = string.Format("__refParamPtr{0}", Context.ParameterIndex);
Context.SupportBefore.WriteLine("fixed ({0} {1} = &{2})", var templateSubstitution = pointer.Pointee as TemplateParameterSubstitutionType;
pointer, refParamPtr, Context.Parameter.Name); if (templateSubstitution != null)
Context.HasCodeBlock = true; {
Context.SupportBefore.WriteStartBraceIndent(); var castParam = $"__{Context.Parameter.Name}{Context.ParameterIndex}";
Context.Return.Write(refParamPtr); Context.SupportBefore.WriteLine(
$"var {castParam} = ({templateSubstitution}) (object) {Context.Parameter.Name};");
Context.SupportBefore.WriteLine($"{pointer} {refParamPtr} = &{castParam};");
Context.Return.Write(refParamPtr);
}
else
{
Context.SupportBefore.WriteLine(
$"fixed ({pointer} {refParamPtr} = &{Context.Parameter.Name})");
Context.HasCodeBlock = true;
Context.SupportBefore.WriteStartBraceIndent();
Context.Return.Write(refParamPtr);
}
return true; return true;
} }
var param = Context.Parameter; var param = Context.Parameter;
var isRefParam = param != null && (param.IsInOut || param.IsOut); var isRefParam = param != null && (param.IsInOut || param.IsOut);
var pointee = pointer.Pointee.Desugar();
if (CSharpTypePrinter.IsConstCharString(pointee) && isRefParam) if (CSharpTypePrinter.IsConstCharString(pointee) && isRefParam)
{ {
if (param.IsOut) if (param.IsOut)
@ -668,6 +686,15 @@ namespace CppSharp.Generators.CSharp
return decl.Type.Visit(this); return decl.Type.Visit(this);
} }
public override bool VisitTemplateParameterSubstitutionType(TemplateParameterSubstitutionType param, TypeQualifiers quals)
{
var replacement = param.Replacement.Type.Desugar();
Class @class;
Context.Return.Write($@"{(replacement.TryGetClass(out @class) ?
string.Empty : $"({replacement}) (object) ")}");
return base.VisitTemplateParameterSubstitutionType(param, quals);
}
public override bool VisitTemplateParameterType(TemplateParameterType param, TypeQualifiers quals) public override bool VisitTemplateParameterType(TemplateParameterType param, TypeQualifiers quals)
{ {
Context.Return.Write(param.Parameter.Name); Context.Return.Write(param.Parameter.Name);
@ -706,12 +733,17 @@ namespace CppSharp.Generators.CSharp
Type type = Context.Parameter.Type.Desugar(); Type type = Context.Parameter.Type.Desugar();
string paramInstance; string paramInstance;
Class @interface; Class @interface;
if ((type.GetFinalPointee() ?? type).TryGetClass(out @interface) && var finalType = type.GetFinalPointee() ?? type;
var templateType = finalType as TemplateParameterSubstitutionType;
if (finalType.TryGetClass(out @interface) &&
@interface.IsInterface) @interface.IsInterface)
paramInstance = string.Format("{0}.__PointerTo{1}", paramInstance = string.Format("{0}.__PointerTo{1}",
param, @interface.OriginalClass.Name); param, @interface.OriginalClass.Name);
else else
paramInstance = string.Format("{0}.{1}", param, Helpers.InstanceIdentifier); paramInstance = $@"{
(templateType != null ? $"(({@class.Visit(typePrinter)}) (object) " : string.Empty)}{
param}{(templateType != null ? ")" : string.Empty)
}.{Helpers.InstanceIdentifier}";
if (type.IsAddress()) if (type.IsAddress())
{ {
Class decl; Class decl;
@ -747,11 +779,12 @@ namespace CppSharp.Generators.CSharp
} }
var realClass = @class.OriginalClass ?? @class; var realClass = @class.OriginalClass ?? @class;
var qualifiedIdentifier = realClass.Visit(this.typePrinter); typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
var qualifiedIdentifier = realClass.Visit(typePrinter);
typePrinter.PopContext();
Context.Return.Write( Context.Return.Write(
"ReferenceEquals({0}, null) ? new {1}.{2}{3}() : *({1}.{2}{3}*) {4}", "ReferenceEquals({0}, null) ? new {1}() : *({1}*) {2}",
param, qualifiedIdentifier, Helpers.InternalStruct, param, qualifiedIdentifier, paramInstance);
Helpers.GetSuffixForInternal(@class), paramInstance);
} }
private void MarshalValueClass() private void MarshalValueClass()

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

@ -448,7 +448,8 @@ namespace CppSharp.Generators.CSharp
System.Type typeMap = null; System.Type typeMap = null;
string key = string.Empty; string key = string.Empty;
foreach (var name in new[] { @class.OriginalName, @class.QualifiedOriginalName }) var cppTypePrinter = new CppTypePrinter { PrintScopeKind = CppTypePrintScopeKind.Qualified };
foreach (var name in new[] { @class.OriginalName, @class.Visit(cppTypePrinter) })
{ {
if (Context.TypeMaps.TypeMaps.ContainsKey(name)) if (Context.TypeMaps.TypeMaps.ContainsKey(name))
{ {
@ -502,7 +503,7 @@ namespace CppSharp.Generators.CSharp
// use interfaces if any - derived types with a secondary base this class must be compatible with the map // use interfaces if any - derived types with a secondary base this class must be compatible with the map
var @interface = @class.Namespace.Classes.Find(c => c.OriginalClass == @class); var @interface = @class.Namespace.Classes.Find(c => c.OriginalClass == @class);
var dict = string.Format("global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {0}>", var dict = string.Format("global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {0}>",
@interface != null ? @interface.Name : @class.Name); (@interface ?? @class).Visit(TypePrinter));
WriteLine("internal static readonly {0} NativeToManagedMap = new {0}();", dict); WriteLine("internal static readonly {0} NativeToManagedMap = new {0}();", dict);
WriteLine("protected void*[] __OriginalVTables;"); WriteLine("protected void*[] __OriginalVTables;");
} }
@ -695,9 +696,8 @@ namespace CppSharp.Generators.CSharp
if (@class != null && @class.NeedsBase && !@class.BaseClass.IsInterface & !isSpecialization) if (@class != null && @class.NeedsBase && !@class.BaseClass.IsInterface & !isSpecialization)
Write("new "); Write("new ");
var suffix = Helpers.GetSuffixForInternal(@class); WriteLine($@"{(isSpecialization ? "unsafe " : string.Empty)}partial struct {
WriteLine("{0}partial struct {1}{2}", Helpers.InternalStruct}{Helpers.GetSuffixForInternal(@class)}");
isSpecialization ? "unsafe " : string.Empty, Helpers.InternalStruct, suffix);
} }
public static bool ShouldGenerateClassNativeField(Class @class) public static bool ShouldGenerateClassNativeField(Class @class)
@ -884,18 +884,12 @@ namespace CppSharp.Generators.CSharp
if (method != null && method.OperatorKind == CXXOperatorKind.Subscript) if (method != null && method.OperatorKind == CXXOperatorKind.Subscript)
{ {
if (method.OperatorKind == CXXOperatorKind.Subscript) if (method.OperatorKind == CXXOperatorKind.Subscript)
{
GenerateIndexerSetter(method); GenerateIndexerSetter(method);
}
else else
{
GenerateInternalFunctionCall(function, new List<Parameter> { param }); GenerateInternalFunctionCall(function, new List<Parameter> { param });
}
} }
else else
{
GenerateInternalFunctionCall(function, new List<Parameter> { param }); GenerateInternalFunctionCall(function, new List<Parameter> { param });
}
} }
} }
else if (decl is Field) else if (decl is Field)
@ -920,13 +914,11 @@ namespace CppSharp.Generators.CSharp
else else
{ {
var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name; var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name;
ctx.ReturnVarName = string.Format("{0}{1}{2}", TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
@class.IsValueType ctx.ReturnVarName = $@"{(@class.IsValueType ? Helpers.InstanceField :
? Helpers.InstanceField $"(({@class.Visit(TypePrinter)}*) {Helpers.InstanceIdentifier})")}{
: string.Format("(({0}{1}*) {2})", Helpers.InternalStruct, (@class.IsValueType ? "." : "->")}{Helpers.SafeIdentifier(name)}";
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier), TypePrinter.PopContext();
@class.IsValueType ? "." : "->",
Helpers.SafeIdentifier(name));
} }
param.Visit(marshal); param.Visit(marshal);
@ -1047,11 +1039,12 @@ namespace CppSharp.Generators.CSharp
function.Type.IsPointerTo(out type); function.Type.IsPointerTo(out type);
PrimitiveType primitiveType; PrimitiveType primitiveType;
var internalFunction = GetFunctionNativeIdentifier(function); var internalFunction = GetFunctionNativeIdentifier(function);
var @internal = $@"{Helpers.InternalStruct}{
Helpers.GetSuffixForInternal(function.Namespace)}";
if (type.IsPrimitiveType(out primitiveType)) if (type.IsPrimitiveType(out primitiveType))
{ {
WriteLine("*{0}{1}.{2}({3}, {4}) = value;", WriteLine($@"*{@internal}.{internalFunction}({
Helpers.InternalStruct, Helpers.GetSuffixForInternal(function.Namespace), GetInstanceParam(function)}, {function.Parameters[0].Name}) = value;");
internalFunction, GetInstanceParam(function), function.Parameters[0].Name);
} }
else else
{ {
@ -1059,14 +1052,13 @@ namespace CppSharp.Generators.CSharp
Class @class; Class @class;
var isValueType = (type.GetFinalPointee() ?? type).TryGetClass(out @class) && var isValueType = (type.GetFinalPointee() ?? type).TryGetClass(out @class) &&
@class.IsValueType; @class.IsValueType;
var paramMarshal = GenerateFunctionParamMarshal(function.Parameters[0], 0, function); var paramMarshal = GenerateFunctionParamMarshal(
var suffix = Helpers.GetSuffixForInternal(function.Namespace); function.Parameters[0], 0, function);
WriteLine("*({0}.{1}{2}*) {1}{2}.{3}({4}, {5}) = {6}value.{7};", WriteLine($@"*({typeString}.{@internal}*) {@internal}.{internalFunction}({
typeString, Helpers.InternalStruct, suffix, internalFunction, GetInstanceParam(function), GetInstanceParam(function)}, {(paramMarshal.Context == null ?
paramMarshal.Context == null ? paramMarshal.Name : paramMarshal.Context.Return, paramMarshal.Name : paramMarshal.Context.Return)}) = {
isValueType ? string.Empty : (isValueType ? string.Empty : $@"*({typeString}.{@internal}*) ")}value.{
string.Format("*({0}.{1}{2}*) ", typeString, Helpers.InternalStruct, suffix), Helpers.InstanceIdentifier};");
Helpers.InstanceIdentifier);
} }
} }
@ -1121,20 +1113,18 @@ namespace CppSharp.Generators.CSharp
WriteStartBraceIndent(); WriteStartBraceIndent();
var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name; var name = @class.Layout.Fields.First(f => f.FieldPtr == field.OriginalPtr).Name;
TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
var ctx = new CSharpMarshalContext(Context) var ctx = new CSharpMarshalContext(Context)
{ {
Kind = CSharpMarshalKind.NativeField, Kind = CSharpMarshalKind.NativeField,
ArgName = decl.Name, ArgName = decl.Name,
Declaration = decl, Declaration = decl,
ReturnVarName = string.Format("{0}{1}{2}", ReturnVarName = $@"{(@class.IsValueType ? Helpers.InstanceField :
@class.IsValueType $"(({@class.Visit(TypePrinter)}*) {Helpers.InstanceIdentifier})")}{
? Helpers.InstanceField (@class.IsValueType ? "." : "->")}{Helpers.SafeIdentifier(name)}",
: string.Format("(({0}{1}*) {2})", Helpers.InternalStruct,
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier),
@class.IsValueType ? "." : "->",
Helpers.SafeIdentifier(name)),
ReturnType = decl.QualifiedType ReturnType = decl.QualifiedType
}; };
TypePrinter.PopContext();
var arrayType = field.Type as ArrayType; var arrayType = field.Type as ArrayType;
@ -1459,8 +1449,9 @@ namespace CppSharp.Generators.CSharp
WriteLine("if (__OriginalVTables != null)"); WriteLine("if (__OriginalVTables != null)");
WriteLineIndent("return;"); WriteLineIndent("return;");
WriteLine("var native = ({0}{1}*) {2}.ToPointer();", Helpers.InternalStruct, TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier); WriteLine($"var native = ({@class.Visit(TypePrinter)}*) {Helpers.InstanceIdentifier}.ToPointer();");
TypePrinter.PopContext();
NewLine(); NewLine();
SaveOriginalVTablePointers(@class); SaveOriginalVTablePointers(@class);
@ -1532,8 +1523,8 @@ namespace CppSharp.Generators.CSharp
private void SaveOriginalVTablePointers(Class @class, bool cast = false) private void SaveOriginalVTablePointers(Class @class, bool cast = false)
{ {
var pointer = cast ? $@"(({Helpers.InternalStruct}{ TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
Helpers.GetSuffixForInternal(@class)}*) native)" : "native"; var pointer = cast ? $@"(({@class.Visit(TypePrinter)}*) native)" : "native";
if (Context.ParserOptions.IsMicrosoftAbi) if (Context.ParserOptions.IsMicrosoftAbi)
WriteLine("__OriginalVTables = new void*[] {{ {0} }};", WriteLine("__OriginalVTables = new void*[] {{ {0} }};",
string.Join(", ", string.Join(", ",
@ -1543,6 +1534,7 @@ namespace CppSharp.Generators.CSharp
WriteLine( WriteLine(
$@"__OriginalVTables = new void*[] {{ {pointer}->{ $@"__OriginalVTables = new void*[] {{ {pointer}->{
@class.Layout.VTablePointers[0].Name}.ToPointer() }};"); @class.Layout.VTablePointers[0].Name}.ToPointer() }};");
TypePrinter.PopContext();
} }
private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries, private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries,
@ -1770,7 +1762,7 @@ namespace CppSharp.Generators.CSharp
WriteLineIndent("throw new global::System.Exception(\"No managed instance was found\");"); WriteLineIndent("throw new global::System.Exception(\"No managed instance was found\");");
NewLine(); NewLine();
WriteLine("var {0} = ({1}) NativeToManagedMap[instance];", Helpers.TargetIdentifier, @class.Name); WriteLine("var {0} = ({1}) NativeToManagedMap[instance];", Helpers.TargetIdentifier, @class.Visit(TypePrinter));
WriteLine("if ({0}.{1})", Helpers.TargetIdentifier, Helpers.OwnsNativeInstanceIdentifier); WriteLine("if ({0}.{1})", Helpers.TargetIdentifier, Helpers.OwnsNativeInstanceIdentifier);
WriteLineIndent("{0}.SetupVTables();", Helpers.TargetIdentifier); WriteLineIndent("{0}.SetupVTables();", Helpers.TargetIdentifier);
GenerateVTableManagedCall(method); GenerateVTableManagedCall(method);
@ -1988,18 +1980,18 @@ namespace CppSharp.Generators.CSharp
Helpers.DummyIdentifier); Helpers.DummyIdentifier);
WriteLine("NativeToManagedMap.TryRemove({0}, out {1});", WriteLine("NativeToManagedMap.TryRemove({0}, out {1});",
Helpers.InstanceIdentifier, Helpers.DummyIdentifier); Helpers.InstanceIdentifier, Helpers.DummyIdentifier);
var suffix = Helpers.GetSuffixForInternal(@class); TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
var classInternal = @class.Visit(TypePrinter);
TypePrinter.PopContext();
if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0) if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0)
{ {
if (Context.ParserOptions.IsMicrosoftAbi) if (Context.ParserOptions.IsMicrosoftAbi)
for (var i = 0; i < @class.Layout.VTablePointers.Count; i++) for (var i = 0; i < @class.Layout.VTablePointers.Count; i++)
WriteLine("(({0}{1}*) {2})->{3} = new global::System.IntPtr(__OriginalVTables[{4}]);", WriteLine($@"(({classInternal}*) {Helpers.InstanceIdentifier})->{
Helpers.InternalStruct, suffix, Helpers.InstanceIdentifier, @class.Layout.VTablePointers[i].Name} = new global::System.IntPtr(__OriginalVTables[{i}]);");
@class.Layout.VTablePointers[i].Name, i);
else else
WriteLine("(({0}{1}*) {2})->{3} = new global::System.IntPtr(__OriginalVTables[0]);", WriteLine($@"(({classInternal}*) {Helpers.InstanceIdentifier})->{
Helpers.InternalStruct, suffix, Helpers.InstanceIdentifier, @class.Layout.VTablePointers[0].Name} = new global::System.IntPtr(__OriginalVTables[0]);");
@class.Layout.VTablePointers[0].Name);
} }
} }
@ -2060,14 +2052,14 @@ namespace CppSharp.Generators.CSharp
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("internal static {0}{1} {2}(global::System.IntPtr native, bool skipVTables = false)", WriteLine("internal static {0}{1} {2}(global::System.IntPtr native, bool skipVTables = false)",
@class.NeedsBase && !@class.BaseClass.IsInterface ? "new " : string.Empty, @class.NeedsBase && !@class.BaseClass.IsInterface ? "new " : string.Empty,
@class.Name, Helpers.CreateInstanceIdentifier); @class.Visit(TypePrinter), Helpers.CreateInstanceIdentifier);
WriteStartBraceIndent(); WriteStartBraceIndent();
WriteLine("return new {0}(native.ToPointer(), skipVTables);", ctorCall); WriteLine("return new {0}(native.ToPointer(), skipVTables);", ctorCall);
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
GenerateNativeConstructorByValue(@class, className, ctorCall); GenerateNativeConstructorByValue(@class, ctorCall);
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("{0} {1}(void* native, bool skipVTables = false){2}", WriteLine("{0} {1}(void* native, bool skipVTables = false){2}",
@ -2115,35 +2107,36 @@ namespace CppSharp.Generators.CSharp
} }
else else
{ {
WriteLine("{0} = *({1}{2}*) native;", Helpers.InstanceField, TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
Helpers.InternalStruct, Helpers.GetSuffixForInternal(@class)); WriteLine($"{Helpers.InstanceField} = *({@class.Visit(TypePrinter)}*) native;");
TypePrinter.PopContext();
} }
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
private void GenerateNativeConstructorByValue(Class @class, string className, string ctorCall) private void GenerateNativeConstructorByValue(Class @class, string ctorCall)
{ {
var internalSuffix = Helpers.GetSuffixForInternal(@class); TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
var @internal = (@class.IsAbstractImpl ? @class.BaseClass : @class).Visit(TypePrinter);
TypePrinter.PopContext();
if (!@class.IsAbstractImpl) if (!@class.IsAbstractImpl)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("internal static {0} {1}({0}.{2}{3} native, bool skipVTables = false)", WriteLine("internal static {0} {1}({2} native, bool skipVTables = false)",
className, Helpers.CreateInstanceIdentifier, @class.Visit(TypePrinter), Helpers.CreateInstanceIdentifier, @internal);
Helpers.InternalStruct, internalSuffix);
WriteStartBraceIndent(); WriteStartBraceIndent();
WriteLine("return new {0}(native, skipVTables);", ctorCall); WriteLine("return new {0}(native, skipVTables);", ctorCall);
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
if (@class.IsRefType && !@class.IsAbstract) if (@class.IsRefType && !@class.IsAbstract)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("private static void* __CopyValue({0}.{1}{2} native)", WriteLine("private static void* __CopyValue({0} native)", @internal);
className, Helpers.InternalStruct, internalSuffix);
WriteStartBraceIndent(); WriteStartBraceIndent();
var copyCtorMethod = @class.Methods.FirstOrDefault(method => var copyCtorMethod = @class.Methods.FirstOrDefault(method =>
method.IsCopyConstructor); method.IsCopyConstructor);
@ -2152,18 +2145,17 @@ namespace CppSharp.Generators.CSharp
{ {
// Allocate memory for a new native object and call the ctor. // Allocate memory for a new native object and call the ctor.
WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size); WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size);
WriteLine("{0}.{1}{2}.{3}(ret, new global::System.IntPtr(&native));", TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
@class.Visit(TypePrinter), Helpers.InternalStruct, WriteLine($"{@class.Visit(TypePrinter)}.{GetFunctionNativeIdentifier(copyCtorMethod)}(ret, new global::System.IntPtr(&native));",
Helpers.GetSuffixForInternal(@class), @class.Visit(TypePrinter),
GetFunctionNativeIdentifier(copyCtorMethod)); GetFunctionNativeIdentifier(copyCtorMethod));
WriteLine("return ret.ToPointer();", className); TypePrinter.PopContext();
WriteLine("return ret.ToPointer();");
} }
else else
{ {
WriteLine("var ret = Marshal.AllocHGlobal({1});", WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size);
className, @class.Layout.Size); WriteLine("*({0}*) ret = native;", @internal);
WriteLine("*({0}.{1}{2}*) ret = native;", className,
Helpers.InternalStruct, Helpers.GetSuffixForInternal(@class));
WriteLine("return ret.ToPointer();"); WriteLine("return ret.ToPointer();");
} }
WriteCloseBraceIndent(); WriteCloseBraceIndent();
@ -2172,9 +2164,8 @@ namespace CppSharp.Generators.CSharp
if (!@class.IsAbstract) if (!@class.IsAbstract)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("{0} {1}({2}.{3}{4} native, bool skipVTables = false)", WriteLine("{0} {1}({2} native, bool skipVTables = false)",
@class.IsAbstractImpl ? "internal" : "private", @class.IsAbstractImpl ? "internal" : "private", @class.Name, @internal);
@class.Name, className, Helpers.InternalStruct, internalSuffix);
WriteLineIndent(@class.IsRefType ? ": this(__CopyValue(native), skipVTables)" : ": this()"); WriteLineIndent(@class.IsRefType ? ": this(__CopyValue(native), skipVTables)" : ": this()");
WriteStartBraceIndent(); WriteStartBraceIndent();
if (@class.IsRefType) if (@class.IsRefType)
@ -2455,8 +2446,10 @@ namespace CppSharp.Generators.CSharp
{ {
WriteLine("if ({0} == global::System.IntPtr.Zero)", Helpers.InstanceIdentifier); WriteLine("if ({0} == global::System.IntPtr.Zero)", Helpers.InstanceIdentifier);
WriteLineIndent("return global::System.IntPtr.Zero.GetHashCode();"); WriteLineIndent("return global::System.IntPtr.Zero.GetHashCode();");
WriteLine("return (*({0}{1}*) {2}).GetHashCode();", Helpers.InternalStruct, TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier); WriteLine($@"return (*({@class.Visit(TypePrinter)}*) {
Helpers.InstanceIdentifier}).GetHashCode();");
TypePrinter.PopContext();
} }
else else
{ {
@ -2623,10 +2616,13 @@ namespace CppSharp.Generators.CSharp
if (@class.HasNonTrivialCopyConstructor) if (@class.HasNonTrivialCopyConstructor)
GenerateInternalFunctionCall(method); GenerateInternalFunctionCall(method);
else else
WriteLine("*(({0}.{1}{2}*) {3}) = *(({0}.{1}{2}*) {4}.{3});", {
@class.Name, Helpers.InternalStruct, TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier, var classInternal = @class.Visit(TypePrinter);
method.Parameters[0].Name); TypePrinter.PopContext();
WriteLine($@"*(({classInternal}*) {Helpers.InstanceIdentifier}) = *(({
classInternal}*) {method.Parameters[0].Name}.{Helpers.InstanceIdentifier});");
}
} }
else else
{ {
@ -2643,14 +2639,17 @@ namespace CppSharp.Generators.CSharp
if (parameters == null) if (parameters == null)
parameters = function.Parameters; parameters = function.Parameters;
var templateSpecialization = function.Namespace as ClassTemplateSpecialization; var @class = function.Namespace as Class;
string @namespace = templateSpecialization != null && string @internal = Helpers.InternalStruct;
templateSpecialization.Ignore ? if (@class != null && @class is ClassTemplateSpecialization)
(templateSpecialization.Namespace.OriginalName + '.') : string.Empty; {
TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
@internal = @class.Visit(TypePrinter).Type;
TypePrinter.PopContext();
}
var functionName = string.Format("{0}{1}{2}.{3}", @namespace, var functionName = string.Format("{0}.{1}", @internal,
Helpers.InternalStruct, Helpers.GetSuffixForInternal(function.Namespace),
GetFunctionNativeIdentifier(function.OriginalFunction ?? function)); GetFunctionNativeIdentifier(function.OriginalFunction ?? function));
GenerateFunctionCall(functionName, parameters, function, returnType); GenerateFunctionCall(functionName, parameters, function, returnType);
} }
@ -2706,9 +2705,9 @@ namespace CppSharp.Generators.CSharp
if (construct == null) if (construct == null)
{ {
var @class = retClass.OriginalClass ?? retClass; var @class = retClass.OriginalClass ?? retClass;
WriteLine("var {0} = new {1}.{2}{3}();", Helpers.ReturnIdentifier, TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
@class.Visit(TypePrinter), Helpers.InternalStruct, WriteLine($"var {Helpers.ReturnIdentifier} = new {@class.Visit(TypePrinter)}();");
Helpers.GetSuffixForInternal(@class)); TypePrinter.PopContext();
} }
else else
{ {
@ -2766,9 +2765,9 @@ namespace CppSharp.Generators.CSharp
{ {
if (operatorParam == null) if (operatorParam == null)
{ {
WriteLine("fixed ({0}{1}* __instancePtr = &{2})", WriteLine($@"fixed ({Helpers.InternalStruct}{
Helpers.InternalStruct, Helpers.GetSuffixForInternal(originalFunction.Namespace), Helpers.GetSuffixForInternal(originalFunction.Namespace)}* __instancePtr = &{
Helpers.InstanceField); Helpers.InstanceField})");
WriteStartBraceIndent(); WriteStartBraceIndent();
} }
else else

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

@ -400,18 +400,12 @@ namespace CppSharp.Generators.CSharp
public CSharpTypePrinterResult VisitTemplateSpecializationType( public CSharpTypePrinterResult VisitTemplateSpecializationType(
TemplateSpecializationType template, TypeQualifiers quals) TemplateSpecializationType template, TypeQualifiers quals)
{ {
var decl = template.Template.TemplatedDecl; var decl = template.GetClassTemplateSpecialization() ??
template.Template.TemplatedDecl;
TypeMap typeMap; TypeMap typeMap;
if (!TypeMapDatabase.FindTypeMap(template, out typeMap)) if (!TypeMapDatabase.FindTypeMap(template, out typeMap))
{ return decl.Visit(this);
if (ContextKind != CSharpTypePrinterContextKind.Native)
return GetNestedQualifiedName(decl);
if (template.Desugared.Type.IsAddress())
return template.Desugared.Type.ToString();
var specialization = template.GetClassTemplateSpecialization();
return specialization.Visit(this);
}
typeMap.Declaration = decl; typeMap.Declaration = decl;
typeMap.Type = template; typeMap.Type = template;
@ -612,8 +606,8 @@ namespace CppSharp.Generators.CSharp
public CSharpTypePrinterResult VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization) public CSharpTypePrinterResult VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization)
{ {
if (ContextKind == CSharpTypePrinterContextKind.Native) if (ContextKind == CSharpTypePrinterContextKind.Native)
return string.Format("{0}{1}", VisitClassDecl(specialization), return $@"{VisitClassDecl(specialization)}{
Helpers.GetSuffixForInternal(specialization)); Helpers.GetSuffixForInternal(specialization)}";
return VisitClassDecl(specialization); return VisitClassDecl(specialization);
} }
@ -672,7 +666,7 @@ namespace CppSharp.Generators.CSharp
Declaration ctx; Declaration ctx;
var specialization = decl as ClassTemplateSpecialization; var specialization = decl as ClassTemplateSpecialization;
if (specialization != null) if (specialization != null && ContextKind == CSharpTypePrinterContextKind.Native)
{ {
ctx = specialization.TemplatedDecl.TemplatedClass.Namespace; ctx = specialization.TemplatedDecl.TemplatedClass.Namespace;
if (specialization.OriginalNamespace is Class && if (specialization.OriginalNamespace is Class &&

Loading…
Cancel
Save