Browse Source

Rework the handling for functions that need hidden structure parameters.

The main changes are:
 - The original return type is now kept as the type of the generated parameter
 - The return type of the function is set to void to represent what is actually happening.

This also fixes a bunch of bugs related due to using the wrong return type in some places.
pull/28/head
triton 12 years ago
parent
commit
3e505737d7
  1. 14
      src/AST/Function.cs
  2. 54
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 5
      src/Generator/Passes/CheckAbiParameters.cs

14
src/AST/Function.cs

@ -102,6 +102,20 @@ namespace CppSharp.AST
} }
} }
public QualifiedType OriginalReturnType
{
get
{
if (!HasHiddenStructParameter)
return ReturnType;
var hiddenParam = Parameters.Single(param =>
param.Kind == ParameterKind.HiddenStructureReturn);
return hiddenParam.QualifiedType;
}
}
public string Mangled { get; set; } public string Mangled { get; set; }
public override T Visit<T>(IDeclVisitor<T> visitor) public override T Visit<T>(IDeclVisitor<T> visitor)

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

@ -1432,7 +1432,7 @@ namespace CppSharp.Generators.CSharp
if (method.IsConstructor || method.IsDestructor) if (method.IsConstructor || method.IsDestructor)
Write("{0}(", functionName); Write("{0}(", functionName);
else else
Write("{0} {1}(", method.ReturnType, functionName); Write("{0} {1}(", method.OriginalReturnType, functionName);
GenerateMethodParameters(method); GenerateMethodParameters(method);
@ -1557,14 +1557,13 @@ namespace CppSharp.Generators.CSharp
return; return;
} }
var retType = function.ReturnType; var retType = function.OriginalReturnType;
var needsReturn = !retType.Type.IsPrimitiveType(PrimitiveType.Void); var needsReturn = !retType.Type.IsPrimitiveType(PrimitiveType.Void);
var method = function as Method;
var isValueType = false; var isValueType = false;
var needsInstance = false; var needsInstance = false;
var method = function as Method;
if (method != null) if (method != null)
{ {
var @class = (Class) method.Namespace; var @class = (Class) method.Namespace;
@ -1585,10 +1584,14 @@ namespace CppSharp.Generators.CSharp
Class retClass = null; Class retClass = null;
if (function.HasHiddenStructParameter) if (function.HasHiddenStructParameter)
{ {
function.ReturnType.Type.Desugar().IsTagDecl(out retClass); var hiddenParam = function.Parameters[0];
if (hiddenParam.Kind != ParameterKind.HiddenStructureReturn)
throw new NotSupportedException("Expected hidden structure parameter kind");
hiddenParam.Type.Desugar().IsTagDecl(out retClass);
WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("udt"), WriteLine("var {0} = new {1}.Internal();", GeneratedIdentifier("udt"),
retClass.OriginalName); retClass.OriginalName);
}
retType.Type = new BuiltinType(PrimitiveType.Void); retType.Type = new BuiltinType(PrimitiveType.Void);
needsReturn = false; needsReturn = false;
@ -1620,7 +1623,7 @@ namespace CppSharp.Generators.CSharp
WriteLine("var {0} = ToInternal();", Helpers.GeneratedIdentifier("instance")); WriteLine("var {0} = ToInternal();", Helpers.GeneratedIdentifier("instance"));
} }
if (needsReturn) if (needsReturn && !function.HasHiddenStructParameter)
Write("var ret = "); Write("var ret = ");
WriteLine("{0}({1});", functionName, string.Join(", ", names)); WriteLine("{0}({1});", functionName, string.Join(", ", names));
@ -1650,28 +1653,30 @@ namespace CppSharp.Generators.CSharp
if (needsReturn) if (needsReturn)
{ {
var ctx = new CSharpMarshalContext(Driver) if (function.HasHiddenStructParameter)
{ {
ArgName = "ret", WriteLine("var ret = new {0}({1});", retClass.Name,
ReturnVarName = "ret", GeneratedIdentifier("udt"));
ReturnType = retType
};
var marshal = new CSharpMarshalNativeToManagedPrinter(ctx);
function.ReturnType.Type.Visit(marshal, function.ReturnType.Qualifiers);
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) WriteLine("return ret;");
Write(marshal.Context.SupportBefore); }
else
{
var ctx = new CSharpMarshalContext(Driver)
{
ArgName = "ret",
ReturnVarName = "ret",
ReturnType = retType
};
WriteLine("return {0};", marshal.Context.Return); var marshal = new CSharpMarshalNativeToManagedPrinter(ctx);
} function.ReturnType.Type.Visit(marshal, function.ReturnType.Qualifiers);
if (function.HasHiddenStructParameter) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
{ Write(marshal.Context.SupportBefore);
WriteLine("var ret = new {0}({1});", retClass.Name,
GeneratedIdentifier("udt"));
WriteLine("return ret;"); WriteLine("return {0};", marshal.Context.Return);
}
} }
} }
@ -1737,6 +1742,9 @@ namespace CppSharp.Generators.CSharp
var paramIndex = 0; var paramIndex = 0;
foreach (var param in @params) foreach (var param in @params)
{ {
if (param.Kind == ParameterKind.HiddenStructureReturn)
continue;
marshals.Add(GenerateFunctionParamMarshal(param, paramIndex, function)); marshals.Add(GenerateFunctionParamMarshal(param, paramIndex, function));
paramIndex++; paramIndex++;
} }

5
src/Generator/Passes/CheckAbiParameters.cs

@ -19,13 +19,12 @@ namespace CppSharp.Passes
var structParameter = new Parameter() var structParameter = new Parameter()
{ {
Kind = ParameterKind.HiddenStructureReturn, Kind = ParameterKind.HiddenStructureReturn,
QualifiedType = new QualifiedType( QualifiedType = method.ReturnType,
new BuiltinType(PrimitiveType.IntPtr)),
Name = "return", Name = "return",
IgnoreFlags = IgnoreFlags.Generation
}; };
method.Parameters.Insert(0, structParameter); method.Parameters.Insert(0, structParameter);
method.ReturnType = new QualifiedType(new BuiltinType(PrimitiveType.Void));
return true; return true;
} }

Loading…
Cancel
Save