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);