From 12642f9a4216443027bd772efebc82c93d131cf9 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Tue, 5 Feb 2019 04:09:39 +0200 Subject: [PATCH] Fixed the generated C# when an unsigned enum is assigned a negative value. Signed-off-by: Dimitar Dobrev --- build/InstallMono.sh | 2 +- .../Passes/HandleDefaultParamValuesPass.cs | 34 ++++++++++++++++--- tests/CSharp/CSharp.Tests.cs | 1 + tests/CSharp/CSharp.cpp | 4 +++ tests/CSharp/CSharp.h | 5 +++ 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/build/InstallMono.sh b/build/InstallMono.sh index 37998da3..5e85fabf 100755 --- a/build/InstallMono.sh +++ b/build/InstallMono.sh @@ -1,6 +1,6 @@ OS=$(uname -s) if [ "$OS" == "Darwin" ]; then - wget -O mono.pkg https://download.mono-project.com/archive/5.2.0/macos-10-universal/MonoFramework-MDK-5.2.0.215.macos10.xamarin.universal.pkg + wget -O mono.pkg https://download.mono-project.com/archive/5.18.0/macos-10-universal/MonoFramework-MDK-5.18.0.240.macos10.xamarin.universal.pkg sudo installer -pkg mono.pkg -target / export PATH=$PATH:/Library/Frameworks/Mono.framework/Versions/Current/bin elif [ "$OS" == "Linux" ]; then diff --git a/src/Generator/Passes/HandleDefaultParamValuesPass.cs b/src/Generator/Passes/HandleDefaultParamValuesPass.cs index 86922160..ee299f8c 100644 --- a/src/Generator/Passes/HandleDefaultParamValuesPass.cs +++ b/src/Generator/Passes/HandleDefaultParamValuesPass.cs @@ -129,8 +129,7 @@ namespace CppSharp.Passes Class @class; if (desugared.GetFinalPointee().TryGetClass(out @class) && @class.IsValueType) { - result = string.Format("new {0}()", - new CSharpTypePrinter(Context).VisitClassDecl(@class)); + result = $"new {@class.Visit(new CSharpTypePrinter(Context))}()"; return true; } @@ -253,15 +252,40 @@ namespace CppSharp.Passes if (call != null && statement.String != "0") { var @params = regexFunctionParams.Match(statement.String).Groups[1].Value; - result = TranslateEnumExpression(call, desugared, @params); + result = TranslateEnumExpression(desugared, @params); + return true; + } + + if (desugared.TryGetEnum(out Enumeration @enum) && + int.TryParse(statement.String, out int value)) + { + var typePrinter = new CSharpTypePrinter(Context); + var printedEnum = @enum.Visit(typePrinter); + if (value < 0) + switch (@enum.BuiltinType.Type) + { + case PrimitiveType.UShort: + case PrimitiveType.UInt: + case PrimitiveType.ULong: + case PrimitiveType.ULongLong: + case PrimitiveType.UInt128: + result = $@"({printedEnum}) unchecked(({ + @enum.BuiltinType.Visit(typePrinter)}) { + statement.String})"; + break; + default: + result = $"({printedEnum}) ({statement.String})"; + break; + } + else + result = $"({printedEnum}) {statement.String}"; return true; } return false; } - private string TranslateEnumExpression(Function function, - Type desugared, string @params) + private string TranslateEnumExpression(Type desugared, string @params) { if (@params.Contains("::")) return regexDoubleColon.Replace(@params, desugared + "."); diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index 41411a1d..6d5829e2 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -229,6 +229,7 @@ public unsafe class CSharpTests : GeneratorTestFixture methodsWithDefaultValues.DefaultValueType(); methodsWithDefaultValues.DefaultChar(); methodsWithDefaultValues.DefaultEmptyChar(); + methodsWithDefaultValues.DefaultEmptyEnum(); methodsWithDefaultValues.DefaultRefTypeBeforeOthers(); methodsWithDefaultValues.DefaultRefTypeAfterOthers(); methodsWithDefaultValues.DefaultRefTypeBeforeAndAfterOthers(0, null); diff --git a/tests/CSharp/CSharp.cpp b/tests/CSharp/CSharp.cpp index bafd2d8b..26955ff1 100644 --- a/tests/CSharp/CSharp.cpp +++ b/tests/CSharp/CSharp.cpp @@ -584,6 +584,10 @@ void MethodsWithDefaultValues::defaultEmptyChar(char c) { } +void MethodsWithDefaultValues::defaultEmptyEnum(Empty e) +{ +} + void MethodsWithDefaultValues::defaultRefTypeBeforeOthers(Foo foo, int i, Bar::Items item) { } diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 326a55c2..5dd81f57 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -379,6 +379,10 @@ public: DefaultZeroMappedToEnum(int* = 0); }; +enum class Empty : unsigned long long int +{ +}; + class DLL_API MethodsWithDefaultValues : public Quux { public: @@ -404,6 +408,7 @@ public: void defaultValueType(QGenericArgument valueType = QGenericArgument()); void defaultChar(char c = 'a'); void defaultEmptyChar(char c = 0); + void defaultEmptyEnum(Empty e = Empty(-1)); void defaultRefTypeBeforeOthers(Foo foo = Foo(), int i = 5, Bar::Items item = Bar::Item2); void defaultRefTypeAfterOthers(int i = 5, Bar::Items item = Bar::Item2, Foo foo = Foo()); void defaultRefTypeBeforeAndAfterOthers(int i = 5, Foo foo = Foo(), Bar::Items item = Bar::Item2, Baz baz = Baz());