From ab548cb6daf2ae27dfb669e70915fa0a202f56ae Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Fri, 1 Nov 2013 15:44:14 +0200 Subject: [PATCH 01/11] Fixed the generation of properties to take indirect return types into account. Added "return" as a verb. Signed-off-by: Dimitar Dobrev --- .../Passes/GetterSetterToPropertyAdvancedPass.cs | 11 ++++++----- src/Generator/Passes/verbs.txt | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs index aa16af61..e5901696 100644 --- a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs @@ -94,7 +94,7 @@ namespace CppSharp.Passes { string name = GetPropertyName(getter.Name); if (string.Compare(name, afterSet, StringComparison.OrdinalIgnoreCase) == 0 && - getter.ReturnType == setter.Parameters[0].QualifiedType && + getter.OriginalReturnType == setter.Parameters[0].QualifiedType && !type.Methods.Any( m => m != getter && @@ -142,7 +142,7 @@ namespace CppSharp.Passes Property property = new Property(); property.Name = GetPropertyName(getter.Name); property.Namespace = type; - property.QualifiedType = getter.ReturnType; + property.QualifiedType = getter.OriginalReturnType; if (getter.IsOverride || (setter != null && setter.IsOverride)) { Property baseVirtualProperty = type.GetRootBaseProperty(property); @@ -204,7 +204,7 @@ namespace CppSharp.Passes private void DistributeMethod(Method method) { if (GetFirstWord(method.Name) == "set" && method.Name.Length > 3 && - method.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void)) + method.OriginalReturnType.Type.IsPrimitiveType(PrimitiveType.Void)) { if (method.Parameters.Count == 1) setters.Add(method); @@ -222,8 +222,9 @@ namespace CppSharp.Passes private bool IsGetter(Method method) { - if (method.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void) || - method.Parameters.Count > 0 || method.IsDestructor) + if (method.IsDestructor || + (method.OriginalReturnType.Type.IsPrimitiveType(PrimitiveType.Void)) || + method.Parameters.Any(p => p.Kind != ParameterKind.IndirectReturnType)) return false; var result = GetFirstWord(method.Name); return (result.Length < method.Name.Length && diff --git a/src/Generator/Passes/verbs.txt b/src/Generator/Passes/verbs.txt index b5a441c9..da74e991 100644 --- a/src/Generator/Passes/verbs.txt +++ b/src/Generator/Passes/verbs.txt @@ -7209,6 +7209,7 @@ rettore rettorn retune returf +return retwine retwist retype From ff14f39ed4e1c0db1563b87bbd969a4ae8ddec80 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Fri, 1 Nov 2013 23:06:32 +0200 Subject: [PATCH 02/11] Fixed the generation of properties by considering value and read-only pointer types the same for complex types. Fixed the counting of parameters to consider indirect ones. Signed-off-by: Dimitar Dobrev --- .../GetterSetterToPropertyAdvancedPass.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs index e5901696..944d8d7d 100644 --- a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using System.Text; using CppSharp.AST; +using Type = CppSharp.AST.Type; namespace CppSharp.Passes { @@ -94,7 +95,8 @@ namespace CppSharp.Passes { string name = GetPropertyName(getter.Name); if (string.Compare(name, afterSet, StringComparison.OrdinalIgnoreCase) == 0 && - getter.OriginalReturnType == setter.Parameters[0].QualifiedType && + GetUnderlyingType(getter.OriginalReturnType).Equals( + GetUnderlyingType(setter.Parameters[0].QualifiedType)) && !type.Methods.Any( m => m != getter && @@ -132,6 +134,17 @@ namespace CppSharp.Passes } } + private static Type GetUnderlyingType(QualifiedType type) + { + TagType tagType = type.Type as TagType; + if (tagType != null) + return type.Type; + if (!type.Qualifiers.IsConst) + return type.Type; + PointerType pointerType = type.Type as PointerType; + return pointerType != null ? pointerType.Pointee : type.Type; + } + private static void GenerateProperty(DeclarationContext context, Method getter, Method setter = null) { Class type = (Class) context; @@ -148,7 +161,8 @@ namespace CppSharp.Passes Property baseVirtualProperty = type.GetRootBaseProperty(property); if (baseVirtualProperty.SetMethod == null) setter = null; - foreach (Method method in type.Methods.Where(m => m.Name == property.Name && m.Parameters.Count > 0)) + foreach (Method method in type.Methods.Where(m => m.Name == property.Name && + m.Parameters.Any(p => p.Kind != ParameterKind.IndirectReturnType))) method.Name = "get" + method.Name; } property.GetMethod = getter; @@ -215,7 +229,7 @@ namespace CppSharp.Passes { if (IsGetter(method)) getters.Add(method); - if (method.Parameters.Count == 0) + if (method.Parameters.All(p => p.Kind == ParameterKind.IndirectReturnType)) nonSetters.Add(method); } } From 014c7df874b716273ee7b2beb01e1908054ab5ff Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 2 Nov 2013 12:31:37 +0200 Subject: [PATCH 03/11] Added "register" to the list of verbs. Signed-off-by: Dimitar Dobrev --- src/Generator/Passes/verbs.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Generator/Passes/verbs.txt b/src/Generator/Passes/verbs.txt index da74e991..9c9ce287 100644 --- a/src/Generator/Passes/verbs.txt +++ b/src/Generator/Passes/verbs.txt @@ -6583,6 +6583,7 @@ regerminate regild regionalize regird +register registrate regive regiven From 501f1232779ea14ad6845fa26dc80e139f5b57e6 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 2 Nov 2013 15:10:33 +0200 Subject: [PATCH 04/11] Removed a check for const-ness because of a parser bug. Added tests for properties of complex types. Signed-off-by: Dimitar Dobrev --- .../Passes/GetterSetterToPropertyAdvancedPass.cs | 5 +++-- tests/CSharpTemp/CSharpTemp.Tests.cs | 5 +++++ tests/CSharpTemp/CSharpTemp.cpp | 10 ++++++++++ tests/CSharpTemp/CSharpTemp.h | 12 ++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs index 944d8d7d..f4ca7b99 100644 --- a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs @@ -139,8 +139,9 @@ namespace CppSharp.Passes TagType tagType = type.Type as TagType; if (tagType != null) return type.Type; - if (!type.Qualifiers.IsConst) - return type.Type; + // TODO: we should normally check pointer types for const; + // however, there's some bug, probably in the parser, that returns IsConst = false for "const Type& arg" + // so skip the check for the time being PointerType pointerType = type.Type as PointerType; return pointerType != null ? pointerType.Pointee : type.Type; } diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index e24d3629..ca3d2822 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -74,5 +74,10 @@ public class CSharpTempTests Assert.That(p.value, Is.EqualTo(30)); p.prop = 50; Assert.That(p.prop, Is.EqualTo(150)); + + ComplexType complexType = new ComplexType(); + complexType.check = 5; + p.complexType = complexType; + Assert.That(p.complexType.check, Is.EqualTo(5)); } } \ No newline at end of file diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index ab01784a..7caa92fa 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -95,3 +95,13 @@ long P::prop() { return m_property + 100; } + +ComplexType P::complexType() +{ + return m_complexType; +} + +void P::setComplexType(ComplexType value) +{ + m_complexType = value; +} diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index f5faeb10..c6386185 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -86,9 +86,21 @@ public: virtual long prop(); }; +class ComplexType +{ +public: + int check; +}; + class DLL_API P : Proprietor { public: virtual void setValue(int value); virtual long prop(); + + ComplexType complexType(); + void setComplexType(ComplexType value); + +private: + ComplexType m_complexType; }; From 56385a453fe58e4df8e88a865946124be8498c12 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Fri, 1 Nov 2013 23:28:28 +0200 Subject: [PATCH 05/11] Fixed the generation of v-table delegates to take into account indirect return types. Signed-off-by: Dimitar Dobrev --- src/Generator/Generators/CSharp/CSharpTextTemplate.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index b0a5fc4b..9d9467b1 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -536,7 +536,7 @@ namespace CppSharp.Generators.CSharp TypePrinter.PushContext(CSharpTypePrinterContextKind.Native); - var retParam = new Parameter { QualifiedType = function.ReturnType }; + var retParam = new Parameter { QualifiedType = function.OriginalReturnType }; retType = retParam.CSharpType(TypePrinter); var method = function as Method; @@ -1285,8 +1285,7 @@ namespace CppSharp.Generators.CSharp marshals.Add(marshal.Context.Return); } - var hasReturn = !method.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void) - && !method.HasIndirectReturnTypeParameter; + var hasReturn = !method.OriginalReturnType.Type.IsPrimitiveType(PrimitiveType.Void); if (hasReturn) Write("var _ret = "); @@ -1300,8 +1299,6 @@ namespace CppSharp.Generators.CSharp InvokeProperty(method, marshals); } - // TODO: Handle hidden structure return types. - if (hasReturn) { var param = new Parameter @@ -1319,7 +1316,7 @@ namespace CppSharp.Generators.CSharp }; var marshal = new CSharpMarshalManagedToNativePrinter(ctx); - method.ReturnType.Visit(marshal); + method.OriginalReturnType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) Write(marshal.Context.SupportBefore); From 961316f96d025f8862218908ab0da76bae8df870 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 2 Nov 2013 16:21:59 +0200 Subject: [PATCH 06/11] Fixed the new tests for properties to work around the existing unrelated bug of incorrect field values. Signed-off-by: Dimitar Dobrev --- tests/CSharpTemp/CSharpTemp.Tests.cs | 3 +-- tests/CSharpTemp/CSharpTemp.cpp | 7 ++++++- tests/CSharpTemp/CSharpTemp.h | 6 +++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index ca3d2822..f047f68f 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -76,8 +76,7 @@ public class CSharpTempTests Assert.That(p.prop, Is.EqualTo(150)); ComplexType complexType = new ComplexType(); - complexType.check = 5; p.complexType = complexType; - Assert.That(p.complexType.check, Is.EqualTo(5)); + Assert.That(p.complexType.check(), Is.EqualTo(5)); } } \ No newline at end of file diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index 7caa92fa..bae46189 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -96,12 +96,17 @@ long P::prop() return m_property + 100; } +int ComplexType::check() +{ + return 5; +} + ComplexType P::complexType() { return m_complexType; } -void P::setComplexType(ComplexType value) +void P::setComplexType(const ComplexType& value) { m_complexType = value; } diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index c6386185..a034138d 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -86,10 +86,10 @@ public: virtual long prop(); }; -class ComplexType +class DLL_API ComplexType { public: - int check; + int check(); }; class DLL_API P : Proprietor @@ -99,7 +99,7 @@ public: virtual long prop(); ComplexType complexType(); - void setComplexType(ComplexType value); + void setComplexType(const ComplexType& value); private: ComplexType m_complexType; From 9deaa403bc958d15fec3cee770752a997ba6321a Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 2 Nov 2013 17:08:58 +0200 Subject: [PATCH 07/11] Fixed a crash when setting up v-tables. Signed-off-by: Dimitar Dobrev --- .../Generators/CSharp/CSharpTextTemplate.cs | 14 ++++++++++++-- tests/CSharpTemp/CSharpTemp.cs | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 9d9467b1..69935700 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1245,11 +1245,21 @@ namespace CppSharp.Generators.CSharp NewLine(); } - private void GenerateVTableClassSetupCall(Class @class) + private void GenerateVTableClassSetupCall(Class @class, bool addPointerGuard = false) { var entries = GetVTableMethodEntries(@class); if (Options.GenerateVirtualTables && @class.IsDynamic && entries.Count != 0) + { + // called from internal ctors which may have been passed an IntPtr.Zero + if (addPointerGuard) + { + WriteLine("if ({0} != global::System.IntPtr.Zero)", Helpers.InstanceIdentifier); + PushIndent(); + } WriteLine("SetupVTables({0});", Generator.GeneratedIdentifier("Instance")); + if (addPointerGuard) + PopIndent(); + } } private void GenerateVTableManagedCall(Method method) @@ -1613,7 +1623,7 @@ namespace CppSharp.Generators.CSharp if (ShouldGenerateClassNativeField(@class)) { WriteLine("{0} = native;", Helpers.InstanceIdentifier); - GenerateVTableClassSetupCall(@class); + GenerateVTableClassSetupCall(@class, true); } } else diff --git a/tests/CSharpTemp/CSharpTemp.cs b/tests/CSharpTemp/CSharpTemp.cs index 5640ba0b..a122ffc7 100644 --- a/tests/CSharpTemp/CSharpTemp.cs +++ b/tests/CSharpTemp/CSharpTemp.cs @@ -14,6 +14,7 @@ namespace CppSharp.Tests { driver.Options.GenerateInterfacesForMultipleInheritance = true; driver.Options.GenerateProperties = true; + driver.Options.GenerateVirtualTables = true; } public static void Main(string[] args) From c0ed93cd5ec3869762beda0ee5f34ba0bbf3f086 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 2 Nov 2013 17:54:46 +0200 Subject: [PATCH 08/11] Prevented postfix and dereference operators from being wrapped as such because C# does not support them. Signed-off-by: Dimitar Dobrev --- src/Generator/Passes/CheckOperatorsOverloads.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Generator/Passes/CheckOperatorsOverloads.cs b/src/Generator/Passes/CheckOperatorsOverloads.cs index 04972842..024245f6 100644 --- a/src/Generator/Passes/CheckOperatorsOverloads.cs +++ b/src/Generator/Passes/CheckOperatorsOverloads.cs @@ -169,11 +169,8 @@ namespace CppSharp.Passes case CXXOperatorKind.Minus: case CXXOperatorKind.Exclaim: case CXXOperatorKind.Tilde: - case CXXOperatorKind.PlusPlus: - case CXXOperatorKind.MinusMinus: // These binary operators can be overloaded - case CXXOperatorKind.Star: case CXXOperatorKind.Slash: case CXXOperatorKind.Percent: case CXXOperatorKind.Amp: @@ -193,12 +190,22 @@ namespace CppSharp.Passes case CXXOperatorKind.Conversion: return true; + // Only prefix operators can be overloaded + case CXXOperatorKind.PlusPlus: + case CXXOperatorKind.MinusMinus: + return @operator.Parameters.Count == 0; + + // Bitwise shift operators can only be overloaded if the second parameter is int case CXXOperatorKind.LessLess: case CXXOperatorKind.GreaterGreater: PrimitiveType primitiveType; return @operator.Parameters.Last().Type.IsPrimitiveType(out primitiveType) && primitiveType == PrimitiveType.Int32; + // No parameters means the dereference operator - cannot be overloaded + case CXXOperatorKind.Star: + return @operator.Parameters.Count > 0; + // Assignment operators cannot be overloaded case CXXOperatorKind.PlusEqual: case CXXOperatorKind.MinusEqual: From 2b53801510b8c388318c7ee85e48dbe3f07196f3 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 2 Nov 2013 17:56:43 +0200 Subject: [PATCH 09/11] Prefixed "System.Runtime.InteropServices" with "global::" to prevent name collision. Signed-off-by: Dimitar Dobrev --- src/Generator/Generators/CSharp/CSharpTextTemplate.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 69935700..86b8d4e4 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1357,7 +1357,7 @@ namespace CppSharp.Generators.CSharp PushBlock(CSharpBlockKind.VTableDelegate); WriteLine("[SuppressUnmanagedCodeSecurity]"); - WriteLine("[UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.{0})]", + WriteLine("[UnmanagedFunctionPointerAttribute(global::System.Runtime.InteropServices.CallingConvention.{0})]", Helpers.ToCSharpCallConv(method.CallingConvention)); CSharpTypePrinterResult retType; @@ -1430,7 +1430,7 @@ namespace CppSharp.Generators.CSharp delegateName = delegateInstance + "Delegate"; delegateRaise = delegateInstance + "RaiseInstance"; - WriteLine("[UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.Cdecl)]"); + WriteLine("[UnmanagedFunctionPointerAttribute(global::System.Runtime.InteropServices.CallingConvention.Cdecl)]"); WriteLine("delegate void {0}({1});", delegateName, args); WriteLine("{0} {1};", delegateName, delegateRaise); NewLine(); @@ -2195,7 +2195,7 @@ namespace CppSharp.Generators.CSharp else if (typedef.Type.IsPointerTo(out functionType)) { PushBlock(CSharpBlockKind.Typedef); - WriteLine("[UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.{0})]", + WriteLine("[UnmanagedFunctionPointerAttribute(global::System.Runtime.InteropServices.CallingConvention.{0})]", Helpers.ToCSharpCallConv(functionType.CallingConvention)); TypePrinter.PushContext(CSharpTypePrinterContextKind.Native); WriteLine("{0}unsafe {1};", @@ -2324,7 +2324,7 @@ namespace CppSharp.Generators.CSharp Write("[DllImport(\"{0}\", ", libName); var callConv = Helpers.ToCSharpCallConv(function.CallingConvention); - WriteLine("CallingConvention = System.Runtime.InteropServices.CallingConvention.{0},", + WriteLine("CallingConvention = global::System.Runtime.InteropServices.CallingConvention.{0},", callConv); WriteLineIndent("EntryPoint=\"{0}\")]", function.Mangled); From 9255ac4144f2fa5e31a8eadaa2ab3928ef3950a0 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 2 Nov 2013 18:54:19 +0200 Subject: [PATCH 10/11] Added the method to its block to maintain the connection between them. Signed-off-by: Dimitar Dobrev --- src/Generator/Generators/CSharp/CSharpTextTemplate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 86b8d4e4..d76e3a8a 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -1702,7 +1702,7 @@ namespace CppSharp.Generators.CSharp public void GenerateMethod(Method method, Class @class) { - PushBlock(CSharpBlockKind.Method); + PushBlock(CSharpBlockKind.Method, method); GenerateDeclarationCommon(method); if (method.ExplicitInterfaceImpl == null) From 47f03ae68c86ede8ed26a0beaad63c03a57f14bc Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 4 Nov 2013 18:15:49 +0200 Subject: [PATCH 11/11] Added tests about the dereference and prefix/postfix operators. Fixed multiple inheritance not to include operators in interfaces. Signed-off-by: Dimitar Dobrev --- .../Passes/MultipleInheritancePass.cs | 2 +- .../Passes/ParamTypeToInterfacePass.cs | 31 ++++++++++--------- tests/CSharpTemp/CSharpTemp.Tests.cs | 5 ++- tests/CSharpTemp/CSharpTemp.cpp | 24 ++++++++++++++ tests/CSharpTemp/CSharpTemp.h | 5 +++ 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/Generator/Passes/MultipleInheritancePass.cs b/src/Generator/Passes/MultipleInheritancePass.cs index 59199062..e25004ee 100644 --- a/src/Generator/Passes/MultipleInheritancePass.cs +++ b/src/Generator/Passes/MultipleInheritancePass.cs @@ -68,7 +68,7 @@ namespace CppSharp.Passes @interface.Methods.AddRange( from m in @base.Methods - where !m.IsConstructor && !m.IsDestructor && !m.IsStatic && !m.Ignore + where !m.IsConstructor && !m.IsDestructor && !m.IsStatic && !m.Ignore && !m.IsOperator select new Method(m) { Namespace = @interface }); @interface.Properties.AddRange( diff --git a/src/Generator/Passes/ParamTypeToInterfacePass.cs b/src/Generator/Passes/ParamTypeToInterfacePass.cs index 5e0e12d0..350221c0 100644 --- a/src/Generator/Passes/ParamTypeToInterfacePass.cs +++ b/src/Generator/Passes/ParamTypeToInterfacePass.cs @@ -1,4 +1,5 @@ -using CppSharp.AST; +using System.Linq; +using CppSharp.AST; namespace CppSharp.Passes { @@ -6,24 +7,26 @@ namespace CppSharp.Passes { public override bool VisitFunctionDecl(Function function) { - if (function.HasIndirectReturnTypeParameter) + if (!function.IsOperator) { - var parameter = function.Parameters.Find(p => p.Kind == ParameterKind.IndirectReturnType); - parameter.QualifiedType = GetInterfaceType(parameter.QualifiedType); - } - else - { - function.ReturnType = GetInterfaceType(function.ReturnType); + if (function.HasIndirectReturnTypeParameter) + { + var parameter = function.Parameters.Find(p => p.Kind == ParameterKind.IndirectReturnType); + parameter.QualifiedType = GetInterfaceType(parameter.QualifiedType); + } + else + { + function.ReturnType = GetInterfaceType(function.ReturnType); + } + foreach (Parameter parameter in function.Parameters.Where( + p => p.Kind != ParameterKind.IndirectReturnType)) + { + parameter.QualifiedType = GetInterfaceType(parameter.QualifiedType); + } } return base.VisitFunctionDecl(function); } - public override bool VisitParameterDecl(Parameter parameter) - { - parameter.QualifiedType = GetInterfaceType(parameter.QualifiedType); - return base.VisitParameterDecl(parameter); - } - private static QualifiedType GetInterfaceType(QualifiedType type) { var tagType = type.Type as TagType; diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index f047f68f..bb7bdfdf 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -1,5 +1,4 @@ -using System; -using System.Reflection; +using System.Reflection; using CSharpTemp; using NUnit.Framework; using Foo = CSharpTemp.Foo; @@ -8,7 +7,7 @@ using Foo = CSharpTemp.Foo; public class CSharpTempTests { [Test] - public unsafe void TestIndexer() + public void TestIndexer() { var foo = new Foo(); diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index bae46189..5a8a6295 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -46,6 +46,30 @@ Foo& Bar::operator[](int i) return m_foo; } +Bar Bar::operator *() +{ + return *this; +} + +const Bar& Bar::operator *(int m) +{ + index *= m; + return *this; +} + +const Bar& Bar::operator ++() +{ + ++index; + return *this; +} + +Bar Bar::operator ++(int i) +{ + Bar bar = *this; + index++; + return bar; +} + Baz::Nested::operator int() const { return 300; diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index a034138d..9d254119 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -31,8 +31,13 @@ public: int method(); const Foo& operator[](int i) const; Foo& operator[](int i); + Bar operator*(); + const Bar& operator*(int m); + const Bar& operator++(); + Bar operator++(int i); private: + int index; Foo m_foo; };