Browse Source

Fixed the generated usages of internals of template specialisations with dependent fields.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/696/head
Dimitar Dobrev 10 years ago
parent
commit
5b52075d32
  1. 7
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 118
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 2
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs

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

@ -724,10 +724,11 @@ namespace CppSharp.Generators.CSharp
return; return;
} }
var qualifiedIdentifier = (@class.OriginalClass ?? @class).Visit(typePrinter); var realClass = @class.OriginalClass ?? @class;
var qualifiedIdentifier = realClass.Visit(this.typePrinter);
Context.Return.Write( Context.Return.Write(
"ReferenceEquals({0}, null) ? new {1}.Internal() : *({1}.Internal*) ({0}.{2})", param, "ReferenceEquals({0}, null) ? new {1}.Internal{3}() : *({1}.Internal{3}*) ({0}.{2})", param,
qualifiedIdentifier, Helpers.InstanceIdentifier); qualifiedIdentifier, Helpers.InstanceIdentifier, Helpers.GetSuffixForInternal(@class));
} }
private void MarshalValueClass() private void MarshalValueClass()

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

@ -72,10 +72,12 @@ namespace CppSharp.Generators.CSharp
.Replace('.', '_').Replace(' ', '_').Replace("::", "_").ToString(); .Replace('.', '_').Replace(' ', '_').Replace("::", "_").ToString();
} }
public static string GetSuffixForInternal(ClassTemplateSpecialization specialization, public static string GetSuffixForInternal(Declaration context)
CSharpTypePrinter typePrinter, bool nested = false)
{ {
if (specialization.TemplatedDecl.TemplatedClass.Fields.All( var specialization = context as ClassTemplateSpecialization;
if (specialization == null ||
specialization.TemplatedDecl.TemplatedClass.Fields.All(
f => !(f.Type.Desugar() is TemplateParameterType))) f => !(f.Type.Desugar() is TemplateParameterType)))
return string.Empty; return string.Empty;
@ -300,7 +302,6 @@ namespace CppSharp.Generators.CSharp
if (classTemplate.Specializations.Count == 0) if (classTemplate.Specializations.Count == 0)
return; return;
bool generateClass = false;
List<ClassTemplateSpecialization> specializations; List<ClassTemplateSpecialization> specializations;
if (classTemplate.Fields.Any( if (classTemplate.Fields.Any(
f => f.Type.Desugar() is TemplateParameterType)) f => f.Type.Desugar() is TemplateParameterType))
@ -310,16 +311,12 @@ namespace CppSharp.Generators.CSharp
specializations = new List<ClassTemplateSpecialization>(); specializations = new List<ClassTemplateSpecialization>();
var specialization = classTemplate.Specializations.FirstOrDefault(s => !s.Ignore); var specialization = classTemplate.Specializations.FirstOrDefault(s => !s.Ignore);
if (specialization == null) if (specialization == null)
{
specializations.Add(classTemplate.Specializations[0]); specializations.Add(classTemplate.Specializations[0]);
}
else else
{
specializations.Add(specialization); specializations.Add(specialization);
generateClass = true;
}
} }
bool generateClass = specializations.Any(s => s.IsGenerated);
if (!generateClass) if (!generateClass)
{ {
PushBlock(CSharpBlockKind.Namespace); PushBlock(CSharpBlockKind.Namespace);
@ -688,15 +685,13 @@ namespace CppSharp.Generators.CSharp
{ {
Write("public "); Write("public ");
if (@class != null && @class.NeedsBase && !@class.BaseClass.IsInterface && var isSpecialization = @class is ClassTemplateSpecialization;
!(@class is ClassTemplateSpecialization)) if (@class != null && @class.NeedsBase && !@class.BaseClass.IsInterface & !isSpecialization)
Write("new "); Write("new ");
var templateSpecialization = @class as ClassTemplateSpecialization; var suffix = Helpers.GetSuffixForInternal(@class);
var suffix = templateSpecialization == null ? string.Empty :
Helpers.GetSuffixForInternal(templateSpecialization, TypePrinter);
WriteLine("{0}partial struct Internal{1}", WriteLine("{0}partial struct Internal{1}",
templateSpecialization != null ? "unsafe " : string.Empty, suffix); isSpecialization ? "unsafe " : string.Empty, suffix);
} }
public static bool ShouldGenerateClassNativeField(Class @class) public static bool ShouldGenerateClassNativeField(Class @class)
@ -951,7 +946,8 @@ namespace CppSharp.Generators.CSharp
ctx.ReturnVarName = string.Format("{0}{1}{2}", ctx.ReturnVarName = string.Format("{0}{1}{2}",
@class.IsValueType @class.IsValueType
? Helpers.InstanceField ? Helpers.InstanceField
: string.Format("((Internal*) {0})", Helpers.InstanceIdentifier), : string.Format("((Internal{0}*) {1})",
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier),
@class.IsValueType ? "." : "->", @class.IsValueType ? "." : "->",
Helpers.SafeIdentifier(name)); Helpers.SafeIdentifier(name));
} }
@ -1035,8 +1031,9 @@ namespace CppSharp.Generators.CSharp
var internalFunction = GetFunctionNativeIdentifier(function); var internalFunction = GetFunctionNativeIdentifier(function);
if (type.IsPrimitiveType(out primitiveType)) if (type.IsPrimitiveType(out primitiveType))
{ {
WriteLine("*Internal.{0}({1}, {2}) = value;", internalFunction, WriteLine("*Internal{0}.{1}({2}, {3}) = value;",
GetInstanceParam(function), function.Parameters[0].Name); Helpers.GetSuffixForInternal(function.Namespace),
internalFunction, GetInstanceParam(function), function.Parameters[0].Name);
} }
else else
{ {
@ -1045,10 +1042,12 @@ namespace CppSharp.Generators.CSharp
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(function.Parameters[0], 0, function);
WriteLine("*({0}.Internal*) Internal.{1}({2}, {3}) = {4}value.{5};", var suffix = Helpers.GetSuffixForInternal(function.Namespace);
typeString, internalFunction, GetInstanceParam(function), WriteLine("*({0}.Internal{1}*) Internal{1}.{2}({3}, {4}) = {5}value.{6};",
typeString, suffix, internalFunction, GetInstanceParam(function),
paramMarshal.Context == null ? paramMarshal.Name : paramMarshal.Context.Return, paramMarshal.Context == null ? paramMarshal.Name : paramMarshal.Context.Return,
isValueType ? string.Empty : string.Format("*({0}.Internal*) ", typeString), isValueType ? string.Empty :
string.Format("*({0}.Internal{1}*) ", typeString, suffix),
Helpers.InstanceIdentifier); Helpers.InstanceIdentifier);
} }
} }
@ -1099,7 +1098,8 @@ namespace CppSharp.Generators.CSharp
ReturnVarName = string.Format("{0}{1}{2}", ReturnVarName = string.Format("{0}{1}{2}",
@class.IsValueType @class.IsValueType
? Helpers.InstanceField ? Helpers.InstanceField
: string.Format("((Internal*) {0})", Helpers.InstanceIdentifier), : string.Format("((Internal{0}*) {1})",
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier),
@class.IsValueType ? "." : "->", @class.IsValueType ? "." : "->",
Helpers.SafeIdentifier(name)), Helpers.SafeIdentifier(name)),
ReturnType = decl.QualifiedType ReturnType = decl.QualifiedType
@ -1421,10 +1421,11 @@ namespace CppSharp.Generators.CSharp
WriteLine("if (__OriginalVTables != null)"); WriteLine("if (__OriginalVTables != null)");
WriteLineIndent("return;"); WriteLineIndent("return;");
WriteLine("var native = (Internal*) {0}.ToPointer();", Helpers.InstanceIdentifier); WriteLine("var native = (Internal{0}*) {1}.ToPointer();",
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier);
NewLine(); NewLine();
SaveOriginalVTablePointers(@class.Layout.VTablePointers); SaveOriginalVTablePointers(@class);
NewLine(); NewLine();
@ -1491,16 +1492,19 @@ namespace CppSharp.Generators.CSharp
AllocateNewVTablesItanium(@class, wrappedEntries, destructorOnly); AllocateNewVTablesItanium(@class, wrappedEntries, destructorOnly);
} }
private void SaveOriginalVTablePointers(IList<LayoutField> vTablePtrs) private void SaveOriginalVTablePointers(Class @class)
{ {
var suffix = Helpers.GetSuffixForInternal(@class);
if (Driver.Options.IsMicrosoftAbi) if (Driver.Options.IsMicrosoftAbi)
WriteLine("__OriginalVTables = new void*[] {{ {0} }};", WriteLine("__OriginalVTables = new void*[] {{ {0} }};",
string.Join(", ", string.Join(", ",
vTablePtrs.Select(v => string.Format("((Internal*) native)->{0}.ToPointer()", v.Name)))); @class.Layout.VTablePointers.Select(v => string.Format(
"((Internal{0}*) native)->{1}.ToPointer()",
suffix, v.Name))));
else else
WriteLine( WriteLine(
"__OriginalVTables = new void*[] {{ ((Internal*) native)->{0}.ToPointer() }};", "__OriginalVTables = new void*[] {{ ((Internal{0}*) native)->{1}.ToPointer() }};",
vTablePtrs[0].Name); suffix, @class.Layout.VTablePointers[0].Name);
} }
private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries, private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries,
@ -1951,15 +1955,17 @@ 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);
if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0) if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0)
{ {
if (Options.IsMicrosoftAbi) if (Options.IsMicrosoftAbi)
for (var i = 0; i < @class.Layout.VTablePointers.Count; i++) for (var i = 0; i < @class.Layout.VTablePointers.Count; i++)
WriteLine("((Internal*) {0})->{1} = new global::System.IntPtr(__OriginalVTables[{2}]);", WriteLine("((Internal{0}*) {1})->{2} = new global::System.IntPtr(__OriginalVTables[{3}]);",
Helpers.InstanceIdentifier, @class.Layout.VTablePointers[i].Name, i); suffix, Helpers.InstanceIdentifier,
@class.Layout.VTablePointers[i].Name, i);
else else
WriteLine("((Internal*) {0})->{1} = new global::System.IntPtr(__OriginalVTables[0]);", WriteLine("((Internal{0}*) {1})->{2} = new global::System.IntPtr(__OriginalVTables[0]);",
Helpers.InstanceIdentifier, @class.Layout.VTablePointers[0].Name); suffix, Helpers.InstanceIdentifier, @class.Layout.VTablePointers[0].Name);
} }
} }
@ -2056,7 +2062,7 @@ namespace CppSharp.Generators.CSharp
} }
if (@class.IsAbstractImpl || hasVTables) if (@class.IsAbstractImpl || hasVTables)
SaveOriginalVTablePointers(@class.Layout.VTablePointers); SaveOriginalVTablePointers(@class);
if (setupVTables) if (setupVTables)
{ {
@ -2069,7 +2075,8 @@ namespace CppSharp.Generators.CSharp
} }
else else
{ {
WriteLine("{0} = *(Internal*) native;", Helpers.InstanceField); WriteLine("{0} = *(Internal{1}*) native;",
Helpers.InstanceField, Helpers.GetSuffixForInternal(@class));
} }
WriteCloseBraceIndent(); WriteCloseBraceIndent();
@ -2078,11 +2085,13 @@ namespace CppSharp.Generators.CSharp
private void GenerateNativeConstructorByValue(Class @class, string className, string ctorCall) private void GenerateNativeConstructorByValue(Class @class, string className, string ctorCall)
{ {
var internalSuffix = Helpers.GetSuffixForInternal(@class);
if (!@class.IsAbstractImpl) if (!@class.IsAbstractImpl)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("public static {0} {1}({0}.Internal native, bool skipVTables = false)", WriteLine("public static {0} {1}({0}.Internal{2} native, bool skipVTables = false)",
className, Helpers.CreateInstanceIdentifier); className, Helpers.CreateInstanceIdentifier, internalSuffix);
WriteStartBraceIndent(); WriteStartBraceIndent();
WriteLine("return new {0}(native, skipVTables);", ctorCall); WriteLine("return new {0}(native, skipVTables);", ctorCall);
WriteCloseBraceIndent(); WriteCloseBraceIndent();
@ -2092,7 +2101,8 @@ namespace CppSharp.Generators.CSharp
if (@class.IsRefType && !@class.IsAbstract) if (@class.IsRefType && !@class.IsAbstract)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("private static void* __CopyValue({0}.Internal native)", className); WriteLine("private static void* __CopyValue({0}.Internal{1} native)",
className, internalSuffix);
WriteStartBraceIndent(); WriteStartBraceIndent();
var copyCtorMethod = @class.Methods.FirstOrDefault(method => var copyCtorMethod = @class.Methods.FirstOrDefault(method =>
method.IsCopyConstructor); method.IsCopyConstructor);
@ -2100,15 +2110,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}.Internal.{1}(ret, new global::System.IntPtr(&native));", WriteLine("{0}.Internal{1}.{2}(ret, new global::System.IntPtr(&native));",
@class.Visit(TypePrinter), GetFunctionNativeIdentifier(copyCtorMethod)); @class.Visit(TypePrinter), Helpers.GetSuffixForInternal(@class),
GetFunctionNativeIdentifier(copyCtorMethod));
WriteLine("return ret.ToPointer();", className); WriteLine("return ret.ToPointer();", className);
} }
else else
{ {
WriteLine("var ret = Marshal.AllocHGlobal({1});", WriteLine("var ret = Marshal.AllocHGlobal({1});",
className, @class.Layout.Size); className, @class.Layout.Size);
WriteLine("*({0}.Internal*) ret = native;", className); WriteLine("*({0}.Internal{1}*) ret = native;",
className, Helpers.GetSuffixForInternal(@class));
WriteLine("return ret.ToPointer();"); WriteLine("return ret.ToPointer();");
} }
WriteCloseBraceIndent(); WriteCloseBraceIndent();
@ -2117,8 +2129,9 @@ namespace CppSharp.Generators.CSharp
if (!@class.IsAbstract) if (!@class.IsAbstract)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("{0} {1}({2}.Internal native, bool skipVTables = false)", WriteLine("{0} {1}({2}.Internal{3} native, bool skipVTables = false)",
@class.IsAbstractImpl ? "internal" : "private", @class.Name, className); @class.IsAbstractImpl ? "internal" : "private",
@class.Name, className, 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)
@ -2401,7 +2414,8 @@ 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 (*(Internal*) {0}).GetHashCode();", Helpers.InstanceIdentifier); WriteLine("return (*(Internal{0}*) {1}).GetHashCode();",
Helpers.GetSuffixForInternal(@class), Helpers.InstanceIdentifier);
} }
else else
{ {
@ -2559,8 +2573,9 @@ namespace CppSharp.Generators.CSharp
if (@class.HasNonTrivialCopyConstructor) if (@class.HasNonTrivialCopyConstructor)
GenerateInternalFunctionCall(method); GenerateInternalFunctionCall(method);
else else
WriteLine("*(({0}.Internal*) {2}) = *(({0}.Internal*) {1}.{2});", WriteLine("*(({0}.Internal{1}*) {3}) = *(({0}.Internal{1}*) {2}.{3});",
@class.Name, method.Parameters[0].Name, Helpers.InstanceIdentifier); @class.Name, Helpers.GetSuffixForInternal(@class),
method.Parameters[0].Name, Helpers.InstanceIdentifier);
} }
else else
{ {
@ -2583,7 +2598,8 @@ namespace CppSharp.Generators.CSharp
templateSpecialization.Ignore ? templateSpecialization.Ignore ?
(templateSpecialization.Namespace.OriginalName + '.') : string.Empty; (templateSpecialization.Namespace.OriginalName + '.') : string.Empty;
var functionName = string.Format("{0}Internal.{1}", @namespace, var functionName = string.Format("{0}Internal{1}.{2}", @namespace,
Helpers.GetSuffixForInternal(function.Namespace),
GetFunctionNativeIdentifier(function.OriginalFunction ?? function)); GetFunctionNativeIdentifier(function.OriginalFunction ?? function));
GenerateFunctionCall(functionName, parameters, function, returnType); GenerateFunctionCall(functionName, parameters, function, returnType);
} }
@ -2638,8 +2654,11 @@ namespace CppSharp.Generators.CSharp
if (construct == null) if (construct == null)
{ {
WriteLine("var {0} = new {1}.Internal();", Helpers.ReturnIdentifier, var @class = retClass.OriginalClass ?? retClass;
(retClass.OriginalClass ?? retClass).Visit(TypePrinter)); var specialization = @class as ClassTemplateSpecialization;
WriteLine("var {0} = new {1}.Internal{2}();", Helpers.ReturnIdentifier,
@class.Visit(TypePrinter),
Helpers.GetSuffixForInternal(@class));
} }
else else
{ {
@ -2697,7 +2716,8 @@ namespace CppSharp.Generators.CSharp
{ {
if (operatorParam == null) if (operatorParam == null)
{ {
WriteLine("fixed (Internal* __instancePtr = &{0})", Helpers.InstanceField); WriteLine("fixed (Internal{0}* __instancePtr = &{1})",
Helpers.GetSuffixForInternal(originalFunction.Namespace), Helpers.InstanceField);
WriteStartBraceIndent(); WriteStartBraceIndent();
} }
else else

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

@ -604,7 +604,7 @@ namespace CppSharp.Generators.CSharp
{ {
if (ContextKind == CSharpTypePrinterContextKind.Native) if (ContextKind == CSharpTypePrinterContextKind.Native)
return string.Format("{0}{1}", VisitClassDecl(specialization), return string.Format("{0}{1}", VisitClassDecl(specialization),
Helpers.GetSuffixForInternal(specialization, this)); Helpers.GetSuffixForInternal(specialization));
return VisitClassDecl(specialization); return VisitClassDecl(specialization);
} }

Loading…
Cancel
Save