Browse Source

Fixed the generated C# for templates with > 1 ctor taking a pointer to a class.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1125/head
Dimitar Dobrev 7 years ago
parent
commit
eec05041a3
  1. 2
      src/Generator/Driver.cs
  2. 7
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 56
      src/Generator/Passes/CheckDuplicatedNamesPass.cs
  4. 10
      tests/CSharp/CSharp.Tests.cs
  5. 12
      tests/CSharp/CSharpTemplates.h

2
src/Generator/Driver.cs

@ -234,9 +234,9 @@ namespace CppSharp
TranslationUnitPasses.AddPass(new CheckStaticClass()); TranslationUnitPasses.AddPass(new CheckStaticClass());
TranslationUnitPasses.AddPass(new MoveOperatorToClassPass()); TranslationUnitPasses.AddPass(new MoveOperatorToClassPass());
TranslationUnitPasses.AddPass(new MoveFunctionToClassPass()); TranslationUnitPasses.AddPass(new MoveFunctionToClassPass());
TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
TranslationUnitPasses.AddPass(new ConstructorToConversionOperatorPass()); TranslationUnitPasses.AddPass(new ConstructorToConversionOperatorPass());
TranslationUnitPasses.AddPass(new MarshalPrimitivePointersAsRefTypePass()); TranslationUnitPasses.AddPass(new MarshalPrimitivePointersAsRefTypePass());
TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
TranslationUnitPasses.AddPass(new CheckOperatorsOverloadsPass()); TranslationUnitPasses.AddPass(new CheckOperatorsOverloadsPass());
TranslationUnitPasses.AddPass(new CheckVirtualOverrideReturnCovariance()); TranslationUnitPasses.AddPass(new CheckVirtualOverrideReturnCovariance());
TranslationUnitPasses.AddPass(new CleanCommentsPass()); TranslationUnitPasses.AddPass(new CleanCommentsPass());

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

@ -2598,6 +2598,7 @@ namespace CppSharp.Generators.CSharp
{ {
// To avoid ambiguity when having the multiple inheritance pass enabled // To avoid ambiguity when having the multiple inheritance pass enabled
var paramType = method.Parameters[0].Type.SkipPointerRefs().Desugar(); var paramType = method.Parameters[0].Type.SkipPointerRefs().Desugar();
paramType = (paramType.GetPointee() ?? paramType).Desugar();
Class paramClass; Class paramClass;
Class @interface = null; Class @interface = null;
if (paramType.TryGetClass(out paramClass)) if (paramType.TryGetClass(out paramClass))
@ -3175,8 +3176,10 @@ namespace CppSharp.Generators.CSharp
var internalParams = function.GatherInternalParams( var internalParams = function.GatherInternalParams(
Context.ParserOptions.IsItaniumLikeAbi); Context.ParserOptions.IsItaniumLikeAbi);
var overloads = function.Namespace.GetOverloads(function) var overloads = function.Namespace.GetOverloads(function)
.Where(f => !f.Ignore && (isForDelegate || internalParams.SequenceEqual( .Where(f => (!f.Ignore ||
f.GatherInternalParams(Context.ParserOptions.IsItaniumLikeAbi), (f.OriginalFunction != null && !f.OriginalFunction.Ignore)) &&
(isForDelegate || internalParams.SequenceEqual(
f.GatherInternalParams(Context.ParserOptions.IsItaniumLikeAbi),
new MarshallingParamComparer()))).ToList(); new MarshallingParamComparer()))).ToList();
var index = -1; var index = -1;
if (overloads.Count > 1) if (overloads.Count > 1)

56
src/Generator/Passes/CheckDuplicatedNamesPass.cs

@ -2,24 +2,24 @@
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using CppSharp.AST; using CppSharp.AST;
using CppSharp.Generators; using CppSharp.AST.Extensions;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
class DeclarationName class DeclarationName
{ {
private readonly Dictionary<string, int> methodSignatures; private readonly Dictionary<Function, int> functions;
private int Count; private int Count;
public DeclarationName() public DeclarationName()
{ {
methodSignatures = new Dictionary<string, int>(); functions = new Dictionary<Function, int>();
} }
public bool UpdateName(Declaration decl) public bool UpdateName(Declaration decl)
{ {
var function = decl as Function; var function = decl as Function;
if (function != null && !(function.Namespace is ClassTemplateSpecialization)) if (function != null)
{ {
return UpdateName(function); return UpdateName(function);
} }
@ -50,19 +50,22 @@ namespace CppSharp.Passes
(method.OperatorKind == CXXOperatorKind.Conversion || (method.OperatorKind == CXXOperatorKind.Conversion ||
method.OperatorKind == CXXOperatorKind.ExplicitConversion)) method.OperatorKind == CXXOperatorKind.ExplicitConversion))
@params = @params.Concat(new[] { method.ConversionType.ToString() }); @params = @params.Concat(new[] { method.ConversionType.ToString() });
var signature = string.Format("{0}({1})", function.Name, string.Join( ", ", @params)); var signature = $"{function.Name}({string.Join(", ", @params)})";
signature = FixSignatureForConversions(function, signature); signature = FixSignatureForConversions(function, signature);
if (Count == 0) if (Count == 0)
Count++; Count++;
if (!methodSignatures.ContainsKey(signature)) var duplicate = functions.Keys.FirstOrDefault(f =>
f.Parameters.SequenceEqual(function.Parameters, ParameterTypeComparer.Instance));
if (duplicate == null)
{ {
methodSignatures.Add(signature, 0); functions.Add(function, 0);
return false; return false;
} }
var methodCount = ++methodSignatures[signature]; var methodCount = ++functions[duplicate];
if (Count < methodCount + 1) if (Count < methodCount + 1)
Count = methodCount + 1; Count = methodCount + 1;
@ -96,6 +99,34 @@ namespace CppSharp.Passes
} }
return signature; return signature;
} }
private class ParameterTypeComparer : IEqualityComparer<Parameter>
{
public static readonly ParameterTypeComparer Instance = new ParameterTypeComparer();
private ParameterTypeComparer()
{
}
public bool Equals(Parameter x, Parameter y)
{
Type left = x.Type.Desugar(resolveTemplateSubstitution: false);
Type right = y.Type.Desugar(resolveTemplateSubstitution: false);
if (left.Equals(right))
return true;
// TODO: some target languages might maek a difference between values and pointers
Type leftPointee = left.GetPointee();
Type rightPointee = right.GetPointee();
return (leftPointee != null && leftPointee.Desugar(false).Equals(right)) ||
(rightPointee != null && rightPointee.Desugar(false).Equals(left));
}
public int GetHashCode(Parameter obj)
{
return obj.Type.GetHashCode();
}
}
} }
public class CheckDuplicatedNamesPass : TranslationUnitPass public class CheckDuplicatedNamesPass : TranslationUnitPass
@ -180,15 +211,6 @@ namespace CppSharp.Passes
return false; return false;
} }
private static IEnumerable<Field> GetAllFields(Class @class, List<Field> fields = null)
{
fields = fields ?? new List<Field>();
foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class != @class))
GetAllFields(@base.Class, fields);
fields.AddRange(@class.Fields);
return fields;
}
private void CheckDuplicate(Declaration decl) private void CheckDuplicate(Declaration decl)
{ {
if (decl.IsDependent || !decl.IsGenerated) if (decl.IsDependent || !decl.IsGenerated)

10
tests/CSharp/CSharp.Tests.cs

@ -84,6 +84,16 @@ public unsafe class CSharpTests : GeneratorTestFixture
{ {
} }
using (var t1 = new T1())
using (new IndependentFields<int>(t1))
{
}
using (var t2 = new T2())
using (new IndependentFields<int>(t2))
{
}
#pragma warning restore 0168 #pragma warning restore 0168
#pragma warning restore 0219 #pragma warning restore 0219
} }

12
tests/CSharp/CSharpTemplates.h

@ -32,6 +32,8 @@ public:
IndependentFields(); IndependentFields();
IndependentFields(const IndependentFields<T>& other); IndependentFields(const IndependentFields<T>& other);
IndependentFields(const T& t); IndependentFields(const T& t);
IndependentFields(T1* t1);
IndependentFields(T2* t2);
IndependentFields(int i); IndependentFields(int i);
~IndependentFields(); ~IndependentFields();
explicit IndependentFields(const std::map<T, T> &other); explicit IndependentFields(const std::map<T, T> &other);
@ -66,6 +68,16 @@ IndependentFields<T>::IndependentFields(const T& t) : independent(1)
{ {
} }
template <typename T>
IndependentFields<T>::IndependentFields(T1* t1) : independent(1)
{
}
template <typename T>
IndependentFields<T>::IndependentFields(T2* t2) : independent(1)
{
}
template <typename T> template <typename T>
IndependentFields<T>::IndependentFields(int i) IndependentFields<T>::IndependentFields(int i)
{ {

Loading…
Cancel
Save