From 19f3400cff99b9c5efccca1742a3a4b61f2efcb8 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Thu, 25 Dec 2014 15:09:42 +0200 Subject: [PATCH] Extended the generation of implicit ctors. Signed-off-by: Dimitar Dobrev --- .../Passes/CheckOperatorsOverloads.cs | 25 +++++---- .../ConstructorToConversionOperatorPass.cs | 52 +++++++++++-------- tests/CSharpTemp/CSharpTemp.Tests.cs | 10 ++++ tests/CSharpTemp/CSharpTemp.cpp | 11 ++++ tests/CSharpTemp/CSharpTemp.h | 4 ++ 5 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/Generator/Passes/CheckOperatorsOverloads.cs b/src/Generator/Passes/CheckOperatorsOverloads.cs index c4946f71..0cc69788 100644 --- a/src/Generator/Passes/CheckOperatorsOverloads.cs +++ b/src/Generator/Passes/CheckOperatorsOverloads.cs @@ -71,18 +71,21 @@ namespace CppSharp.Passes if (@operator.IsStatic) @operator.Parameters = @operator.Parameters.Skip(1).ToList(); - var type = new PointerType + if (@operator.ConversionType.Type == null || @operator.Parameters.Count == 0) { - QualifiedPointee = new QualifiedType(new TagType(@class)), - Modifier = PointerType.TypeModifier.LVReference - }; - - @operator.Parameters.Insert(0, new Parameter - { - Name = Generator.GeneratedIdentifier("op"), - QualifiedType = new QualifiedType(type), - Kind = ParameterKind.OperatorParameter - }); + var type = new PointerType + { + QualifiedPointee = new QualifiedType(new TagType(@class)), + Modifier = PointerType.TypeModifier.LVReference + }; + + @operator.Parameters.Insert(0, new Parameter + { + Name = Generator.GeneratedIdentifier("op"), + QualifiedType = new QualifiedType(type), + Kind = ParameterKind.OperatorParameter + }); + } } } } diff --git a/src/Generator/Passes/ConstructorToConversionOperatorPass.cs b/src/Generator/Passes/ConstructorToConversionOperatorPass.cs index b43bb40e..22488d99 100644 --- a/src/Generator/Passes/ConstructorToConversionOperatorPass.cs +++ b/src/Generator/Passes/ConstructorToConversionOperatorPass.cs @@ -1,5 +1,4 @@ -using System.Linq; -using CppSharp.AST; +using CppSharp.AST; using CppSharp.AST.Extensions; namespace CppSharp.Passes @@ -19,38 +18,45 @@ namespace CppSharp.Passes if (method.Parameters.Count != 1) return false; var parameter = method.Parameters[0]; - var parameterType = parameter.Type as PointerType; - if (parameterType == null) - return false; - if (!parameterType.IsReference) - return false; - var qualifiedPointee = parameterType.QualifiedPointee; + // TODO: disable implicit operators for C++/CLI because they seem not to be support parameters + if (!Driver.Options.IsCSharpGenerator) + { + var pointerType = parameter.Type as PointerType; + if (pointerType != null && !pointerType.IsReference) + return false; + } + var qualifiedPointee = parameter.Type.SkipPointerRefs(); Class castFromClass; - if (!qualifiedPointee.Type.TryGetClass(out castFromClass)) - return false; - var castToClass = method.OriginalNamespace as Class; - if (castToClass == null) - return false; - if (castFromClass == castToClass) - return false; + if (qualifiedPointee.TryGetClass(out castFromClass)) + { + var castToClass = method.OriginalNamespace as Class; + if (castToClass == null) + return false; + if (castFromClass == castToClass) + return false; + } var operatorKind = method.IsExplicit ? CXXOperatorKind.ExplicitConversion : CXXOperatorKind.Conversion; - var castToType = new TagType(castToClass); - var qualifiedCastToType = new QualifiedType(castToType); - var conversionOperator = new Method() + var qualifiedCastToType = new QualifiedType(new TagType(method.Namespace)); + var conversionOperator = new Method { Name = Operators.GetOperatorIdentifier(operatorKind), - Namespace = castFromClass, + Namespace = method.Namespace, Kind = CXXMethodKind.Conversion, SynthKind = FunctionSynthKind.ComplementOperator, ConversionType = qualifiedCastToType, - ReturnType = qualifiedCastToType + ReturnType = qualifiedCastToType, + OperatorKind = operatorKind }; - conversionOperator.OperatorKind = operatorKind; - - castFromClass.Methods.Add(conversionOperator); + var p = new Parameter(parameter); + Class @class; + if (p.Type.SkipPointerRefs().TryGetClass(out @class)) + p.QualifiedType = new QualifiedType(new TagType(@class), parameter.QualifiedType.Qualifiers); + p.DefaultArgument = null; + conversionOperator.Parameters.Add(p); + ((Class) method.Namespace).Methods.Add(conversionOperator); return true; } } diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index bf607102..fe41ab78 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -164,4 +164,14 @@ public class CSharpTempTests : GeneratorTestFixture Assert.AreEqual(q1.Array[i], q2.Array[i]); } } + + [Test] + public void TestImplicitCtor() + { + Foo foo = new Foo { A = 10 }; + MethodsWithDefaultValues m = foo; + Assert.AreEqual(foo.A, m.A); + MethodsWithDefaultValues m1 = 5; + Assert.AreEqual(5, m1.A); + } } \ No newline at end of file diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index 58670fe6..b81ac26f 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -277,6 +277,12 @@ QGenericArgument::QGenericArgument(const char *name) MethodsWithDefaultValues::MethodsWithDefaultValues(Foo foo) { + m_foo = foo; +} + +MethodsWithDefaultValues::MethodsWithDefaultValues(int a) +{ + m_foo.A = a; } void MethodsWithDefaultValues::defaultPointer(Foo *ptr) @@ -347,6 +353,11 @@ void MethodsWithDefaultValues::rotate4x4Matrix(float angle, float x, float y, fl { } +int MethodsWithDefaultValues::getA() +{ + return m_foo.A; +} + void HasPrivateOverrideBase::privateOverride(int i) { } diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 0324aa47..d57dc90f 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -248,6 +248,7 @@ class DLL_API MethodsWithDefaultValues { public: MethodsWithDefaultValues(Foo foo = Foo()); + MethodsWithDefaultValues(int a); void defaultPointer(Foo* ptr = 0); void defaultVoidStar(void* ptr = 0); void defaultValueType(QGenericArgument valueType = QGenericArgument()); @@ -270,6 +271,9 @@ public: void defaultIntWithLongExpression(unsigned int i = DEFAULT_INT); void defaultRefTypeEnumImplicitCtor(const QColor &fillColor = Qt::white); void rotate4x4Matrix(float angle, float x, float y, float z = 0.0f); + int getA(); +private: + Foo m_foo; }; class DLL_API HasPrivateOverrideBase