Browse Source

Fixed the generated C# when a template interface specialised with another specialisation returns a template parameter.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1033/head
Dimitar Dobrev 8 years ago
parent
commit
10c8211a7c
  1. 1
      src/AST/Function.cs
  2. 2
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 76
      src/Generator/Passes/ParamTypeToInterfacePass.cs
  4. 17
      tests/CSharp/CSharpTemplates.h

1
src/AST/Function.cs

@ -157,6 +157,7 @@ namespace CppSharp.AST @@ -157,6 +157,7 @@ namespace CppSharp.AST
Parameters.AddRange(function.Parameters.Select(p => new Parameter(p)));
foreach (var parameter in Parameters)
parameter.Namespace = this;
InstantiatedFrom = function.InstantiatedFrom;
IsVariadic = function.IsVariadic;
IsInline = function.IsInline;
IsPure = function.IsPure;

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

@ -1206,7 +1206,7 @@ namespace CppSharp.Generators.CSharp @@ -1206,7 +1206,7 @@ namespace CppSharp.Generators.CSharp
{
var final = field.Type.GetFinalPointee().Desugar(resolveTemplateSubstitution: false);
var templateSubstitution = final as TemplateParameterSubstitutionType;
if (templateSubstitution != null)
if (templateSubstitution != null && returnType.Type.IsDependent)
Write($"({templateSubstitution.ReplacedParameter.Parameter.Name}) (object) ");
if ((final.IsPrimitiveType() && !final.IsPrimitiveType(PrimitiveType.Void) &&
(!final.IsPrimitiveType(PrimitiveType.Char) &&

76
src/Generator/Passes/ParamTypeToInterfacePass.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
@ -21,7 +22,13 @@ namespace CppSharp.Passes @@ -21,7 +22,13 @@ namespace CppSharp.Passes
if (!base.VisitFunctionDecl(function))
return false;
if (!function.IsOperator || function.Parameters.Count > 1)
// parameters and returns from a specialised interface
// must not be replaced if the templated interface uses a template parameter
Function templateInterfaceFunction = GetTemplateInterfaceFunction(function);
if ((!function.IsOperator || function.Parameters.Count > 1) &&
(templateInterfaceFunction == null ||
!IsTemplateParameter(templateInterfaceFunction.OriginalReturnType)))
{
var originalReturnType = function.OriginalReturnType;
ChangeToInterfaceType(ref originalReturnType);
@ -30,13 +37,27 @@ namespace CppSharp.Passes @@ -30,13 +37,27 @@ namespace CppSharp.Passes
if (function.OperatorKind != CXXOperatorKind.Conversion &&
function.OperatorKind != CXXOperatorKind.ExplicitConversion)
foreach (var parameter in function.Parameters.Where(
p => p.Kind != ParameterKind.OperatorParameter))
{
IList<Parameter> parameters = function.Parameters.Where(
p => p.Kind != ParameterKind.OperatorParameter &&
p.Kind != ParameterKind.IndirectReturnType).ToList();
var templateFunctionParameters = new List<Parameter>();
if (templateInterfaceFunction != null)
templateFunctionParameters.AddRange(
templateInterfaceFunction.Parameters.Where(
p => p.Kind != ParameterKind.OperatorParameter &&
p.Kind != ParameterKind.IndirectReturnType));
for (int i = 0; i < parameters.Count; i++)
{
var qualifiedType = parameter.QualifiedType;
if (templateFunctionParameters.Any() &&
IsTemplateParameter(templateFunctionParameters[i].QualifiedType))
continue;
var qualifiedType = parameters[i].QualifiedType;
ChangeToInterfaceType(ref qualifiedType);
parameter.QualifiedType = qualifiedType;
parameters[i].QualifiedType = qualifiedType;
}
}
return true;
}
@ -46,12 +67,55 @@ namespace CppSharp.Passes @@ -46,12 +67,55 @@ namespace CppSharp.Passes
if (!base.VisitProperty(property))
return false;
var templateInterfaceProperty = GetTemplateInterfaceProperty(property);
if (templateInterfaceProperty != null &&
IsTemplateParameter(templateInterfaceProperty.QualifiedType))
return false;
var type = property.QualifiedType;
ChangeToInterfaceType(ref type);
property.QualifiedType = type;
return true;
}
private static Function GetTemplateInterfaceFunction(Function function)
{
Function templateInterfaceFunction = null;
Class @class = function.OriginalNamespace as Class;
if (@class != null && @class.IsInterface)
templateInterfaceFunction = @class.Methods.First(
m => m.OriginalFunction == function.OriginalFunction).InstantiatedFrom;
return templateInterfaceFunction;
}
private static Property GetTemplateInterfaceProperty(Property property)
{
if (property.GetMethod != null &&
property.GetMethod.SynthKind == FunctionSynthKind.InterfaceInstance)
return null;
Property templateInterfaceProperty = null;
Class @class = property.OriginalNamespace as Class;
if (@class != null && @class.IsInterface)
{
var specialization = @class as ClassTemplateSpecialization;
if (specialization != null)
{
Class template = specialization.TemplatedDecl.TemplatedClass;
templateInterfaceProperty = template.Properties.FirstOrDefault(
p => p.Name == property.Name);
}
}
return templateInterfaceProperty;
}
private static bool IsTemplateParameter(QualifiedType type)
{
return (type.Type.Desugar().GetFinalPointee() ?? type.Type).Desugar() is TemplateParameterType;
}
private static void ChangeToInterfaceType(ref QualifiedType type)
{
var finalType = (type.Type.GetFinalPointee() ?? type.Type).Desugar();

17
tests/CSharp/CSharpTemplates.h

@ -220,6 +220,8 @@ class DLL_API DependentPointerFields @@ -220,6 +220,8 @@ class DLL_API DependentPointerFields
public:
DependentPointerFields();
~DependentPointerFields();
T property();
T takeField(T t);
T* field;
};
@ -233,6 +235,18 @@ DependentPointerFields<T>::~DependentPointerFields() @@ -233,6 +235,18 @@ DependentPointerFields<T>::~DependentPointerFields()
{
}
template <typename T>
T DependentPointerFields<T>::property()
{
return *field;
}
template <typename T>
T DependentPointerFields<T>::takeField(T t)
{
return *field;
}
template <typename K, typename V>
class TwoTemplateArgs
{
@ -463,7 +477,8 @@ public: @@ -463,7 +477,8 @@ public:
~SpecializedInterfaceForMap();
};
class DLL_API HasSpecializationForSecondaryBase : T1, DependentValueFields<int>, IndependentFields<int>, InternalWithExtension<float>
class DLL_API HasSpecializationForSecondaryBase : T1, DependentValueFields<int>, IndependentFields<int>,
InternalWithExtension<float>, DependentPointerFields<DependentValueFields<int>>
{
public:
HasSpecializationForSecondaryBase();

Loading…
Cancel
Save