Example #1
0
        public override TypePrinterResult VisitPointerType(PointerType pointer,
                                                           TypeQualifiers quals)
        {
            var pointee = pointer.Pointee.Desugar();

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;
                return(string.Format("{0}^", function.Visit(this, quals)));
            }

            if (CSharpTypePrinter.IsConstCharString(pointer))
            {
                return("System::String^");
            }

            // From http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx
            // Any of the following types may be a pointer type:
            // * sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.
            // * Any enum type.
            // * Any pointer type.
            // * Any user-defined struct type that contains fields of unmanaged types only.
            var finalPointee = pointer.GetFinalPointee();

            if (finalPointee.IsPrimitiveType())
            {
                // Skip one indirection if passed by reference
                bool isRefParam = Parameter != null && (Parameter.IsOut || Parameter.IsInOut);
                if (isRefParam)
                {
                    return(pointer.QualifiedPointee.Visit(this));
                }

                if (pointee.IsPrimitiveType(PrimitiveType.Void))
                {
                    return("::System::IntPtr");
                }

                var result = pointer.QualifiedPointee.Visit(this).ToString();
                return(!isRefParam && result == "::System::IntPtr" ? "void**" : result + "*");
            }

            Enumeration @enum;

            if (pointee.TryGetEnum(out @enum))
            {
                var typeName = @enum.Visit(this);

                // Skip one indirection if passed by reference
                if (Parameter != null && (Parameter.IsOut || Parameter.IsInOut) &&
                    pointee == finalPointee)
                {
                    return(string.Format("{0}", typeName));
                }

                return(string.Format("{0}*", typeName));
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
Example #2
0
 public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
 {
     var type = ctx.Parameter.Type.Desugar();
     ClassTemplateSpecialization basicString = GetBasicString(type);
     var typePrinter = new CSharpTypePrinter(ctx.Driver);
     typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
     if (!ctx.Parameter.Type.Desugar().IsAddress())
         ctx.Return.Write("*({0}*) ", basicString.Visit(typePrinter));
     typePrinter.PopContext();
     var allocator = ctx.Driver.ASTContext.FindClass("allocator", false, true).First(
         a => a.IsSupportedStdType());
     if (type.IsPointer() || (type.IsReference() && ctx.Declaration is Field))
     {
         ctx.Return.Write("new {0}({1}, new {2}()).{3}",
             basicString.Visit(typePrinter), ctx.Parameter.Name,
             allocator.Visit(typePrinter), Helpers.InstanceIdentifier);
     }
     else
     {
         string varBasicString = "__basicString" + ctx.ParameterIndex;
         ctx.SupportBefore.WriteLine("using (var {0} = new {1}({2}, new {3}()))",
             varBasicString, basicString.Visit(typePrinter),
             ctx.Parameter.Name, allocator.Visit(typePrinter));
         ctx.SupportBefore.WriteStartBraceIndent();
         ctx.Return.Write("{0}.{1}", varBasicString, Helpers.InstanceIdentifier);
         ctx.HasCodeBlock = true;
     }
 }
Example #3
0
 public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
 {
     var type = ctx.Parameter.Type.Desugar();
     ClassTemplateSpecialization basicString = GetBasicString(type);
     var typePrinter = new CSharpTypePrinter(ctx.Context);
     typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
     if (!ctx.Parameter.Type.Desugar().IsAddress())
         ctx.Return.Write("*({0}*) ", basicString.Visit(typePrinter));
     typePrinter.PopContext();
     var allocator = ctx.Context.ASTContext.FindClass("allocator", false, true).First(
         a => a.IsDependent);
     if (type.IsPointer() || (type.IsReference() && ctx.Declaration is Field))
     {
         ctx.Return.Write("new {0}({1}, new {2}()).{3}",
             basicString.Visit(typePrinter), ctx.Parameter.Name,
             allocator.Visit(typePrinter), Helpers.InstanceIdentifier);
     }
     else
     {
         string varAllocator = "__allocator" + ctx.ParameterIndex;
         string varBasicString = "__basicString" + ctx.ParameterIndex;
         ctx.SupportBefore.WriteLine("var {0} = new {1}();",
             varAllocator, allocator.Visit(typePrinter));
         ctx.SupportBefore.WriteLine("var {0} = new {1}({2}, {3});",
             varBasicString, basicString.Visit(typePrinter),
             ctx.Parameter.Name, varAllocator);
         ctx.Return.Write("{0}.{1}", varBasicString, Helpers.InstanceIdentifier);
         ctx.Cleanup.WriteLine("{0}.Dispose({1});", varBasicString,
             type.IsPointer() ? "true" : "false");
         ctx.Cleanup.WriteLine("{0}.Dispose();", varAllocator);
     }
 }
Example #4
0
        public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
        {
            var type = ctx.ReturnType.Type.Desugar();
            ClassTemplateSpecialization basicString = GetBasicString(type);
            Declaration c_str = basicString.Methods.FirstOrDefault(m => m.OriginalName == "c_str");

            if (!c_str.IsGenerated)
            {
                c_str = basicString.Properties.First(p => p.OriginalName == "c_str");
            }
            var typePrinter = new CSharpTypePrinter(ctx.Context);

            if (type.IsAddress() || ctx.Declaration is Field)
            {
                ctx.Return.Write("{0}.{1}({2}).{3}{4}",
                                 basicString.Visit(typePrinter), Helpers.CreateInstanceIdentifier,
                                 ctx.ReturnVarName, c_str.Name, c_str is Method ? "()" : string.Empty);
            }
            else
            {
                const string varBasicString = "__basicStringRet";
                ctx.SupportBefore.WriteLine("using (var {0} = {1}.{2}({3}))",
                                            varBasicString, basicString.Visit(typePrinter),
                                            Helpers.CreateInstanceIdentifier, ctx.ReturnVarName);
                ctx.SupportBefore.WriteStartBraceIndent();
                ctx.Return.Write("{0}.{1}{2}", varBasicString, c_str.Name,
                                 c_str is Method ? "()" : string.Empty);
                ctx.HasCodeBlock = true;
            }
        }
Example #5
0
        public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
        {
            Type type = ctx.Parameter.Type.Desugar();
            ClassTemplateSpecialization basicString = GetBasicString(type);
            var typePrinter = new CSharpTypePrinter(ctx.Context);

            if (!ctx.Parameter.Type.Desugar().IsAddress() &&
                ctx.MarshalKind != MarshalKind.NativeField)
            {
                ctx.Return.Write($"*({typePrinter.PrintNative(basicString)}*) ");
            }
            string qualifiedBasicString = GetQualifiedBasicString(basicString);
            var    assign = basicString.Methods.First(m => m.OriginalName == "assign");

            if (ctx.MarshalKind == MarshalKind.NativeField)
            {
                ctx.Return.Write($@"{qualifiedBasicString}Extensions.{
                    Helpers.InternalStruct}.{assign.Name}(new {
                    typePrinter.IntPtrType}(&{
                    ctx.ReturnVarName}), {ctx.Parameter.Name})");
                ctx.ReturnVarName = string.Empty;
            }
            else
            {
                var varBasicString = $"__basicString{ctx.ParameterIndex}";
                ctx.Before.WriteLine($@"var {varBasicString} = new {
                    basicString.Visit(typePrinter)}();");
                ctx.Before.WriteLine($@"{qualifiedBasicString}Extensions.{
                    assign.Name}({varBasicString}, {ctx.Parameter.Name});");
                ctx.Return.Write($"{varBasicString}.{Helpers.InstanceIdentifier}");
                ctx.Cleanup.WriteLine($@"{varBasicString}.Dispose({
                    (!Type.IsAddress() || ctx.Parameter?.IsIndirect == true ? "false" : string.Empty)});");
            }
        }
Example #6
0
        public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
        {
            var type = Type.Desugar(resolveTemplateSubstitution: false);
            ClassTemplateSpecialization basicString = GetBasicString(type);
            var    c_str                = basicString.Methods.First(m => m.OriginalName == "c_str");
            var    typePrinter          = new CSharpTypePrinter(ctx.Context);
            string qualifiedBasicString = GetQualifiedBasicString(basicString);
            string varBasicString       = $"__basicStringRet{ctx.ParameterIndex}";

            ctx.Before.WriteLine($@"var {varBasicString} = {
                basicString.Visit(typePrinter)}.{Helpers.CreateInstanceIdentifier}({
                ctx.ReturnVarName});");
            if (type.IsAddress())
            {
                ctx.Return.Write($@"{qualifiedBasicString}Extensions.{c_str.Name}({
                    varBasicString})");
            }
            else
            {
                string varString = $"__stringRet{ctx.ParameterIndex}";
                ctx.Before.WriteLine($@"var {varString} = {
                    qualifiedBasicString}Extensions.{c_str.Name}({varBasicString});");
                ctx.Before.WriteLine($"{varBasicString}.Dispose(false);");
                ctx.Return.Write(varString);
            }
        }
        private TypePrinter GetTypePrinter(GeneratorKind kind, BindingContext context)
        {
            TypePrinter typePrinter;

            switch (kind)
            {
            case GeneratorKind.C:
                typePrinter = new CppTypePrinter(Context)
                {
                    PrintFlavorKind = CppTypePrintFlavorKind.C
                };
                break;

            case GeneratorKind.CPlusPlus:
            case GeneratorKind.QuickJS:
            case GeneratorKind.NAPI:
            case GeneratorKind.TypeScript:
                typePrinter = new CppTypePrinter(Context);
                break;

            case GeneratorKind.CLI:
                typePrinter = new CLITypePrinter(Context);
                break;

            case GeneratorKind.CSharp:
                typePrinter = new CSharpTypePrinter(Context);
                break;

            default:
                throw new System.NotImplementedException();
            }

            return(typePrinter);
        }
Example #8
0
        public override Type CSharpSignatureType(TypePrinterContext ctx)
        {
            if (ctx.Kind == TypePrinterContextKind.Managed)
            {
                return(new CILType(typeof(string)));
            }

            if (ctx.Parameter == null || ctx.Parameter.Name == Helpers.ReturnIdentifier)
            {
                var typePrinter = new CSharpTypePrinter(Context);
                return(new CustomType(typePrinter.IntPtrType));
            }

            if (Context.Options.Encoding == Encoding.ASCII)
            {
                return(new CustomType("[MarshalAs(UnmanagedType.LPStr)] string"));
            }

            if (Context.Options.Encoding == Encoding.Unicode ||
                Context.Options.Encoding == Encoding.BigEndianUnicode)
            {
                return(new CustomType("[MarshalAs(UnmanagedType.LPWStr)] string"));
            }

            throw new System.NotSupportedException(
                      $"{Context.Options.Encoding.EncodingName} is not supported yet.");
        }
Example #9
0
 public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
 {
     var type = ctx.Parameter.Type.Desugar();
     ClassTemplateSpecialization basicString = GetBasicString(type);
     var typePrinter = new CSharpTypePrinter(ctx.Context);
     typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
     if (!ctx.Parameter.Type.Desugar().IsAddress())
         ctx.Return.Write("*({0}*) ", basicString.Visit(typePrinter));
     typePrinter.PopContext();
     var allocator = ctx.Context.ASTContext.FindClass("allocator", false, true).First(
         a => a.IsDependent && a.TranslationUnit.IsSystemHeader);
     if (type.IsPointer() || (type.IsReference() && ctx.Declaration is Field))
     {
         ctx.Return.Write("new {0}({1}, new {2}()).{3}",
             basicString.Visit(typePrinter), ctx.Parameter.Name,
             allocator.Visit(typePrinter), Helpers.InstanceIdentifier);
     }
     else
     {
         string varAllocator = "__allocator" + ctx.ParameterIndex;
         string varBasicString = "__basicString" + ctx.ParameterIndex;
         ctx.SupportBefore.WriteLine("var {0} = new {1}();",
             varAllocator, allocator.Visit(typePrinter));
         ctx.SupportBefore.WriteLine("var {0} = new {1}({2}, {3});",
             varBasicString, basicString.Visit(typePrinter),
             ctx.Parameter.Name, varAllocator);
         ctx.Return.Write("{0}.{1}", varBasicString, Helpers.InstanceIdentifier);
         ctx.Cleanup.WriteLine("{0}.Dispose({1});", varBasicString,
             type.IsPointer() ? "true" : "false");
         ctx.Cleanup.WriteLine("{0}.Dispose();", varAllocator);
     }
 }
 public CSharpGenerator(Driver driver)
     : base(driver)
 {
     typePrinter = new CSharpTypePrinter(driver);
     expressionPrinter = new CSharpExpressionPrinter();
     CppSharp.AST.Type.TypePrinterDelegate += type => type.Visit(typePrinter).Type;
 }
Example #11
0
 public override string CSharpSignature(CSharpTypePrinterContext ctx)
 {
     if (ctx.CSharpKind == CSharpTypePrinterContextKind.Managed)
         return "string";
     ClassTemplateSpecialization basicString = GetBasicString(ctx.Type);
     var typePrinter = new CSharpTypePrinter(null);
     typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
     return basicString.Visit(typePrinter).Type;
 }
Example #12
0
 public override string CSharpSignature(CSharpTypePrinterContext ctx)
 {
     if (ctx.CSharpKind == CSharpTypePrinterContextKind.Managed)
         return "string";
     ClassTemplateSpecialization basicString = GetBasicString(ctx.Type);
     var typePrinter = new CSharpTypePrinter(null);
     typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
     return basicString.Visit(typePrinter).Type;
 }
Example #13
0
        public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
        {
            // pointless, put just so that the generated code compiles
            var type           = (TemplateSpecializationType)ctx.Parameter.Type.Desugar();
            var specialization = type.GetClassTemplateSpecialization();
            var typePrinter    = new CSharpTypePrinter(null);

            typePrinter.PushContext(TypePrinterContextKind.Native);
            ctx.Return.Write("new {0}()", specialization.Visit(typePrinter));
        }
Example #14
0
        public override Type CSharpSignatureType(TypePrinterContext ctx)
        {
            if (ctx.Kind == TypePrinterContextKind.Managed)
            {
                return(new CILType(typeof(string)));
            }
            ClassTemplateSpecialization basicString = GetBasicString(ctx.Type);
            var typePrinter = new CSharpTypePrinter(null);

            typePrinter.PushContext(TypePrinterContextKind.Native);
            return(new CustomType(basicString.Visit(typePrinter).Type));
        }
Example #15
0
        private static bool CheckForEnumValue(BindingContext context, Type desugared, Statement statement,
                                              ref string result)
        {
            var enumItem = statement.Declaration as Enumeration.Item;

            if (enumItem != null)
            {
                return(true);
            }

            var call = statement.Declaration as Function;

            if (call != null && statement.String != "0")
            {
                var @params = regexFunctionParams.Match(statement.String).Groups[1].Value;
                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);
        }
Example #16
0
        public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
        {
            var type = Type.Desugar(resolveTemplateSubstitution: false);
            ClassTemplateSpecialization basicString = GetBasicString(type);
            var    data                 = basicString.Methods.First(m => m.OriginalName == "data");
            var    typePrinter          = new CSharpTypePrinter(ctx.Context);
            string qualifiedBasicString = GetQualifiedBasicString(basicString);
            string varBasicString       = $"__basicStringRet{ctx.ParameterIndex}";
            bool   usePointer           = type.IsAddress() || ctx.MarshalKind == MarshalKind.NativeField ||
                                          ctx.MarshalKind == MarshalKind.ReturnVariableArray;

            ctx.Before.WriteLine($@"var {varBasicString} = {
                basicString.Visit(typePrinter)}.{Helpers.CreateInstanceIdentifier}({
                (usePointer ? string.Empty : $"new {typePrinter.IntPtrType}(&")}{
Example #17
0
        public override string CSharpSignature(TypePrinterContext ctx)
        {
            if (ctx.Kind == TypePrinterContextKind.Native)
            {
                var type           = (TemplateSpecializationType)ctx.Type.Desugar();
                var specialization = type.GetClassTemplateSpecialization();
                var typePrinter    = new CSharpTypePrinter(null);
                typePrinter.PushContext(TypePrinterContextKind.Native);
                return(string.Format($"{specialization.Visit(typePrinter)}{(Type.IsAddress() ? "*" : string.Empty)}", specialization.Visit(typePrinter),
                                     Type.IsAddress() ? "*" : string.Empty));
            }

            return(string.Format("System.Collections.Generic.{0}<{1}>",
                                 ctx.MarshalKind == MarshalKind.DefaultExpression ? "List" : "IList",
                                 ctx.GetTemplateParameterList()));
        }
Example #18
0
        public override bool VisitASTContext(ASTContext context)
        {
            TypePrinter typePrinter = null;

            switch (Options.GeneratorKind)
            {
            case GeneratorKind.CLI:
                typePrinter = new CLITypePrinter(Context);
                break;

            case GeneratorKind.CSharp:
                typePrinter = new CSharpTypePrinter(Context);
                break;
            }
            DeclarationName.ParameterTypeComparer.TypePrinter = typePrinter;
            return(base.VisitASTContext(context));
        }
Example #19
0
        public static System.Type GetSystemType(BindingContext context, Type type)
        {
            if (context.TypeMaps.FindTypeMap(type, out TypeMap typeMap))
            {
                var cilType = typeMap.CSharpSignatureType(new TypePrinterContext {
                    Type = type, Kind = TypePrinterContextKind.Managed
                }) as CILType;
                if (cilType != null)
                {
                    return(cilType.Type);
                }
            }

            if (type is BuiltinType builtInType)
            {
                if (builtInType.Type == PrimitiveType.Float)
                {
                    return(typeof(float));
                }
                else if (builtInType.Type == PrimitiveType.Double)
                {
                    return(typeof(double));
                }

                try
                {
                    CSharpTypePrinter.GetPrimitiveTypeWidth(builtInType.Type, context.TargetInfo, out var w, out var signed);
                    var cilType = (signed ? CSharpTypePrinter.GetSignedType(w) : CSharpTypePrinter.GetUnsignedType(w)) as CILType;
                    if (cilType != null)
                    {
                        return(cilType.Type);
                    }
                }
                catch
                {
                    return(null);
                }
            }

            return(null);
        }
Example #20
0
        public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
        {
            var type = ctx.Parameter.Type.Desugar();
            ClassTemplateSpecialization basicString = GetBasicString(type);
            var typePrinter = new CSharpTypePrinter(ctx.Context);

            typePrinter.PushContext(TypePrinterContextKind.Native);
            if (!ctx.Parameter.Type.Desugar().IsAddress())
            {
                ctx.Return.Write($"*({basicString.Visit(typePrinter)}*) ");
            }
            typePrinter.PopContext();
            var allocator = ctx.Context.ASTContext.FindClass("allocator", false, true).First(
                a => a.IsDependent && a.TranslationUnit.IsSystemHeader);
            var    allocatorChar        = allocator.Specializations.First(s => !s.Ignore);
            string qualifiedBasicString = GetQualifiedBasicString(basicString);

            if (type.IsPointer() || (type.IsReference() && ctx.Declaration is Field))
            {
                ctx.Return.Write($@"{qualifiedBasicString}Extensions.{basicString.Name}({
                    ctx.Parameter.Name}, new {allocatorChar.Visit(typePrinter)}()).{
                    Helpers.InstanceIdentifier}");
            }
            else
            {
                var varAllocator   = $"__allocator{ctx.ParameterIndex}";
                var varBasicString = $"__basicString{ctx.ParameterIndex}";
                ctx.Before.WriteLine($@"var {varAllocator} = new {
                    allocatorChar.Visit(typePrinter)}();");
                ctx.Before.WriteLine($@"var {varBasicString} = {
                    qualifiedBasicString}Extensions.{basicString.Name}({ctx.Parameter.Name}, {
                    varAllocator});");
                ctx.Return.Write($"{varBasicString}.{Helpers.InstanceIdentifier}");
                ctx.Cleanup.WriteLine($@"{varBasicString}.Dispose({
                    (type.IsPointer() ? "true" : "false")});");
                ctx.Cleanup.WriteLine($"{varAllocator}.Dispose();");
            }
        }
Example #21
0
        public override Type CSharpSignatureType(TypePrinterContext ctx)
        {
            if (ctx.Kind == TypePrinterContextKind.Managed)
            {
                return(new CILType(typeof(string)));
            }

            if (ctx.Parameter == null || ctx.Parameter.Name == Helpers.ReturnIdentifier)
            {
                var typePrinter = new CSharpTypePrinter(Context);
                return(new CustomType(typePrinter.IntPtrType));
            }

            var(encoding, _) = GetEncoding();

            if (encoding == Encoding.ASCII || encoding == Encoding.Default)
            {
                // This is not really right. ASCII is 7-bit only - the 8th bit is stripped; ANSI has
                // multi-byte support via a code page. MarshalAs(UnmanagedType.LPStr) marshals as ANSI.
                // Perhaps we need a CppSharp.Runtime.ASCIIMarshaller?
                return(new CustomType("[MarshalAs(UnmanagedType.LPStr)] string"));
            }
            else if (encoding == Encoding.UTF8)
            {
                return(new CustomType("[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CppSharp.Runtime.UTF8Marshaller))] string"));
            }
            else if (encoding == Encoding.Unicode || encoding == Encoding.BigEndianUnicode)
            {
                return(new CustomType("[MarshalAs(UnmanagedType.LPWStr)] string"));
            }
            else if (encoding == Encoding.UTF32)
            {
                return(new CustomType("[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CppSharp.Runtime.UTF32Marshaller))] string"));
            }

            throw new System.NotSupportedException(
                      $"{Context.Options.Encoding.EncodingName} is not supported yet.");
        }
Example #22
0
        private string GenerateDelegateSignature(IEnumerable <Parameter> @params, QualifiedType returnType)
        {
            var typePrinter = new CSharpTypePrinter(Driver);

            typePrinter.PushContext(CSharpTypePrinterContextKind.Native);

            var typesBuilder = new StringBuilder();

            if (!returnType.Type.IsPrimitiveType(PrimitiveType.Void))
            {
                typesBuilder.Insert(0, returnType.Type.CSharpType(typePrinter));
                typesBuilder.Append('_');
            }
            foreach (var parameter in @params)
            {
                typesBuilder.Append(parameter.CSharpType(typePrinter));
                typesBuilder.Append('_');
            }
            if (typesBuilder.Length > 0)
            {
                typesBuilder.Remove(typesBuilder.Length - 1, 1);
            }
            var delegateName = typesBuilder.Replace("global::System.", string.Empty).Replace(
                "*", "Ptr").Replace('.', '_').ToString();

            if (returnType.Type.IsPrimitiveType(PrimitiveType.Void))
            {
                delegateName = "Action_" + delegateName;
            }
            else
            {
                delegateName = "Func_" + delegateName;
            }

            typePrinter.PopContext();
            return(delegateName);
        }
Example #23
0
 public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
 {
     ctx.SupportBefore.WriteLine("var __stringPtr{0} = ReferenceEquals({1}, null) ? null : (ushort*) Marshal.StringToHGlobalUni({1}).ToPointer();",
                                 ctx.ParameterIndex, ctx.Parameter.Name);
     ctx.SupportBefore.WriteLine("var __qstring{0} = __stringPtr{0} == null ? null : QtCore.QString.FromUtf16(ref *__stringPtr{0}, {1}.Length);",
                                 ctx.ParameterIndex, ctx.Parameter.Name);
     var type = ctx.Parameter.Type.Desugar();
     if (type.IsAddress())
     {
         ctx.Return.Write("ReferenceEquals(__qstring{0}, null) ? global::System.IntPtr.Zero : __qstring{0}.{1}",
                          ctx.ParameterIndex, Helpers.InstanceIdentifier);
         return;
     }
     Class @class;
     type.TryGetClass(out @class);
     if (@class == null)
     {
         this.Type.TryGetClass(out @class);
     }
     this.typePrinter = this.typePrinter ?? (this.typePrinter = new CSharpTypePrinter(ctx.Context));
     var qualifiedIdentifier = (@class.OriginalClass ?? @class).Visit(this.typePrinter);
     ctx.Return.Write("ReferenceEquals(__qstring{0}, null) ? new {1}.{2}() : *({1}.{2}*) (__qstring{0}.{3})",
                      ctx.ParameterIndex, qualifiedIdentifier, Helpers.InternalStruct, Helpers.InstanceIdentifier);
 }
Example #24
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            if (pointee.IsPrimitiveType(PrimitiveType.Void))
            {
                Context.Return.Write("::System::IntPtr({0})", Context.ReturnVarName);
                return(true);
            }

            if (CSharpTypePrinter.IsConstCharString(pointer))
            {
                Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName,
                                                            pointer.Pointee.Desugar() as BuiltinType));
                return(true);
            }

            PrimitiveType primitive;
            var           param = Context.Parameter;

            if (param != null && (param.IsOut || param.IsInOut) &&
                pointee.IsPrimitiveType(out primitive))
            {
                Context.Return.Write(Context.ReturnVarName);
                return(true);
            }

            if (pointee.IsPrimitiveType(out primitive))
            {
                var returnVarName = Context.ReturnVarName;
                if (quals.IsConst != Context.ReturnType.Qualifiers.IsConst)
                {
                    var nativeTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase, false);
                    var returnType        = Context.ReturnType.Type.Desugar();
                    var constlessPointer  = new PointerType()
                    {
                        IsDependent      = pointer.IsDependent,
                        Modifier         = pointer.Modifier,
                        QualifiedPointee = new QualifiedType(returnType.GetPointee())
                    };
                    var nativeConstlessTypeName = constlessPointer.Visit(nativeTypePrinter, new TypeQualifiers());
                    returnVarName = string.Format("const_cast<{0}>({1})",
                                                  nativeConstlessTypeName, Context.ReturnVarName);
                }
                if (pointer.Pointee is TypedefType)
                {
                    var desugaredPointer = new PointerType()
                    {
                        IsDependent      = pointer.IsDependent,
                        Modifier         = pointer.Modifier,
                        QualifiedPointee = new QualifiedType(pointee)
                    };
                    var nativeTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                    var nativeTypeName    = desugaredPointer.Visit(nativeTypePrinter, quals);
                    Context.Return.Write("reinterpret_cast<{0}>({1})", nativeTypeName,
                                         returnVarName);
                }
                else
                {
                    Context.Return.Write(returnVarName);
                }
                return(true);
            }

            TypeMap typeMap = null;

            Context.Driver.TypeDatabase.FindTypeMap(pointee, out typeMap);

            Class @class;

            if (pointee.TryGetClass(out @class) && typeMap == null)
            {
                var instance = (pointer.IsReference) ? "&" + Context.ReturnVarName
                    : Context.ReturnVarName;
                WriteClassInstance(@class, instance);
                return(true);
            }

            return(pointer.Pointee.Visit(this, quals));
        }
Example #25
0
 public override Type CSharpSignatureType(TypePrinterContext ctx) =>
 CSharpTypePrinter.GetUnsignedType(Context.TargetInfo.LongWidth);
Example #26
0
 public CSharpGenerator(BindingContext context) : base(context)
 {
     typePrinter = new CSharpTypePrinter(context);
     expressionPrinter = new CSharpExpressionPrinter(typePrinter);
 }
Example #27
0
        private bool?CheckForDefaultConstruct(Type desugared, Expression arg, TypeQualifiers qualifiers)
        {
            // Unwrapping the underlying type behind a possible pointer/reference
            Type type = desugared.GetFinalPointee() ?? desugared;

            Class decl;

            if (!type.TryGetClass(out decl))
            {
                return(false);
            }

            var ctor = arg.Declaration as Method;

            TypeMap typeMap;
            var     typePrinterContext = new CSharpTypePrinterContext
            {
                CSharpKind = CSharpTypePrinterContextKind.DefaultExpression,
                Type       = type
            };

            string typePrinterResult = null;

            if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap))
            {
                var         typeInSignature = typeMap.CSharpSignatureType(typePrinterContext).SkipPointerRefs();
                Enumeration @enum;
                if (typeInSignature.TryGetEnum(out @enum))
                {
                    return(false);
                }

                if (ctor == null || !ctor.IsConstructor)
                {
                    return(false);
                }

                typePrinterResult = typeMap.CSharpSignature(typePrinterContext);
                if (typePrinterResult == "string" && ctor.Parameters.Count == 0)
                {
                    arg.String = "\"\"";
                    return(true);
                }
            }

            var match = regexCtor.Match(arg.String);

            if (match.Success)
            {
                if (ctor != null)
                {
                    var templateSpecializationType = type as TemplateSpecializationType;
                    var typePrinter = new CSharpTypePrinter(Driver);
                    typePrinterResult = typePrinterResult ?? (templateSpecializationType != null
                        ? typePrinter.VisitTemplateSpecializationType(templateSpecializationType, qualifiers)
                        : typePrinter.VisitClassDecl((Class)ctor.Namespace)).Type;

                    arg.String = string.Format("new {0}{1}", typePrinterResult, match.Groups[2].Value);
                    if (ctor.Parameters.Count > 0 && ctor.Parameters[0].Type.IsAddress())
                    {
                        arg.String = arg.String.Replace("(0)", "()");
                    }
                }
                else
                {
                    arg.String = string.Format("new {0}", arg.String);
                }
            }
            else
            {
                if (ctor != null && ctor.Parameters.Count > 0)
                {
                    var         finalPointee = ctor.Parameters[0].Type.SkipPointerRefs().Desugar();
                    Enumeration @enum;
                    if (finalPointee.TryGetEnum(out @enum))
                    {
                        TranslateEnumExpression(arg, finalPointee, arg.String);
                    }
                }
            }

            return(decl.IsValueType ? true : (bool?)null);
        }
Example #28
0
 public CSharpGenerator(Driver driver)
     : base(driver)
 {
     typePrinter = new CSharpTypePrinter(driver.TypeDatabase, driver.ASTContext);
     CppSharp.AST.Type.TypePrinterDelegate += type => type.Visit(typePrinter).Type;
 }
        private bool?CheckForDefaultConstruct(Type desugared, Statement statement,
                                              ref string result)
        {
            var type = desugared.GetFinalPointee() ?? desugared;

            Class decl;

            if (!type.TryGetClass(out decl))
            {
                return(false);
            }

            var ctor = statement as CXXConstructExpr;

            TypeMap typeMap;

            var typePrinter = new CSharpTypePrinter(Driver);

            typePrinter.PushContext(CSharpTypePrinterContextKind.DefaultExpression);
            var typePrinterResult = type.Visit(typePrinter).Type;

            if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap))
            {
                var typeInSignature = typeMap.CSharpSignatureType(
                    typePrinter.Context).SkipPointerRefs().Desugar();
                Enumeration @enum;
                if (typeInSignature.TryGetEnum(out @enum))
                {
                    if (ctor != null &&
                        (ctor.Arguments.Count == 0 ||
                         HasSingleZeroArgExpression((Function)ctor.Declaration)))
                    {
                        result = "0";
                        return(true);
                    }
                    return(false);
                }

                if (ctor != null && typePrinterResult == "string" && ctor.Arguments.Count == 0)
                {
                    result = "\"\"";
                    return(true);
                }
            }

            if (ctor == null)
            {
                return(decl.IsValueType ? (bool?)false : null);
            }

            var method = (Method)statement.Declaration;
            var expressionSupported = decl.IsValueType && method.Parameters.Count == 0;

            if (statement.String.Contains('('))
            {
                var argsBuilder = new StringBuilder("new ");
                argsBuilder.Append(typePrinterResult);
                argsBuilder.Append('(');
                for (var i = 0; i < ctor.Arguments.Count; i++)
                {
                    var argument  = ctor.Arguments[i];
                    var argResult = argument.String;
                    expressionSupported &= PrintExpression(method.Parameters[i].Type.Desugar(),
                                                           argument, ref argResult) ?? false;
                    argsBuilder.Append(argResult);
                    if (i < ctor.Arguments.Count - 1)
                    {
                        argsBuilder.Append(", ");
                    }
                }
                argsBuilder.Append(')');
                result = argsBuilder.ToString();
            }
            else
            {
                if (method.Parameters.Count > 0)
                {
                    var         paramType = method.Parameters[0].Type.SkipPointerRefs().Desugar();
                    Enumeration @enum;
                    if (paramType.TryGetEnum(out @enum))
                    {
                        result = TranslateEnumExpression(method, paramType, statement.String);
                    }
                }
            }
            return(expressionSupported ? true : (bool?)null);
        }
Example #30
0
 public CSharpGenerator(Driver driver) : base(driver)
 {
     typePrinter = new CSharpTypePrinter(driver);
     expressionPrinter = new CSharpExpressionPrinter(typePrinter);
 }
        private bool?CheckForDefaultConstruct(Type desugared, Expression expression,
                                              ref string result)
        {
            var type = desugared.GetFinalPointee() ?? desugared;

            Class decl;

            if (!type.TryGetClass(out decl))
            {
                return(false);
            }

            var ctor = expression as CXXConstructExpr;

            var typePrinter = new CSharpTypePrinter(Context);

            typePrinter.PushMarshalKind(MarshalKind.DefaultExpression);

            var typePrinterResult = type.Visit(typePrinter).Type;

            TypeMap typeMap;

            if (TypeMaps.FindTypeMap(decl, type, out typeMap))
            {
                var typePrinterContext = new TypePrinterContext()
                {
                    Kind        = typePrinter.Kind,
                    MarshalKind = typePrinter.MarshalKind,
                    Type        = type
                };

                var typeInSignature = typeMap.CSharpSignatureType(typePrinterContext)
                                      .SkipPointerRefs().Desugar();

                Enumeration @enum;
                if (typeInSignature.TryGetEnum(out @enum))
                {
                    if (ctor != null &&
                        (ctor.Arguments.Count == 0 ||
                         HasSingleZeroArgExpression((Function)ctor.Declaration)))
                    {
                        result = "0";
                        return(true);
                    }
                    return(false);
                }

                if (ctor != null && typePrinterResult == "string" && ctor.Arguments.Count == 0)
                {
                    result = "\"\"";
                    return(true);
                }
            }

            if (ctor == null)
            {
                CheckForSimpleExpressions(expression, ref result, desugared);
                return(decl.IsValueType ? (bool?)false : null);
            }

            var method = (Method)expression.Declaration;
            var expressionSupported = decl.IsValueType && method.Parameters.Count == 0;

            if (expression.String.Contains('('))
            {
                var argsBuilder = new StringBuilder("new ");
                argsBuilder.Append(typePrinterResult);
                argsBuilder.Append('(');
                for (var i = 0; i < ctor.Arguments.Count; i++)
                {
                    var argument  = ctor.Arguments[i];
                    var argResult = argument.String;
                    expressionSupported &= PrintExpression(method,
                                                           method.Parameters[i].Type.Desugar(), argument, ref argResult) ?? false;
                    argsBuilder.Append(argResult);
                    if (i < ctor.Arguments.Count - 1)
                    {
                        argsBuilder.Append(", ");
                    }
                }
                argsBuilder.Append(')');
                result = argsBuilder.ToString();
            }
            return(expressionSupported ? true : (bool?)null);
        }
Example #32
0
        private string GenerateDelegateSignature(IEnumerable<Parameter> @params, QualifiedType returnType)
        {
            var typePrinter = new CSharpTypePrinter(Driver);
            typePrinter.PushContext(CSharpTypePrinterContextKind.Native);

            var typesBuilder = new StringBuilder();
            if (!returnType.Type.IsPrimitiveType(PrimitiveType.Void))
            {
                typesBuilder.Insert(0, returnType.Type.CSharpType(typePrinter));
                typesBuilder.Append('_');
            }
            foreach (var parameter in @params)
            {
                typesBuilder.Append(parameter.CSharpType(typePrinter));
                typesBuilder.Append('_');
            }
            if (typesBuilder.Length > 0)
                typesBuilder.Remove(typesBuilder.Length - 1, 1);
            var delegateName = typesBuilder.Replace("global::System.", string.Empty).Replace(
                "*", "Ptr").Replace('.', '_').ToString();
            if (returnType.Type.IsPrimitiveType(PrimitiveType.Void))
                delegateName = "Action_" + delegateName;
            else
                delegateName = "Func_" + delegateName;

            typePrinter.PopContext();
            return delegateName;
        }
        private bool? CheckForDefaultConstruct(Type desugared, Statement arg,
            TypeQualifiers qualifiers)
        {
            // Unwrapping the underlying type behind a possible pointer/reference
            Type type = desugared.GetFinalPointee() ?? desugared;

            Class decl;
            if (!type.TryGetClass(out decl))
                return false;

            var ctor = arg.Declaration as Method;

            TypeMap typeMap;
            var typePrinterContext = new CSharpTypePrinterContext
            {
                CSharpKind = CSharpTypePrinterContextKind.DefaultExpression,
                Type = type
            };

            string typePrinterResult = null;
            if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap))
            {
                var typeInSignature = typeMap.CSharpSignatureType(
                    typePrinterContext).SkipPointerRefs().Desugar();
                Enumeration @enum;
                if (typeInSignature.TryGetEnum(out @enum))
                    return false;

                if (ctor == null || !ctor.IsConstructor)
                    return false;

                typePrinterResult = typeMap.CSharpSignature(typePrinterContext);
                if (typePrinterResult == "string" && ctor.Parameters.Count == 0)
                {
                    arg.String = "\"\"";
                    return true;
                }
            }

            var match = regexCtor.Match(arg.String);
            if (match.Success)
            {
                if (ctor != null)
                {
                    var templateSpecializationType = type as TemplateSpecializationType;
                    var typePrinter = new CSharpTypePrinter(Driver);
                    typePrinterResult = typePrinterResult ?? (templateSpecializationType != null
                        ? typePrinter.VisitTemplateSpecializationType(
                            templateSpecializationType, qualifiers)
                        : typePrinter.VisitClassDecl((Class) ctor.Namespace)).Type;

                    arg.String = string.Format("new {0}{1}", typePrinterResult,
                        match.Groups[2].Value);
                    if (ctor.Parameters.Count > 0 && ctor.Parameters[0].Type.IsAddress())
                        arg.String = arg.String.Replace("(0)", "()");
                }
                else
                    arg.String = string.Format("new {0}", arg.String);
            }
            else
            {
                if (ctor != null && ctor.Parameters.Count > 0)
                {
                    var finalPointee = ctor.Parameters[0].Type.SkipPointerRefs().Desugar();
                    Enumeration @enum;
                    if (finalPointee.TryGetEnum(out @enum))
                        TranslateEnumExpression(ctor, arg, finalPointee, arg.String);
                }
            }

            return decl.IsValueType ? true : (bool?) null;
        }
Example #34
0
 public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
 {
     var type = ctx.ReturnType.Type;
     ClassTemplateSpecialization basicString = GetBasicString(type);
     Declaration c_str = basicString.Methods.FirstOrDefault(m => m.OriginalName == "c_str");
     if (!c_str.IsGenerated)
         c_str = basicString.Properties.First(p => p.OriginalName == "c_str");
     var typePrinter = new CSharpTypePrinter(ctx.Context);
     if (type.IsPointer() || ctx.Declaration is Field)
     {
         ctx.Return.Write("{0}.{1}({2}).{3}{4}",
             basicString.Visit(typePrinter), Helpers.CreateInstanceIdentifier,
             ctx.ReturnVarName, c_str.Name, c_str is Method ? "()" : string.Empty);
     }
     else
     {
         const string varBasicString = "__basicStringRet";
         ctx.SupportBefore.WriteLine("using (var {0} = {1}.{2}({3}))",
             varBasicString, basicString.Visit(typePrinter),
             Helpers.CreateInstanceIdentifier, ctx.ReturnVarName);
         ctx.SupportBefore.WriteStartBraceIndent();
         ctx.Return.Write("{0}.{1}{2}", varBasicString, c_str.Name,
             c_str is Method ? "()" : string.Empty);
         ctx.HasCodeBlock = true;
     }
 }
        private bool? CheckForDefaultConstruct(Type desugared, Expression expression,
            ref string result)
        {
            var type = desugared.GetFinalPointee() ?? desugared;

            Class decl;
            if (!type.TryGetClass(out decl))
                return false;

            var ctor = expression as CXXConstructExpr;

            TypeMap typeMap;

            var typePrinter = new CSharpTypePrinter(Context);
            typePrinter.PushMarshalKind(CSharpMarshalKind.DefaultExpression);
            var typePrinterResult = type.Visit(typePrinter).Type;
            if (TypeMaps.FindTypeMap(decl, type, out typeMap))
            {
                var typeInSignature = typeMap.CSharpSignatureType(
                    typePrinter.TypePrinterContext).SkipPointerRefs().Desugar();
                Enumeration @enum;
                if (typeInSignature.TryGetEnum(out @enum))
                {
                    if (ctor != null &&
                        (ctor.Arguments.Count == 0 ||
                         HasSingleZeroArgExpression((Function) ctor.Declaration)))
                    {
                        result = "0";
                        return true;
                    }
                    return false;
                }

                if (ctor != null && typePrinterResult == "string" && ctor.Arguments.Count == 0)
                {
                    result = "\"\"";
                    return true;
                }
            }

            if (ctor == null)
            {
                CheckForSimpleExpressions(expression, ref result, desugared);
                return decl.IsValueType ? (bool?) false : null;
            }

            var method = (Method) expression.Declaration;
            var expressionSupported = decl.IsValueType && method.Parameters.Count == 0;

            if (expression.String.Contains('('))
            {
                var argsBuilder = new StringBuilder("new ");
                argsBuilder.Append(typePrinterResult);
                argsBuilder.Append('(');
                for (var i = 0; i < ctor.Arguments.Count; i++)
                {
                    var argument = ctor.Arguments[i];
                    var argResult = argument.String;
                    expressionSupported &= PrintExpression(method.Parameters[i].Type.Desugar(),
                        argument, ref argResult) ?? false;
                    argsBuilder.Append(argResult);
                    if (i < ctor.Arguments.Count - 1)
                        argsBuilder.Append(", ");
                }
                argsBuilder.Append(')');
                result = argsBuilder.ToString();
            }
            else
            {
                if (method.Parameters.Count > 0)
                {
                    var paramType = method.Parameters[0].Type.SkipPointerRefs().Desugar();
                    Enumeration @enum;
                    if (paramType.TryGetEnum(out @enum))
                        result = TranslateEnumExpression(method, paramType, expression.String);
                }
            }
            return expressionSupported ? true : (bool?) null;
        }