Browse Source

Fix the generated C# when type arguments are mapped the same

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1204/head
Dimitar Dobrev 7 years ago committed by João Matos
parent
commit
6e78b4df15
  1. 25
      src/Generator/Generators/ExtensionMethods.cs
  2. 30
      src/Generator/Passes/CheckAmbiguousFunctions.cs
  3. 52
      src/Generator/Passes/CheckDuplicatedNamesPass.cs
  4. 6
      tests/CSharp/CSharp.cs
  5. 4
      tests/CSharp/CSharp.h
  6. 3
      tests/CSharp/CSharpTemplates.cpp
  7. 12
      tests/CSharp/CSharpTemplates.h

25
src/Generator/Generators/ExtensionMethods.cs

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.AST.Extensions; using CppSharp.AST.Extensions;
using CppSharp.Types;
using Interop = System.Runtime.InteropServices; using Interop = System.Runtime.InteropServices;
namespace CppSharp.Generators namespace CppSharp.Generators
@ -46,5 +47,29 @@ namespace CppSharp.Generators
return type.IsPointerToPrimitiveType() && return type.IsPointerToPrimitiveType() &&
allowedToHaveDefaultPtrVals.Any(type.IsPointerToPrimitiveType); allowedToHaveDefaultPtrVals.Any(type.IsPointerToPrimitiveType);
} }
public static Type GetMappedType(this Type type, TypeMapDatabase typeMaps,
GeneratorKind generatorKind)
{
TypeMap typeMap;
if (typeMaps.FindTypeMap(type, out typeMap))
{
var typePrinterContext = new TypePrinterContext
{
Kind = TypePrinterContextKind.Managed,
Type = typeMap.Type
};
switch (generatorKind)
{
case GeneratorKind.CLI:
return typeMap.CLISignatureType(typePrinterContext).Desugar();
case GeneratorKind.CSharp:
return typeMap.CSharpSignatureType(typePrinterContext).Desugar();
}
}
return type.Desugar();
}
} }
} }

30
src/Generator/Passes/CheckAmbiguousFunctions.cs

@ -78,8 +78,10 @@ namespace CppSharp.Passes
var i = 0; var i = 0;
for (; i < commonParameters; ++i) for (; i < commonParameters; ++i)
{ {
AST.Type funcType = GetFinalType(functionParams[i]); AST.Type funcType = functionParams[i].Type.GetMappedType(
AST.Type overloadType = GetFinalType(overloadParams[i]); TypeMaps, Options.GeneratorKind);
AST.Type overloadType = overloadParams[i].Type.GetMappedType(
TypeMaps, Options.GeneratorKind);
AST.Type funcPointee = funcType.GetFinalPointee() ?? funcType; AST.Type funcPointee = funcType.GetFinalPointee() ?? funcType;
AST.Type overloadPointee = overloadType.GetFinalPointee() ?? overloadType; AST.Type overloadPointee = overloadType.GetFinalPointee() ?? overloadType;
@ -137,30 +139,6 @@ namespace CppSharp.Passes
return functionParams; return functionParams;
} }
private AST.Type GetFinalType(Parameter parameter)
{
TypeMap typeMap;
if (Context.TypeMaps.FindTypeMap(parameter.Type, out typeMap))
{
var typePrinterContext = new TypePrinterContext
{
Kind = TypePrinterContextKind.Managed,
Parameter = parameter,
Type = typeMap.Type
};
switch (Options.GeneratorKind)
{
case Generators.GeneratorKind.CLI:
return typeMap.CLISignatureType(typePrinterContext).Desugar();
case Generators.GeneratorKind.CSharp:
return typeMap.CSharpSignatureType(typePrinterContext).Desugar();
}
}
return parameter.Type.Desugar();
}
private static bool CheckConstnessForAmbiguity(Function function, Function overload) private static bool CheckConstnessForAmbiguity(Function function, Function overload)
{ {
var method1 = function as Method; var method1 = function as Method;

52
src/Generator/Passes/CheckDuplicatedNamesPass.cs

@ -6,6 +6,7 @@ using CppSharp.AST.Extensions;
using CppSharp.Generators; using CppSharp.Generators;
using CppSharp.Generators.CLI; using CppSharp.Generators.CLI;
using CppSharp.Generators.CSharp; using CppSharp.Generators.CSharp;
using CppSharp.Types;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
@ -95,7 +96,11 @@ namespace CppSharp.Passes
public class ParameterTypeComparer : IEqualityComparer<Parameter> public class ParameterTypeComparer : IEqualityComparer<Parameter>
{ {
public static readonly ParameterTypeComparer Instance = new ParameterTypeComparer(); public static readonly ParameterTypeComparer Instance =
new ParameterTypeComparer();
public static TypeMapDatabase TypeMaps { get; set; }
public static GeneratorKind GeneratorKind { get; set; }
public bool Equals(Parameter x, Parameter y) public bool Equals(Parameter x, Parameter y)
{ {
@ -107,10 +112,31 @@ namespace CppSharp.Passes
// TODO: some target languages might make a difference between values and pointers // TODO: some target languages might make a difference between values and pointers
Type leftPointee = left.GetPointee(); Type leftPointee = left.GetPointee();
Type rightPointee = right.GetPointee(); Type rightPointee = right.GetPointee();
if (CheckForSpecializations(leftPointee, rightPointee))
return true;
if (leftPointee != null && rightPointee != null &&
leftPointee.GetMappedType(TypeMaps, GeneratorKind).Equals(
rightPointee.GetMappedType(TypeMaps, GeneratorKind)))
return true;
return (leftPointee != null && leftPointee.Desugar(false).Equals(right)) || return (leftPointee != null && leftPointee.Desugar(false).Equals(right)) ||
(rightPointee != null && rightPointee.Desugar(false).Equals(left)); (rightPointee != null && rightPointee.Desugar(false).Equals(left));
} }
private static bool CheckForSpecializations(Type leftPointee, Type rightPointee)
{
ClassTemplateSpecialization leftSpecialization;
ClassTemplateSpecialization rightSpecialization;
return leftPointee.TryGetDeclaration(out leftSpecialization) &&
rightPointee.TryGetDeclaration(out rightSpecialization) &&
leftSpecialization.TemplatedDecl.TemplatedDecl.Equals(
rightSpecialization.TemplatedDecl.TemplatedDecl) &&
leftSpecialization.Arguments.SequenceEqual(
rightSpecialization.Arguments, TemplateArgumentComparer.Instance);
}
public int GetHashCode(Parameter obj) public int GetHashCode(Parameter obj)
{ {
return obj.Type.GetHashCode(); return obj.Type.GetHashCode();
@ -118,6 +144,28 @@ namespace CppSharp.Passes
public static TypePrinter TypePrinter { get; set; } public static TypePrinter TypePrinter { get; set; }
} }
public class TemplateArgumentComparer : IEqualityComparer<TemplateArgument>
{
public static readonly TemplateArgumentComparer Instance =
new TemplateArgumentComparer();
public bool Equals(TemplateArgument x, TemplateArgument y)
{
if (x.Kind != TemplateArgument.ArgumentKind.Type ||
y.Kind != TemplateArgument.ArgumentKind.Type)
return x.Equals(y);
return x.Type.Type.GetMappedType(ParameterTypeComparer.TypeMaps,
ParameterTypeComparer.GeneratorKind).Equals(
y.Type.Type.GetMappedType(ParameterTypeComparer.TypeMaps,
ParameterTypeComparer.GeneratorKind));
}
public int GetHashCode(TemplateArgument obj)
{
return obj.GetHashCode();
}
}
} }
public class CheckDuplicatedNamesPass : TranslationUnitPass public class CheckDuplicatedNamesPass : TranslationUnitPass
@ -143,6 +191,8 @@ namespace CppSharp.Passes
break; break;
} }
DeclarationName.ParameterTypeComparer.TypePrinter = typePrinter; DeclarationName.ParameterTypeComparer.TypePrinter = typePrinter;
DeclarationName.ParameterTypeComparer.TypeMaps = Context.TypeMaps;
DeclarationName.ParameterTypeComparer.GeneratorKind = Options.GeneratorKind;
return base.VisitASTContext(context); return base.VisitASTContext(context);
} }

6
tests/CSharp/CSharp.cs

@ -248,6 +248,12 @@ namespace CppSharp.Tests
{ {
public override Type CSharpSignatureType(TypePrinterContext ctx) public override Type CSharpSignatureType(TypePrinterContext ctx)
{ {
if (ctx.Kind == TypePrinterContextKind.Native)
{
return new CustomType($@"global::CSharp.QString.{
Helpers.InternalStruct}{
(ctx.Type.IsAddress() ? "*" : string.Empty)}");
}
return new CILType(typeof(string)); return new CILType(typeof(string));
} }

4
tests/CSharp/CSharp.h

@ -8,10 +8,6 @@
#include "AnotherUnit.h" #include "AnotherUnit.h"
#include "CSharpTemplates.h" #include "CSharpTemplates.h"
class DLL_API QString
{
};
class DLL_API Foo class DLL_API Foo
{ {
public: public:

3
tests/CSharp/CSharpTemplates.cpp

@ -121,7 +121,8 @@ void TemplateSpecializer::completeSpecializationInParameter(DependentValueFields
void TemplateSpecializer::completeSpecializationInParameter(TwoTemplateArgs<int *, int *> p1, void TemplateSpecializer::completeSpecializationInParameter(TwoTemplateArgs<int *, int *> p1,
TwoTemplateArgs<int *, int> p2, TwoTemplateArgs<int *, int> p2,
TwoTemplateArgs<int *, float> p3, TwoTemplateArgs<int *, float> p3,
TwoTemplateArgs<const char *, int> p4) TwoTemplateArgs<const char *, int> p4,
TwoTemplateArgs<QString, int> p5)
{ {
} }

12
tests/CSharp/CSharpTemplates.h

@ -6,6 +6,10 @@
#include <string> #include <string>
#include <map> #include <map>
class DLL_API QString
{
};
class DLL_API T1 class DLL_API T1
{ {
public: public:
@ -275,6 +279,11 @@ private:
V value; V value;
}; };
template <typename K, typename V>
void TwoTemplateArgs<K, V>::takeDependentPtrToSecondTemplateArg(const V& v)
{
}
template <typename T, typename D = IndependentFields<T>> template <typename T, typename D = IndependentFields<T>>
class DLL_API HasDefaultTemplateArgument class DLL_API HasDefaultTemplateArgument
{ {
@ -537,7 +546,8 @@ public:
void completeSpecializationInParameter(TwoTemplateArgs<int*, int*> p1, void completeSpecializationInParameter(TwoTemplateArgs<int*, int*> p1,
TwoTemplateArgs<int*, int> p2, TwoTemplateArgs<int*, int> p2,
TwoTemplateArgs<int*, float> p3, TwoTemplateArgs<int*, float> p3,
TwoTemplateArgs<const char*, int> p4); TwoTemplateArgs<const char*, int> p4,
TwoTemplateArgs<QString, int> p5);
VirtualTemplate<void> returnSpecializedWithVoid(); VirtualTemplate<void> returnSpecializedWithVoid();
private: private:
IndependentFields<int> independentFields; IndependentFields<int> independentFields;

Loading…
Cancel
Save