Browse Source

Fixed code generation for Itanium ABI instance/indirect return types methods in C#.

pull/225/head
triton 12 years ago
parent
commit
a6bd803a71
  1. 95
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs

95
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -710,7 +710,7 @@ namespace CppSharp.Generators.CSharp
baseClass = @class.Bases[0].Class; baseClass = @class.Bases[0].Class;
var hasRefBase = baseClass != null && baseClass.IsRefType var hasRefBase = baseClass != null && baseClass.IsRefType
&& !baseClass.ExplicityIgnored; && !baseClass.ExplicityIgnored;
return hasRefBase; return hasRefBase;
} }
@ -725,7 +725,7 @@ namespace CppSharp.Generators.CSharp
if (@class.IsUnion) if (@class.IsUnion)
WriteLine("[StructLayout(LayoutKind.Explicit)]"); WriteLine("[StructLayout(LayoutKind.Explicit)]");
Write(@class.Ignore ? "internal " : Helpers.GetAccess(@class.Access)); Write(@class.Ignore ? "internal " : Helpers.GetAccess(@class.Access));
Write("unsafe "); Write("unsafe ");
if (Driver.Options.GenerateAbstractImpls && @class.IsAbstract) if (Driver.Options.GenerateAbstractImpls && @class.IsAbstract)
@ -755,11 +755,11 @@ namespace CppSharp.Generators.CSharp
{ {
if (@class.IsRefType) if (@class.IsRefType)
bases.Add("IDisposable"); bases.Add("IDisposable");
if (Options.GenerateClassMarshals) if (Options.GenerateClassMarshals)
{ {
bases.Add("CppSharp.Runtime.ICppMarshal"); bases.Add("CppSharp.Runtime.ICppMarshal");
} }
} }
if (bases.Count > 0) if (bases.Count > 0)
@ -2228,19 +2228,18 @@ namespace CppSharp.Generators.CSharp
needsInstance = !method.IsStatic || operatorParam != null; needsInstance = !method.IsStatic || operatorParam != null;
} }
var needsFixedThis = needsInstance && isValueType;
var @params = GenerateFunctionParamsMarshal(parameters, function); var @params = GenerateFunctionParamsMarshal(parameters, function);
var originalFunction = function.OriginalFunction ?? function; var originalFunction = function.OriginalFunction ?? function;
if (originalFunction.HasIndirectReturnTypeParameter) if (originalFunction.HasIndirectReturnTypeParameter)
{ {
var hiddenParam = originalFunction.Parameters[0]; var indirectRetType = originalFunction.Parameters.First(
if (hiddenParam.Kind != ParameterKind.IndirectReturnType) parameter => parameter.Kind == ParameterKind.IndirectReturnType);
throw new NotSupportedException("Expected hidden structure parameter kind");
Class retClass; Class retClass;
hiddenParam.Type.Desugar().IsTagDecl(out retClass); indirectRetType.Type.Desugar().IsTagDecl(out retClass);
WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("ret"), WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("ret"),
QualifiedIdentifier(retClass.OriginalClass ?? retClass)); QualifiedIdentifier(retClass.OriginalClass ?? retClass));
} }
@ -2258,33 +2257,37 @@ namespace CppSharp.Generators.CSharp
name += param.Name; name += param.Name;
names.Add(name); names.Add(name);
}
var needsFixedThis = needsInstance && isValueType;
if (originalFunction.HasIndirectReturnTypeParameter)
{
var name = string.Format("new IntPtr(&{0})", GeneratedIdentifier("ret"));
names.Insert(0, name);
} }
if (originalFunction.HasIndirectReturnTypeParameter) if (needsInstance)
{ {
var name = string.Format("new IntPtr(&{0})", GeneratedIdentifier("ret")); var instanceIndex = GetInstanceParamIndex(function);
names.Insert(0, name);
}
if (needsInstance)
{
if (needsFixedThis) if (needsFixedThis)
{ {
names.Insert(0, string.Format("new global::System.IntPtr(&{0})", names.Insert(instanceIndex, string.Format("new global::System.IntPtr(&{0})",
GeneratedIdentifier("fixedInstance"))); GeneratedIdentifier("fixedInstance")));
} }
else else
{ {
if (operatorParam != null) if (operatorParam != null)
{ {
names.Insert(0, operatorParam.Name + "." + Helpers.InstanceIdentifier); names.Insert(instanceIndex, operatorParam.Name + "." + Helpers.InstanceIdentifier);
} }
else else
{ {
names.Insert(0, Helpers.InstanceIdentifier); names.Insert(instanceIndex, Helpers.InstanceIdentifier);
} }
} }
} }
if (needsFixedThis) if (needsFixedThis)
{ {
@ -2371,8 +2374,22 @@ namespace CppSharp.Generators.CSharp
? "return *{0};" ? "return *{0};"
: "return {0};", marshal.Context.Return); : "return {0};", marshal.Context.Return);
} }
} }
private int GetInstanceParamIndex(Function function)
{
var method = function as Method;
if (Options.IsMicrosoftAbi)
return 0;
var indirectReturnType = method.Parameters.FirstOrDefault(
parameter => parameter.Kind == ParameterKind.IndirectReturnType);
var indirectReturnTypeIndex = method.Parameters.IndexOf(indirectReturnType);
return indirectReturnTypeIndex >= 0 ? ++indirectReturnTypeIndex : 0;
}
private void GenerateFunctionCallOutParams(IEnumerable<ParamMarshal> @params, private void GenerateFunctionCallOutParams(IEnumerable<ParamMarshal> @params,
ICollection<TextGenerator> cleanups) ICollection<TextGenerator> cleanups)
{ {
@ -2685,14 +2702,20 @@ namespace CppSharp.Generators.CSharp
var retType = retParam.CSharpType(typePrinter); var retType = retParam.CSharpType(typePrinter);
var method = function as Method; var method = function as Method;
if (method != null && !method.IsStatic) var isInstanceMethod = method != null && !method.IsStatic;
if (isInstanceMethod && Options.IsMicrosoftAbi)
{ {
@params.Add("global::System.IntPtr instance"); @params.Add("global::System.IntPtr instance");
if (method.IsConstructor && Options.IsMicrosoftAbi) if (method.IsConstructor)
retType = "global::System.IntPtr"; retType = "global::System.IntPtr";
} }
if (!function.HasIndirectReturnTypeParameter &&
isInstanceMethod && Options.IsItaniumAbi)
@params.Add("global::System.IntPtr instance");
foreach (var param in function.Parameters) foreach (var param in function.Parameters)
{ {
if (param.Kind == ParameterKind.OperatorParameter) if (param.Kind == ParameterKind.OperatorParameter)
@ -2701,8 +2724,12 @@ namespace CppSharp.Generators.CSharp
var typeName = param.CSharpType(typePrinter); var typeName = param.CSharpType(typePrinter);
@params.Add(string.Format("{0} {1}", typeName, param.Name)); @params.Add(string.Format("{0} {1}", typeName, param.Name));
}
if (param.Kind == ParameterKind.IndirectReturnType &&
isInstanceMethod && Options.IsItaniumAbi)
@params.Add("global::System.IntPtr instance");
}
if (method != null && method.IsConstructor) if (method != null && method.IsConstructor)
{ {
var @class = method.Namespace as Class; var @class = method.Namespace as Class;

Loading…
Cancel
Save