diff --git a/src/Generator/Generators/ExtensionMethods.cs b/src/Generator/Generators/ExtensionMethods.cs index f629551a..b5adfde1 100644 --- a/src/Generator/Generators/ExtensionMethods.cs +++ b/src/Generator/Generators/ExtensionMethods.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using CppSharp.AST; using CppSharp.AST.Extensions; +using CppSharp.Types; using Interop = System.Runtime.InteropServices; namespace CppSharp.Generators @@ -46,5 +47,29 @@ namespace CppSharp.Generators return 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(); + } } } diff --git a/src/Generator/Passes/CheckAmbiguousFunctions.cs b/src/Generator/Passes/CheckAmbiguousFunctions.cs index 4ef8956d..f4776f49 100644 --- a/src/Generator/Passes/CheckAmbiguousFunctions.cs +++ b/src/Generator/Passes/CheckAmbiguousFunctions.cs @@ -78,8 +78,10 @@ namespace CppSharp.Passes var i = 0; for (; i < commonParameters; ++i) { - AST.Type funcType = GetFinalType(functionParams[i]); - AST.Type overloadType = GetFinalType(overloadParams[i]); + AST.Type funcType = functionParams[i].Type.GetMappedType( + TypeMaps, Options.GeneratorKind); + AST.Type overloadType = overloadParams[i].Type.GetMappedType( + TypeMaps, Options.GeneratorKind); AST.Type funcPointee = funcType.GetFinalPointee() ?? funcType; AST.Type overloadPointee = overloadType.GetFinalPointee() ?? overloadType; @@ -137,30 +139,6 @@ namespace CppSharp.Passes 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) { var method1 = function as Method; diff --git a/src/Generator/Passes/CheckDuplicatedNamesPass.cs b/src/Generator/Passes/CheckDuplicatedNamesPass.cs index 04490e09..c178cec2 100644 --- a/src/Generator/Passes/CheckDuplicatedNamesPass.cs +++ b/src/Generator/Passes/CheckDuplicatedNamesPass.cs @@ -6,6 +6,7 @@ using CppSharp.AST.Extensions; using CppSharp.Generators; using CppSharp.Generators.CLI; using CppSharp.Generators.CSharp; +using CppSharp.Types; namespace CppSharp.Passes { @@ -95,7 +96,11 @@ namespace CppSharp.Passes public class ParameterTypeComparer : IEqualityComparer { - 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) { @@ -107,10 +112,31 @@ namespace CppSharp.Passes // TODO: some target languages might make a difference between values and pointers Type leftPointee = left.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)) || (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) { return obj.Type.GetHashCode(); @@ -118,6 +144,28 @@ namespace CppSharp.Passes public static TypePrinter TypePrinter { get; set; } } + + public class TemplateArgumentComparer : IEqualityComparer + { + 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 @@ -143,6 +191,8 @@ namespace CppSharp.Passes break; } DeclarationName.ParameterTypeComparer.TypePrinter = typePrinter; + DeclarationName.ParameterTypeComparer.TypeMaps = Context.TypeMaps; + DeclarationName.ParameterTypeComparer.GeneratorKind = Options.GeneratorKind; return base.VisitASTContext(context); } diff --git a/tests/CSharp/CSharp.cs b/tests/CSharp/CSharp.cs index 646b6a4b..ee6eca88 100644 --- a/tests/CSharp/CSharp.cs +++ b/tests/CSharp/CSharp.cs @@ -248,6 +248,12 @@ namespace CppSharp.Tests { 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)); } diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index e21883b7..89a00e35 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -8,10 +8,6 @@ #include "AnotherUnit.h" #include "CSharpTemplates.h" -class DLL_API QString -{ -}; - class DLL_API Foo { public: diff --git a/tests/CSharp/CSharpTemplates.cpp b/tests/CSharp/CSharpTemplates.cpp index a42df9dd..a471e4fb 100644 --- a/tests/CSharp/CSharpTemplates.cpp +++ b/tests/CSharp/CSharpTemplates.cpp @@ -121,7 +121,8 @@ void TemplateSpecializer::completeSpecializationInParameter(DependentValueFields void TemplateSpecializer::completeSpecializationInParameter(TwoTemplateArgs p1, TwoTemplateArgs p2, TwoTemplateArgs p3, - TwoTemplateArgs p4) + TwoTemplateArgs p4, + TwoTemplateArgs p5) { } diff --git a/tests/CSharp/CSharpTemplates.h b/tests/CSharp/CSharpTemplates.h index 098bb5a7..38c28396 100644 --- a/tests/CSharp/CSharpTemplates.h +++ b/tests/CSharp/CSharpTemplates.h @@ -6,6 +6,10 @@ #include #include +class DLL_API QString +{ +}; + class DLL_API T1 { public: @@ -275,6 +279,11 @@ private: V value; }; +template +void TwoTemplateArgs::takeDependentPtrToSecondTemplateArg(const V& v) +{ +} + template > class DLL_API HasDefaultTemplateArgument { @@ -537,7 +546,8 @@ public: void completeSpecializationInParameter(TwoTemplateArgs p1, TwoTemplateArgs p2, TwoTemplateArgs p3, - TwoTemplateArgs p4); + TwoTemplateArgs p4, + TwoTemplateArgs p5); VirtualTemplate returnSpecializedWithVoid(); private: IndependentFields independentFields;