示例#1
0
        public CSharpTypePrinterResult VisitArrayType(ArrayType array,
                                                      TypeQualifiers quals)
        {
            if (ContextKind == CSharpTypePrinterContextKind.Native &&
                array.SizeType == ArrayType.ArraySize.Constant)
            {
                Type arrayType = array.Type.Desugar();

                PrimitiveType primitiveType;
                if (arrayType.IsPointerToPrimitiveType(out primitiveType) &&
                    !(arrayType is FunctionType))
                {
                    if (primitiveType == PrimitiveType.Void)
                    {
                        return("void**");
                    }
                    return(string.Format("{0}*", array.Type.Visit(this, quals)));
                }

                Class @class;
                if (arrayType.TryGetClass(out @class))
                {
                    return(new CSharpTypePrinterResult()
                    {
                        Type = "fixed byte",
                        NameSuffix = string.Format("[{0}]", array.Size * @class.Layout.Size)
                    });
                }

                var arrayElemType = array.Type.Visit(this, quals).ToString();

                // C# does not support fixed arrays of machine pointer type (void* or IntPtr).
                // In that case, replace it by a pointer to an integer type of the same size.
                if (arrayElemType == IntPtrType)
                {
                    arrayElemType = driver.TargetInfo.PointerWidth == 64 ? "long" : "int";
                }

                // Do not write the fixed keyword multiple times for nested array types
                var fixedKeyword = array.Type is ArrayType ? string.Empty : "fixed ";
                return(new CSharpTypePrinterResult()
                {
                    Type = string.Format("{0}{1}", fixedKeyword, arrayElemType),
                    NameSuffix = string.Format("[{0}]", array.Size)
                });
            }

            // const char* and const char[] are the same so we can use a string
            if (array.SizeType == ArrayType.ArraySize.Incomplete &&
                array.Type.Desugar().IsPrimitiveType(PrimitiveType.Char) &&
                array.QualifiedType.Qualifiers.IsConst)
            {
                return("string");
            }

            return(string.Format("{0}[]", array.Type.Visit(this)));

            // C# only supports fixed arrays in unsafe sections
            // and they are constrained to a set of built-in types.
        }
示例#2
0
        public CSharpTypePrinterResult VisitArrayType(ArrayType array,
                                                      TypeQualifiers quals)
        {
            if (ContextKind == CSharpTypePrinterContextKind.Native &&
                array.SizeType == ArrayType.ArraySize.Constant)
            {
                Type          arrayType = array.Type.Desugar();
                PrimitiveType primitiveType;
                if (arrayType.IsPointerToPrimitiveType(out primitiveType))
                {
                    if (primitiveType == PrimitiveType.Void)
                    {
                        return("void**");
                    }
                    return(string.Format("{0}*", array.Type.Visit(this, quals)));
                }
                // Do not write the fixed keyword multiple times for nested array types
                var fixedKeyword = array.Type is ArrayType ? string.Empty : "fixed ";
                return(new CSharpTypePrinterResult()
                {
                    Type = string.Format("{0}{1}", fixedKeyword, array.Type.Visit(this, quals)),
                    NameSuffix = string.Format("[{0}]", array.Size)
                });
            }

            return(string.Format("{0}[]", array.Type.Visit(this)));

            // C# only supports fixed arrays in unsafe sections
            // and they are constrained to a set of built-in types.
        }
 private static bool CheckForDefaultPointer(Type desugared, Parameter parameter)
 {
     if (desugared.IsPointer())
     {
         // IntPtr.Zero is not a constant
         parameter.DefaultArgument.String = desugared.IsPointerToPrimitiveType(PrimitiveType.Void) ?
                                            "new global::System.IntPtr()" : "null";
         return(true);
     }
     return(false);
 }
 private static bool CheckForDefaultPointer(Type desugared, Parameter parameter)
 {
     if (desugared.IsPointer())
     {
         // IntPtr.Zero is not a constant
         parameter.DefaultArgument.String = desugared.IsPointerToPrimitiveType(PrimitiveType.Void) ?
             "new global::System.IntPtr()" : "null";
         return true;
     }
     return false;
 }
示例#5
0
 private static void WriteTemplateSpecializationCheck(CSharpSources gen,
                                                      Class @class, ClassTemplateSpecialization specialization)
 {
     gen.WriteLine("if ({0})", string.Join(" && ",
                                           Enumerable.Range(0, @class.TemplateParameters.Count).Select(
                                               i =>
     {
         CppSharp.AST.Type type = specialization.Arguments[i].Type.Type;
         return(type.IsPointerToPrimitiveType() && !type.IsConstCharString() ?
                $"__{@class.TemplateParameters[i].Name}.FullName == \"System.IntPtr\"" :
                $"__{@class.TemplateParameters[i].Name}.IsAssignableFrom(typeof({type}))");
     })));
 }
示例#6
0
        private void MarshalArray(ArrayType array)
        {
            Type arrayType = array.Type.Desugar();

            if (arrayType.IsPrimitiveType() ||
                arrayType.IsPointerToPrimitiveType() ||
                Context.MarshalKind != MarshalKind.GenericDelegate)
            {
                Context.Return.Write(Context.ReturnVarName);
                return;
            }

            var intermediateArray     = Generator.GeneratedIdentifier(Context.ReturnVarName);
            var intermediateArrayType = arrayType.Visit(typePrinter);

            Context.Before.WriteLine($"{intermediateArrayType}[] {intermediateArray};");

            Context.Before.WriteLine($"if (ReferenceEquals({Context.ReturnVarName}, null))");
            Context.Before.WriteLineIndent($"{intermediateArray} = null;");
            Context.Before.WriteLine("else");

            Context.Before.WriteStartBraceIndent();
            Context.Before.WriteLine($@"{intermediateArray} = new {
                intermediateArrayType}[{Context.ReturnVarName}.Length];");
            Context.Before.WriteLine($"for (int i = 0; i < {intermediateArray}.Length; i++)");

            if (arrayType.IsAddress())
            {
                Context.Before.WriteStartBraceIndent();
                string element = Generator.GeneratedIdentifier("element");
                Context.Before.WriteLine($"var {element} = {Context.ReturnVarName}[i];");
                var intPtrZero = $"{CSharpTypePrinter.IntPtrType}.Zero";
                Context.Before.WriteLine($@"{intermediateArray}[i] = {element} == {
                    intPtrZero} ? null : {intermediateArrayType}.{
                    Helpers.CreateInstanceIdentifier}({element});");
                Context.Before.WriteCloseBraceIndent();
            }
            else
            {
                Context.Before.WriteLineIndent($@"{intermediateArray}[i] = {
                    intermediateArrayType}.{Helpers.CreateInstanceIdentifier}({
                    Context.ReturnVarName}[i]);");
            }

            Context.Before.WriteCloseBraceIndent();

            Context.Return.Write(intermediateArray);
        }
示例#7
0
        public override bool VisitTemplateParameterSubstitutionType(TemplateParameterSubstitutionType param, TypeQualifiers quals)
        {
            Type returnType = Context.ReturnType.Type.Desugar();
            Type finalType  = (returnType.GetFinalPointee() ?? returnType).Desugar();

            if (finalType.IsDependent)
            {
                Context.Return.Write($"({param.ReplacedParameter.Parameter.Name}) (object) ");
            }
            Type replacement = param.Replacement.Type.Desugar();

            if (replacement.IsPointerToPrimitiveType() && !replacement.IsConstCharString())
            {
                Context.Return.Write($"({typePrinter.IntPtrType}) ");
            }
            return(base.VisitTemplateParameterSubstitutionType(param, quals));
        }
示例#8
0
        private void MarshalVariableArray(Type arrayType)
        {
            if (arrayType.IsPrimitiveType() ||
                arrayType.IsPointerToPrimitiveType(PrimitiveType.Char))
            {
                Context.Return.Write(Context.Parameter.Name);
                return;
            }

            var intermediateArray     = $"__{Context.Parameter.Name}";
            var intermediateArrayType = typePrinter.PrintNative(arrayType);

            Context.Before.WriteLine($"{intermediateArrayType}[] {intermediateArray};");

            Context.Before.WriteLine($"if (ReferenceEquals({Context.Parameter.Name}, null))");
            Context.Before.WriteLineIndent($"{intermediateArray} = null;");
            Context.Before.WriteLine("else");

            Context.Before.WriteStartBraceIndent();
            Context.Before.WriteLine($@"{intermediateArray} = new {
                intermediateArrayType}[{Context.Parameter.Name}.Length];");
            Context.Before.WriteLine($"for (int i = 0; i < {intermediateArray}.Length; i++)");

            Context.Before.WriteStartBraceIndent();
            const string element = "__element";

            Context.Before.WriteLine($"var {element} = {Context.Parameter.Name}[i];");
            if (arrayType.IsAddress())
            {
                var intPtrZero = $"{CSharpTypePrinter.IntPtrType}.Zero";
                Context.Before.WriteLine($@"{intermediateArray}[i] = ReferenceEquals({
                    element}, null) ? {intPtrZero} : {element}.{Helpers.InstanceIdentifier};");
            }
            else
            {
                Context.Before.WriteLine($@"{intermediateArray}[i] = ReferenceEquals({
                    element}, null) ? new {intermediateArrayType}() : *({
                    intermediateArrayType}*) {element}.{Helpers.InstanceIdentifier};");
            }
            Context.Before.WriteCloseBraceIndent();

            Context.Before.WriteCloseBraceIndent();

            Context.Return.Write(intermediateArray);
        }
示例#9
0
        public override TypePrinterResult VisitArrayType(ArrayType array,
                                                         TypeQualifiers quals)
        {
            Type arrayType = array.Type.Desugar();

            if (ContextKind == TypePrinterContextKind.Native &&
                array.SizeType == ArrayType.ArraySize.Constant)
            {
                PrimitiveType primitiveType;
                if ((arrayType.IsPointerToPrimitiveType(out primitiveType) &&
                     !(arrayType is FunctionType)) ||
                    (arrayType.IsPrimitiveType() && MarshalKind != MarshalKind.NativeField))
                {
                    if (primitiveType == PrimitiveType.Void)
                    {
                        return("void*");
                    }
                    return(string.Format("{0}", array.Type.Visit(this, quals)));
                }

                if (Parameter != null)
                {
                    return(string.Format("global::System.IntPtr"));
                }

                Enumeration @enum;
                if (arrayType.TryGetEnum(out @enum))
                {
                    return(new TypePrinterResult
                    {
                        Type = string.Format("fixed {0}", @enum.BuiltinType),
                        NameSuffix = string.Format("[{0}]", array.Size)
                    });
                }

                Class @class;
                if (arrayType.TryGetClass(out @class))
                {
                    return(new TypePrinterResult
                    {
                        Type = "fixed byte",
                        NameSuffix = string.Format("[{0}]", array.Size * @class.Layout.Size)
                    });
                }

                var arrayElemType = array.Type.Visit(this, quals).ToString();

                // C# does not support fixed arrays of machine pointer type (void* or IntPtr).
                // In that case, replace it by a pointer to an integer type of the same size.
                if (arrayElemType == IntPtrType)
                {
                    arrayElemType = Context.TargetInfo.PointerWidth == 64 ? "long" : "int";
                }

                // Do not write the fixed keyword multiple times for nested array types
                var fixedKeyword = array.Type is ArrayType ? string.Empty : "fixed ";
                return(new TypePrinterResult
                {
                    Type = string.Format("{0}{1}", fixedKeyword, arrayElemType),
                    NameSuffix = string.Format("[{0}]", array.Size)
                });
            }

            // const char* and const char[] are the same so we can use a string
            if (array.SizeType == ArrayType.ArraySize.Incomplete &&
                arrayType.IsPrimitiveType(PrimitiveType.Char) &&
                array.QualifiedType.Qualifiers.IsConst)
            {
                return("string");
            }

            if (arrayType.IsPointerToPrimitiveType(PrimitiveType.Char))
            {
                return("char**");
            }

            return(string.Format("{0}{1}", array.Type.Visit(this),
                                 array.SizeType == ArrayType.ArraySize.Constant ? "[]" :
                                 (ContextKind == TypePrinterContextKind.Managed ? "*" : string.Empty)));

            // C# only supports fixed arrays in unsafe sections
            // and they are constrained to a set of built-in types.
        }
示例#10
0
        public override TypePrinterResult VisitArrayType(ArrayType array,
                                                         TypeQualifiers quals)
        {
            Type arrayType = array.Type.Desugar();

            if ((MarshalKind == MarshalKind.NativeField ||
                 (ContextKind == TypePrinterContextKind.Native &&
                  MarshalKind == MarshalKind.ReturnVariableArray)) &&
                array.SizeType == ArrayType.ArraySize.Constant)
            {
                if (array.Size == 0)
                {
                    var pointer = new PointerType(array.QualifiedType);
                    return(pointer.Visit(this));
                }

                PrimitiveType primitiveType;
                if ((arrayType.IsPointerToPrimitiveType(out primitiveType) &&
                     !(arrayType is FunctionType)) ||
                    (arrayType.IsPrimitiveType() && MarshalKind != MarshalKind.NativeField))
                {
                    if (primitiveType == PrimitiveType.Void)
                    {
                        return("void*");
                    }

                    return(array.QualifiedType.Visit(this));
                }

                if (Parameter != null)
                {
                    return(IntPtrType);
                }

                Enumeration @enum;
                if (arrayType.TryGetEnum(out @enum))
                {
                    return(new TypePrinterResult
                    {
                        Type = $"fixed {@enum.BuiltinType}",
                        NameSuffix = $"[{array.Size}]"
                    });
                }

                Class @class;
                if (arrayType.TryGetClass(out @class))
                {
                    return(new TypePrinterResult
                    {
                        Type = "fixed byte",
                        NameSuffix = $"[{array.Size * @class.Layout.Size}]"
                    });
                }

                var arrayElemType = array.QualifiedType.Visit(this).ToString();

                // C# does not support fixed arrays of machine pointer type (void* or IntPtr).
                // In that case, replace it by a pointer to an integer type of the same size.
                if (arrayElemType == IntPtrType)
                {
                    arrayElemType = Context.TargetInfo.PointerWidth == 64 ? "long" : "int";
                }

                // Do not write the fixed keyword multiple times for nested array types
                var fixedKeyword = arrayType is ArrayType ? string.Empty : "fixed ";
                return(new TypePrinterResult
                {
                    Type = $"{fixedKeyword}{arrayElemType}",
                    NameSuffix = $"[{array.Size}]"
                });
            }

            // const char* and const char[] are the same so we can use a string
            if (array.SizeType == ArrayType.ArraySize.Incomplete &&
                arrayType.IsPrimitiveType(PrimitiveType.Char) &&
                array.QualifiedType.Qualifiers.IsConst)
            {
                return("string");
            }

            if (arrayType.IsPointerToPrimitiveType(PrimitiveType.Char))
            {
                var prefix = ContextKind == TypePrinterContextKind.Managed ? string.Empty :
                             "[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] ";
                return($"{prefix}string[]");
            }

            var arraySuffix = array.SizeType != ArrayType.ArraySize.Constant &&
                              MarshalKind == MarshalKind.ReturnVariableArray ?
                              (ContextKind == TypePrinterContextKind.Managed &&
                               arrayType.IsPrimitiveType() ? "*" : string.Empty) : "[]";

            return($"{arrayType.Visit(this)}{arraySuffix}");
        }
        private UnwrapInfo?GetUnwrapInfo(ArrayType arrayType, Type typeInArray)
        {
            long unwrapCount;
            Type unwrapType;
            // in bits
            long unwrapTypeWidth;

            if (typeInArray.IsPointerToPrimitiveType())
            {
                // need to unwrap if field is array of pointer to primitive type
                // int* A[N]
                // becomes
                // int* A_0;
                // int* A_N;
                // unwrap to multiple pointer fields
                unwrapType = new PointerType
                {
                    QualifiedPointee = ((PointerType)typeInArray).QualifiedPointee
                };
                unwrapCount = arrayType.Size;
                // TODO: get type width from driver TargetInfo!
                unwrapTypeWidth = 0;
            }
            else if (typeInArray.IsPointerToArrayType())
            {
                // need to unwrap if field is array of pointer to array
                // A (*int[N])[M]
                // becomes
                // int** X_0;
                // int** X_M;
                var innerArray = (ArrayType)((PointerType)typeInArray).Pointee;

                unwrapType = new PointerType
                {
                    QualifiedPointee = new QualifiedType(new PointerType
                    {
                        QualifiedPointee = new QualifiedType(innerArray.Type)
                    })
                };
                unwrapCount     = arrayType.Size;
                unwrapTypeWidth = Driver.TargetInfo.PointerWidth;
            }
            else if (typeInArray is ArrayType)
            {
                // need to unwrap if field is array of array
                // int A[N][M]
                // becomes
                // int A_0[M];
                // int A_N[M];
                Type innerArray = ((ArrayType)(typeInArray)).Type;
                unwrapType = new ArrayType
                {
                    Size     = ((ArrayType)(typeInArray)).Size,
                    SizeType = ArrayType.ArraySize.Constant,
                    Type     = innerArray
                };
                unwrapCount = arrayType.Size / ((ArrayType)(typeInArray)).Size;
                // TODO: get type width from driver TargetInfo!
                unwrapTypeWidth = 0;
            }
            else if (!typeInArray.IsPrimitiveType())
            {
                // need tp unwrap if field is array of complex type
                // Struct A[N]
                // becomes
                // Struct A_0;
                // Struct A_N;
                unwrapType  = typeInArray;
                unwrapCount = arrayType.Size;
                // TODO: get type width from driver TargetInfo!
                unwrapTypeWidth = 0;
            }
            else
            {
                return(null);
            }

            return(new UnwrapInfo
            {
                UnwrapType = unwrapType,
                UnwrapCount = unwrapCount,
                UnwrapTypeWidth = unwrapTypeWidth
            });
        }