diff --git a/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs b/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs index 074922fc..3782650c 100644 --- a/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs @@ -1,7 +1,6 @@ using System.Linq; using CppSharp.AST; using CppSharp.AST.Extensions; -using CppSharp.Types; using Type = CppSharp.AST.Type; namespace CppSharp.Generators.CSharp diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 540124d6..87ccf302 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -1192,11 +1192,11 @@ namespace CppSharp.Generators.CSharp var systemType = Internal.ExpressionHelper.GetSystemType(Context, arrayType.Type.Desugar()); Write($"new {arrayType.Type}[{arrayType.Size}] "); Write("{ "); - + List elements = Internal.ExpressionHelper.SplitInitListExpr(initializerString); while (elements.Count < arrayType.Size) - elements.Add(systemType == typeof(string) ? "\"\"" : null); + elements.Add(systemType == typeof(string) ? "\"\"" : null); for (int i = 0; i < elements.Count; ++i) { @@ -1204,7 +1204,8 @@ namespace CppSharp.Generators.CSharp if (e == null) Write("default"); - else { + else + { if (!Internal.ExpressionHelper.TryParseExactLiteralExpression(ref e, systemType)) Write($"({arrayType.Type})"); Write(e); @@ -1218,19 +1219,7 @@ namespace CppSharp.Generators.CSharp } else { - if (Internal.ExpressionHelper.PrintExpression(Context, null, type, - variable.Initializer, false, ref initializerString) == null) - { - Write(initializerString); - } - else - { - var systemType = Internal.ExpressionHelper.GetSystemType(Context, type); - if (!Internal.ExpressionHelper.TryParseExactLiteralExpression(ref initializerString, systemType)) - Write($"({type}) {initializerString}"); - else - Write(initializerString); - } + Write(initializerString); } WriteLine(";"); } diff --git a/src/Generator/Passes/ExpressionHelper.cs b/src/Generator/Passes/ExpressionHelper.cs index dffb6f82..ca9c011a 100644 --- a/src/Generator/Passes/ExpressionHelper.cs +++ b/src/Generator/Passes/ExpressionHelper.cs @@ -11,7 +11,7 @@ using TypeCode = System.TypeCode; namespace CppSharp.Internal { - internal class ExpressionHelper + internal static class ExpressionHelper { private static readonly Regex regexFunctionParams = new Regex(@"\(?(.+)\)?", RegexOptions.Compiled); private static readonly Regex regexDoubleColon = new Regex(@"\w+::", RegexOptions.Compiled); @@ -200,7 +200,8 @@ namespace CppSharp.Internal { return CheckFloatSyntax(desugared, expression, ref result) || CheckForEnumValue(context, desugared, expression, ref result) || - CheckForDefaultChar(context, desugared, ref result); + CheckForChar(context, desugared, ref result) || + CheckForString(context, desugared, ref result); } private static bool CheckForDefaultPointer(BindingContext context, Type desugared, ref string result) @@ -390,10 +391,9 @@ namespace CppSharp.Internal ((BuiltinTypeExpressionObsolete)defaultArgument).Value == 0; } - private static bool CheckForDefaultChar(BindingContext context, Type desugared, ref string result) + private static bool CheckForChar(BindingContext context, Type desugared, ref string result) { - int value; - if (int.TryParse(result, out value) && + if (int.TryParse(result, out int value) && ((context.Options.MarshalCharAsManagedChar && desugared.IsPrimitiveType(PrimitiveType.Char)) || desugared.IsPrimitiveType(PrimitiveType.WideChar))) @@ -401,7 +401,36 @@ namespace CppSharp.Internal result = value == 0 ? "'\\0'" : ("(char) " + result); return true; } + if (context.Options.MarshalCharAsManagedChar && + desugared.IsPrimitiveType(PrimitiveType.UChar)) + { + result = "(byte) " + result; + return true; + } + + return false; + } + private static bool CheckForString(BindingContext context, Type desugared, ref string result) + { + if (context.TypeMaps.FindTypeMap(desugared, out TypeMap typeMap)) + { + var typePrinterContext = new TypePrinterContext() + { + Kind = TypePrinterContextKind.Managed, + MarshalKind = MarshalKind.DefaultExpression, + Type = desugared + }; + + var typeInSignature = typeMap.CSharpSignatureType(typePrinterContext) + .SkipPointerRefs().Desugar(); + + if (typeInSignature is CILType managed && managed.Type == typeof(string)) + { + result = result[result.IndexOf("\"")..]; + return true; + } + } return false; } } diff --git a/src/Generator/Passes/HandleVariableInitializerPass.cs b/src/Generator/Passes/HandleVariableInitializerPass.cs index f8e60878..888dfcea 100644 --- a/src/Generator/Passes/HandleVariableInitializerPass.cs +++ b/src/Generator/Passes/HandleVariableInitializerPass.cs @@ -1,33 +1,21 @@ using CppSharp.AST; -using CppSharp.AST.Extensions; using CppSharp.Internal; namespace CppSharp.Passes { public class HandleVariableInitializerPass : TranslationUnitPass { + public HandleVariableInitializerPass() + => VisitOptions.ResetFlags(VisitFlags.NamespaceVariables); + public override bool VisitVariableDecl(Variable variable) { - if (!base.VisitVariableDecl(variable) || variable.Ignore || variable.Initializer == null) - return false; - - bool supported = - variable.Type.IsPrimitiveType() || - variable.Type.IsPointerToPrimitiveType(PrimitiveType.Char) || - variable.Type.IsPointerToPrimitiveType(PrimitiveType.WideChar) || - (variable.Type is ArrayType arrayType && ( - arrayType.Type.IsPrimitiveType() || - arrayType.Type.IsPointerToPrimitiveType(PrimitiveType.Char) || - arrayType.Type.IsPointerToPrimitiveType(PrimitiveType.WideChar))); - - if (!supported) - { - variable.Initializer = null; + if (AlreadyVisited(variable) || variable.Ignore || variable.Initializer == null) return false; - } string initializerString = variable.Initializer.String; - ExpressionHelper.PrintExpression(Context, null, variable.Type, variable.Initializer, allowDefaultLiteral: true, ref initializerString); + ExpressionHelper.PrintExpression(Context, null, variable.Type, variable.Initializer, + allowDefaultLiteral: true, ref initializerString); if (string.IsNullOrWhiteSpace(initializerString)) variable.Initializer = null; diff --git a/tests/CSharp/CSharp.cpp b/tests/CSharp/CSharp.cpp index 6a4ee158..64716b44 100644 --- a/tests/CSharp/CSharp.cpp +++ b/tests/CSharp/CSharp.cpp @@ -613,7 +613,11 @@ void MethodsWithDefaultValues::defaultValueType(QGenericArgument valueType) { } -void MethodsWithDefaultValues::defaultChar(char c, char uc, char Uc, char Lc) +void MethodsWithDefaultValues::defaultChar(char c, char uc, char Uc, char Lc, unsigned char b) +{ +} + +void MethodsWithDefaultValues::defaultString(const wchar_t* wideString) { } diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 0db2cd98..5f55bca0 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -423,7 +423,8 @@ public: void defaultVoidStar(void* ptr = 0); void defaultFunctionPointer(void(*functionPtr)(int p) = nullptr); void defaultValueType(QGenericArgument valueType = QGenericArgument()); - void defaultChar(char c = 'a', char uc = u'u', char Uc = U'U', char Lc = L'L'); + void defaultChar(char c = 'a', char uc = u'u', char Uc = U'U', char Lc = L'L', unsigned char b = 'z'); + void defaultString(const wchar_t* wideString = L"Str"); void defaultEmptyChar(char c = 0); void defaultEmptyEnum(Empty e = Empty(-1)); void defaultRefTypeBeforeOthers(Foo foo = Foo(), int i = 5, Bar::Items item = Bar::Item2);