From 54caddeed1d27a17be0caa374a90a411738242bb Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Fri, 24 Jul 2015 14:29:05 +0100 Subject: [PATCH] Cloned types when changing them to interfaces for multiple inheritance. Signed-off-by: Dimitar Dobrev --- src/AST/Function.cs | 7 + src/AST/Type.cs | 154 +++++++++++++++++- .../ConstructorToConversionOperatorPass.cs | 7 +- .../Passes/ParamTypeToInterfacePass.cs | 25 ++- tests/CSharpTemp/CSharpTemp.Tests.cs | 3 + tests/CSharpTemp/CSharpTemp.cpp | 5 + tests/CSharpTemp/CSharpTemp.h | 1 + 7 files changed, 187 insertions(+), 15 deletions(-) diff --git a/src/AST/Function.cs b/src/AST/Function.cs index 453434e3..acf2d952 100644 --- a/src/AST/Function.cs +++ b/src/AST/Function.cs @@ -195,6 +195,13 @@ namespace CppSharp.AST return hiddenParam.QualifiedType; } + set + { + if (HasIndirectReturnTypeParameter) + Parameters.Single(p => p.Kind == ParameterKind.IndirectReturnType).QualifiedType = value; + else + ReturnType = value; + } } public FunctionSynthKind SynthKind { get; set; } diff --git a/src/AST/Type.cs b/src/AST/Type.cs index 741a9834..422ea886 100644 --- a/src/AST/Type.cs +++ b/src/AST/Type.cs @@ -7,7 +7,7 @@ namespace CppSharp.AST /// /// Represents a C++ type. /// - public abstract class Type + public abstract class Type : ICloneable { public static Func TypePrinterDelegate; @@ -20,6 +20,8 @@ namespace CppSharp.AST { return TypePrinterDelegate(this); } + + public abstract object Clone(); } /// @@ -108,6 +110,11 @@ namespace CppSharp.AST return visitor.VisitTagType(this, quals); } + public override object Clone() + { + return new TagType(Declaration) { IsDependent = IsDependent }; + } + public override bool Equals(object obj) { var type = obj as TagType; @@ -154,6 +161,17 @@ namespace CppSharp.AST return visitor.VisitArrayType(this, quals); } + public override object Clone() + { + return new ArrayType + { + IsDependent = IsDependent, + QualifiedType = new QualifiedType((Type) QualifiedType.Type.Clone(), QualifiedType.Qualifiers), + SizeType = SizeType, + Size = Size + }; + } + public override bool Equals(object obj) { var type = obj as ArrayType; @@ -195,6 +213,17 @@ namespace CppSharp.AST return visitor.VisitFunctionType(this, quals); } + public override object Clone() + { + return new FunctionType + { + IsDependent = IsDependent, + ReturnType = new QualifiedType((Type) ReturnType.Type.Clone(), ReturnType.Qualifiers), + Parameters = Parameters.Select(p => new Parameter(p)).ToList(), + CallingConvention = CallingConvention + }; + } + public override bool Equals(object obj) { var type = obj as FunctionType; @@ -252,6 +281,15 @@ namespace CppSharp.AST return visitor.VisitPointerType(this, QualifiedPointee.Qualifiers); } + public override object Clone() + { + return new PointerType(new QualifiedType((Type) QualifiedPointee.Type.Clone(), QualifiedPointee.Qualifiers)) + { + IsDependent = IsDependent, + Modifier = Modifier + }; + } + public override bool Equals(object obj) { var type = obj as PointerType; @@ -284,6 +322,15 @@ namespace CppSharp.AST return visitor.VisitMemberPointerType(this, quals); } + public override object Clone() + { + return new MemberPointerType + { + IsDependent = IsDependent, + QualifiedPointee = new QualifiedType((Type) QualifiedPointee.Type.Clone(), QualifiedPointee.Qualifiers) + }; + } + public override bool Equals(object obj) { var pointer = obj as MemberPointerType; @@ -310,6 +357,15 @@ namespace CppSharp.AST return visitor.VisitTypedefType(this, quals); } + public override object Clone() + { + return new TypedefType + { + IsDependent = IsDependent, + Declaration = Declaration + }; + } + public override bool Equals(object obj) { var typedef = obj as TypedefType; @@ -346,6 +402,16 @@ namespace CppSharp.AST return visitor.VisitAttributedType(this, quals); } + public override object Clone() + { + return new AttributedType + { + IsDependent = IsDependent, + Modified = new QualifiedType((Type) Modified.Type.Clone(), Modified.Qualifiers), + Equivalent = new QualifiedType((Type) Equivalent.Type.Clone(), Equivalent.Qualifiers) + }; + } + public override bool Equals(object obj) { var attributed = obj as AttributedType; @@ -375,6 +441,17 @@ namespace CppSharp.AST return visitor.VisitDecayedType(this, quals); } + public override object Clone() + { + return new DecayedType + { + IsDependent = IsDependent, + Decayed = new QualifiedType((Type) Decayed.Type.Clone(), Decayed.Qualifiers), + Original = new QualifiedType((Type) Original.Type.Clone(), Original.Qualifiers), + Pointee = new QualifiedType((Type) Pointee.Type.Clone(), Pointee.Qualifiers), + }; + } + public override bool Equals(object obj) { var decay = obj as DecayedType; @@ -483,6 +560,25 @@ namespace CppSharp.AST return visitor.VisitTemplateSpecializationType(this, quals); } + public override object Clone() + { + return new TemplateSpecializationType + { + IsDependent = IsDependent, + Arguments = Arguments.Select( + t => + new TemplateArgument + { + Declaration = t.Declaration, + Integral = t.Integral, + Kind = t.Kind, + Type = new QualifiedType((Type) t.Type.Type.Clone(), t.Type.Qualifiers) + }).ToList(), + Template = Template, + Desugared = (Type) Desugared.Clone() + }; + } + public override bool Equals(object obj) { var type = obj as TemplateSpecializationType; @@ -514,6 +610,23 @@ namespace CppSharp.AST return visitor.VisitTemplateParameterType(this, quals); } + public override object Clone() + { + return new TemplateParameterType + { + IsDependent = IsDependent, + Parameter = new TemplateParameter + { + Constraint = Parameter.Constraint, + IsTypeParameter = Parameter.IsTypeParameter, + Name = Parameter.Name + }, + Depth = Depth, + Index = Index, + IsParameterPack = IsParameterPack + }; + } + public override bool Equals(object obj) { var type = obj as TemplateParameterType; @@ -544,6 +657,15 @@ namespace CppSharp.AST return visitor.VisitTemplateParameterSubstitutionType(this, quals); } + public override object Clone() + { + return new TemplateParameterSubstitutionType + { + IsDependent = IsDependent, + Replacement = new QualifiedType((Type) Replacement.Type.Clone(), Replacement.Qualifiers) + }; + } + public override bool Equals(object obj) { var type = obj as TemplateParameterSubstitutionType; @@ -573,6 +695,16 @@ namespace CppSharp.AST return visitor.VisitInjectedClassNameType(this, quals); } + public override object Clone() + { + return new InjectedClassNameType + { + IsDependent = IsDependent, + TemplateSpecialization = (TemplateSpecializationType) TemplateSpecialization.Clone(), + Class = Class + }; + } + public override bool Equals(object obj) { var type = obj as InjectedClassNameType; @@ -600,6 +732,11 @@ namespace CppSharp.AST { return visitor.VisitDependentNameType(this, quals); } + + public override object Clone() + { + return new DependentNameType { IsDependent = IsDependent }; + } } /// @@ -620,6 +757,11 @@ namespace CppSharp.AST return visitor.VisitCILType(this, quals); } + public override object Clone() + { + return new CILType(Type) { IsDependent = IsDependent }; + } + public override bool Equals(object obj) { var type = obj as CILType; @@ -640,6 +782,11 @@ namespace CppSharp.AST { return visitor.VisitPackExpansionType(this, quals); } + + public override object Clone() + { + return new PackExpansionType { IsDependent = IsDependent }; + } } #region Primitives @@ -711,6 +858,11 @@ namespace CppSharp.AST return visitor.VisitBuiltinType(this, quals); } + public override object Clone() + { + return new BuiltinType(Type) { IsDependent = IsDependent }; + } + public override bool Equals(object obj) { var type = obj as BuiltinType; diff --git a/src/Generator/Passes/ConstructorToConversionOperatorPass.cs b/src/Generator/Passes/ConstructorToConversionOperatorPass.cs index 5239b726..7d8bfefa 100644 --- a/src/Generator/Passes/ConstructorToConversionOperatorPass.cs +++ b/src/Generator/Passes/ConstructorToConversionOperatorPass.cs @@ -50,12 +50,7 @@ namespace CppSharp.Passes OperatorKind = operatorKind, IsExplicit = method.IsExplicit }; - 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); + conversionOperator.Parameters.Add(new Parameter(parameter) { DefaultArgument = null }); ((Class) method.Namespace).Methods.Add(conversionOperator); return true; } diff --git a/src/Generator/Passes/ParamTypeToInterfacePass.cs b/src/Generator/Passes/ParamTypeToInterfacePass.cs index e460fc48..c8d7b593 100644 --- a/src/Generator/Passes/ParamTypeToInterfacePass.cs +++ b/src/Generator/Passes/ParamTypeToInterfacePass.cs @@ -9,19 +9,25 @@ namespace CppSharp.Passes public override bool VisitFunctionDecl(Function function) { if (!function.IsOperator || function.Parameters.Count > 1) - ChangeToInterfaceType(function.OriginalReturnType); + { + var originalReturnType = function.OriginalReturnType; + ChangeToInterfaceType(ref originalReturnType); + function.OriginalReturnType = originalReturnType; + } - if (function.OperatorKind != CXXOperatorKind.Conversion && + if (function.OperatorKind != CXXOperatorKind.Conversion && function.OperatorKind != CXXOperatorKind.ExplicitConversion) - { foreach (var parameter in function.Parameters.Where(p => p.Kind != ParameterKind.OperatorParameter)) - ChangeToInterfaceType(parameter.QualifiedType); - } - + { + var qualifiedType = parameter.QualifiedType; + ChangeToInterfaceType(ref qualifiedType); + parameter.QualifiedType = qualifiedType; + } + return base.VisitFunctionDecl(function); } - private static void ChangeToInterfaceType(QualifiedType type) + private static void ChangeToInterfaceType(ref QualifiedType type) { var tagType = (type.Type.GetFinalPointee() ?? type.Type) as TagType; if (tagType != null) @@ -31,7 +37,10 @@ namespace CppSharp.Passes { var @interface = @class.Namespace.Classes.Find(c => c.OriginalClass == @class); if (@interface != null) - tagType.Declaration = @interface; + { + type.Type = (Type) type.Type.Clone(); + ((TagType) (type.Type.GetFinalPointee() ?? type.Type)).Declaration = @interface; + } } } } diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index 2ac01f5c..a22adb66 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -39,6 +39,9 @@ public class CSharpTempTests : GeneratorTestFixture new Bar(qux).Dispose(); } } + using (ComplexType complexType = TestFlag.Flag1) + { + } } [Test] diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index d5e88d88..727fa5f5 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -236,6 +236,11 @@ ComplexType::ComplexType() : qFlags(QFlags(TestFlag::Flag2)) { } +ComplexType::ComplexType(const QFlags f) : qFlags(QFlags(TestFlag::Flag2)) +{ + qFlags = f; +} + int ComplexType::check() { return 5; diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 87711523..726580ec 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -167,6 +167,7 @@ class DLL_API ComplexType { public: ComplexType(); + ComplexType(const QFlags f); int check(); QFlags returnsQFlags(); void takesQFlags(const QFlags f);