From 8c0c76ca596bf56d08b603649b399c36d3f9db9c Mon Sep 17 00:00:00 2001 From: triton Date: Wed, 21 Aug 2013 08:03:42 +0100 Subject: [PATCH] Reworked operator overloading support. --- .../Generators/CLI/CLIHeadersTemplate.cs | 7 +++- src/Generator/Generators/CLI/CLIMarshal.cs | 6 ++- .../Generators/CLI/CLISourcesTemplate.cs | 42 ++++++++++++------- .../Generators/CSharp/CSharpTextTemplate.cs | 10 +++-- tests/Basic/Basic.Tests.cs | 12 ++++-- tests/Basic/Basic.cpp | 8 ++++ tests/Basic/Basic.h | 2 + 7 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 7921073a..291c2309 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using CppSharp.AST; +using CppSharp.Generators.CSharp; using CppSharp.Types; namespace CppSharp.Generators.CLI @@ -512,7 +512,10 @@ namespace CppSharp.Generators.CLI if (method.IsVirtual || method.IsOverride) Write("virtual "); - if (method.IsStatic) + var isBuiltinOperator = method.IsOperator && + Operators.IsBuiltinOperator(method.OperatorKind); + + if (method.IsStatic || isBuiltinOperator) Write("static "); if (method.Kind == CXXMethodKind.Constructor || method.Kind == CXXMethodKind.Destructor) diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs index e9634456..a0bf70de 100644 --- a/src/Generator/Generators/CLI/CLIMarshal.cs +++ b/src/Generator/Generators/CLI/CLIMarshal.cs @@ -524,7 +524,11 @@ namespace CppSharp.Generators.CLI Context.Return.Write(marshalVar); - if (Context.Parameter.Type.IsPointer()) + var param = Context.Parameter; + if (param.Kind == ParameterKind.OperatorParameter) + return; + + if (param.Type.IsPointer()) ArgumentPrefix.Write("&"); } diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index 8f87ae90..5627e237 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -743,30 +743,37 @@ namespace CppSharp.Generators.CLI Write("auto {0}{1} = ",(function.ReturnType.Type.IsReference())? "&": string.Empty, Generator.GeneratedIdentifier("ret")); - if (!IsNativeFunctionOrStaticMethod(function)) + if (function.IsOperator) { - if (isValueType) + var kind = function.OperatorKind; + + var isBinary = function.Parameters.Count > 0; + var opName = function.Name.Replace("operator", "").Trim(); + + // Binary operator + if (isBinary) + WriteLine("{0} {1} {2};", @params[0].Name, opName, + @params[1].Name); + } + else + { + if (IsNativeFunctionOrStaticMethod(function)) { - Write("{0}.", valueMarshalName); + Write("::{0}(", function.QualifiedOriginalName); } - else if (IsNativeMethod(function)) + else { - Write("((::{0}*)NativePtr)->", @class.QualifiedOriginalName); + if (isValueType) + Write("{0}.", valueMarshalName); + else if (IsNativeMethod(function)) + Write("((::{0}*)NativePtr)->", @class.QualifiedOriginalName); + Write("{0}(", function.OriginalName); } - } - if (IsNativeFunctionOrStaticMethod(function)) - { - Write("::{0}(", function.QualifiedOriginalName); - } - else - { - Write("{0}(", function.OriginalName); + GenerateFunctionParams(@params); + WriteLine(");"); } - GenerateFunctionParams(@params); - WriteLine(");"); - foreach(var paramInfo in @params) { var param = paramInfo.Param; @@ -830,6 +837,9 @@ namespace CppSharp.Generators.CLI if (method == null) return true; + if (method.IsOperator && Operators.IsBuiltinOperator(method.OperatorKind)) + return true; + return method.IsStatic || method.Conversion != MethodConversionKind.None; } diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 7baddb71..74b97cf9 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1595,9 +1595,11 @@ namespace CppSharp.Generators.CSharp var needsFixedThis = needsInstance && isValueType; var @params = GenerateFunctionParamsMarshal(parameters, function); - if (function.HasIndirectReturnTypeParameter) + var originalFunction = function.OriginalFunction ?? function; + + if (originalFunction.HasIndirectReturnTypeParameter) { - var hiddenParam = function.Parameters[0]; + var hiddenParam = originalFunction.Parameters[0]; if (hiddenParam.Kind != ParameterKind.IndirectReturnType) throw new NotSupportedException("Expected hidden structure parameter kind"); @@ -1618,7 +1620,7 @@ namespace CppSharp.Generators.CSharp names.Add(name); } - if (function.HasIndirectReturnTypeParameter) + if (originalFunction.HasIndirectReturnTypeParameter) { var name = string.Format("new IntPtr(&{0})", GeneratedIdentifier("ret")); names.Insert(0, name); @@ -1638,7 +1640,7 @@ namespace CppSharp.Generators.CSharp WriteLine("var {0} = ToInternal();", Generator.GeneratedIdentifier("instance")); } - if (needsReturn && !function.HasIndirectReturnTypeParameter) + if (needsReturn && !originalFunction.HasIndirectReturnTypeParameter) Write("var {0} = ", GeneratedIdentifier("ret")); WriteLine("{0}({1});", functionName, string.Join(", ", names)); diff --git a/tests/Basic/Basic.Tests.cs b/tests/Basic/Basic.Tests.cs index fafa1a92..e4aaf48e 100644 --- a/tests/Basic/Basic.Tests.cs +++ b/tests/Basic/Basic.Tests.cs @@ -28,7 +28,7 @@ public class BasicTests Assert.That(retFoo.A, Is.EqualTo(7)); Assert.That(retFoo.B, Is.EqualTo(2.0)); - var foo2 = new Foo2 {A = 4, B = 2, C = 3}; + var foo2 = new Foo2 { A = 4, B = 2, C = 3 }; Assert.That(hello.AddFoo(foo2), Is.EqualTo(6)); Assert.That(hello.AddFoo2(foo2), Is.EqualTo(9)); @@ -43,10 +43,14 @@ public class BasicTests Assert.That(hello.RetEnum(Enum.F), Is.EqualTo(-9)); } - static void Main(string[] args) + [Test] + public void TestFunctionOperator() { - var hello = new Hello(); - hello.RetFoo(7, 2.0f); + var bar = new Bar { A = 4, B = 7 }; + var bar1 = new Bar { A = 5, B = 10 }; + var barSum = bar + bar1; + Assert.That(barSum.A, Is.EqualTo(bar.A + bar1.A)); + Assert.That(barSum.B, Is.EqualTo(bar.B + bar1.B)); } } \ No newline at end of file diff --git a/tests/Basic/Basic.cpp b/tests/Basic/Basic.cpp index 4b01f651..5e3bbfe0 100644 --- a/tests/Basic/Basic.cpp +++ b/tests/Basic/Basic.cpp @@ -75,3 +75,11 @@ int unsafeFunction(const Bar& ret) { return ret.A; } + +Bar operator+(const Bar& b1, const Bar& b2) +{ + Bar b; + b.A = b1.A + b2.A; + b.B = b1.B + b2.B; + return b; +} \ No newline at end of file diff --git a/tests/Basic/Basic.h b/tests/Basic/Basic.h index 079be9bd..1158d450 100644 --- a/tests/Basic/Basic.h +++ b/tests/Basic/Basic.h @@ -71,4 +71,6 @@ public: int RetEnum(Enum); }; +DLL_API Bar operator+(const Bar &, const Bar &); + int DLL_API unsafeFunction(const Bar& ret);