Esempio n. 1
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            if (pointer.IsConstCharString())
            {
                return(VisitPrimitiveType(PrimitiveType.String));
            }

            var pointee = pointer.Pointee.Desugar();

            if (pointee is FunctionType)
            {
                typePrinter.PushContext(TypePrinterContextKind.Managed);
                var cppTypeName = pointer.Visit(typePrinter, quals);
                typePrinter.PopContext();

                return(VisitDelegateType(cppTypeName));
            }

            Enumeration @enum;

            if (pointee.TryGetEnum(out @enum))
            {
                var isRef = Context.Parameter.Usage == ParameterUsage.Out ||
                            Context.Parameter.Usage == ParameterUsage.InOut;

                Context.ArgumentPrefix.Write("&");
                Context.Return.Write($"(::{@enum.QualifiedOriginalName}){0}{Context.Parameter.Name}",
                                     isRef ? string.Empty : "*");
                return(true);
            }

            Class @class;

            if (pointee.TryGetClass(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                {
                    Context.Return.Write("&");
                }
                return(pointer.QualifiedPointee.Visit(this));
            }

            var finalPointee = pointer.GetFinalPointee();

            if (finalPointee.IsPrimitiveType())
            {
                var cppTypeName = pointer.Visit(typePrinter, quals);

                Context.Return.Write($"({cppTypeName})");
                Context.Return.Write(Context.Parameter.Name);
                return(true);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
Esempio n. 2
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            if (pointee is FunctionType)
            {
                var cppTypePrinter = new CppTypePrinter(Context.Context);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                return(VisitDelegateType(cppTypeName));
            }

            Enumeration @enum;

            if (pointee.TryGetEnum(out @enum))
            {
                var isRef = Context.Parameter.Type.IsReference() ||
                            Context.Parameter.Usage == ParameterUsage.Out ||
                            Context.Parameter.Usage == ParameterUsage.InOut;

                if (!isRef)
                {
                    ArgumentPrefix.Write("&");
                }

                Context.Return.Write("(::{0}){1}{2}", @enum.QualifiedOriginalName,
                                     isRef ? string.Empty : "*", Context.Parameter.Name);
                return(true);
            }

            Class @class;

            if (pointee.TryGetClass(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                {
                    Context.Return.Write("&");
                }
                return(pointer.QualifiedPointee.Visit(this));
            }

            var finalPointee = pointer.GetFinalPointee();

            if (finalPointee.IsPrimitiveType())
            {
                var cppTypePrinter = new CppTypePrinter(Context.Context);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return(true);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
Esempio n. 3
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
                 pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
                pointer.QualifiedPointee.Qualifiers.IsConst)
            {
                Context.SupportBefore.WriteLine(
                    "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
                    Context.ArgName, Context.Parameter.Name);

                Context.Return.Write("_{0}.c_str()", Context.ArgName);
                return(true);
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;

                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                return(VisitDelegateType(function, cppTypeName));
            }

            Class @class;

            if (pointee.IsTagDecl(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                {
                    Context.Return.Write("&");
                }
                return(pointee.Visit(this, quals));
            }

            PrimitiveType primitive;

            if (pointee.IsPrimitiveType(out primitive))
            {
                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return(true);
            }

            return(pointer.Pointee.Visit(this, quals));
        }
Esempio n. 4
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            if (Context.Function != null && pointer.IsPrimitiveTypeConvertibleToRef() &&
                Context.Kind != MarshalKind.VTableReturnValue)
            {
                var refParamPtr          = string.Format("__refParamPtr{0}", Context.ParameterIndex);
                var templateSubstitution = pointer.Pointee as TemplateParameterSubstitutionType;
                if (templateSubstitution != null)
                {
                    var castParam = $"__{Context.Parameter.Name}{Context.ParameterIndex}";
                    Context.SupportBefore.WriteLine(
                        $"var {castParam} = ({templateSubstitution}) (object) {Context.Parameter.Name};");
                    Context.SupportBefore.WriteLine($"{pointer} {refParamPtr} = &{castParam};");
                    Context.Return.Write(refParamPtr);
                }
                else
                {
                    Context.SupportBefore.WriteLine(
                        $"fixed ({pointer} {refParamPtr} = &{Context.Parameter.Name})");
                    Context.HasCodeBlock = true;
                    Context.SupportBefore.WriteStartBraceIndent();
                    Context.Return.Write(refParamPtr);
                }
                return(true);
            }

            var param      = Context.Parameter;
            var isRefParam = param != null && (param.IsInOut || param.IsOut);

            if (CSharpTypePrinter.IsConstCharString(pointee) && isRefParam)
            {
                if (param.IsOut)
                {
                    Context.Return.Write("IntPtr.Zero");
                    Context.ArgumentPrefix.Write("&");
                }
                else if (param.IsInOut)
                {
                    Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
                    Context.ArgumentPrefix.Write("&");
                }
                else
                {
                    Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
                    Context.Cleanup.WriteLine("Marshal.FreeHGlobal({0});", Context.ArgName);
                }
                return(true);
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;
                return(VisitDelegateType(function, function.ToString()));
            }

            Class @class;

            if (pointee.TryGetClass(out @class) && @class.IsValueType)
            {
                if (Context.Parameter.Usage == ParameterUsage.Out)
                {
                    var qualifiedIdentifier = (@class.OriginalClass ?? @class).Visit(typePrinter);
                    Context.SupportBefore.WriteLine("var {0} = new {1}.{2}();",
                                                    Generator.GeneratedIdentifier(Context.ArgName), qualifiedIdentifier,
                                                    Helpers.InternalStruct);
                }
                else
                {
                    Context.SupportBefore.WriteLine("var {0} = {1}.{2};",
                                                    Generator.GeneratedIdentifier(Context.ArgName),
                                                    Context.Parameter.Name,
                                                    Helpers.InstanceIdentifier);
                }

                Context.Return.Write("new global::System.IntPtr(&{0})",
                                     Generator.GeneratedIdentifier(Context.ArgName));
                return(true);
            }

            var           marshalAsString = CSharpTypePrinter.IsConstCharString(pointer);
            var           finalPointee    = pointer.GetFinalPointee();
            PrimitiveType primitive;

            if (finalPointee.IsPrimitiveType(out primitive) || finalPointee.IsEnumType() ||
                marshalAsString)
            {
                // From MSDN: "note that a ref or out parameter is classified as a moveable
                // variable". This means we must create a local variable to hold the result
                // and then assign this value to the parameter.

                if (isRefParam)
                {
                    var typeName = Type.TypePrinterDelegate(finalPointee);

                    if (param.IsInOut)
                    {
                        Context.SupportBefore.WriteLine("{0} _{1} = {1};", typeName, param.Name);
                    }
                    else
                    {
                        Context.SupportBefore.WriteLine("{0} _{1};", typeName, param.Name);
                    }

                    Context.Return.Write("&_{0}", param.Name);
                }
                else
                {
                    if (!marshalAsString &&
                        Context.Context.Options.MarshalCharAsManagedChar &&
                        primitive == PrimitiveType.Char)
                    {
                        typePrinter.PushContext(TypePrinterContextKind.Native);
                        Context.Return.Write(string.Format("({0}) ", pointer.Visit(typePrinter)));
                        typePrinter.PopContext();
                    }
                    if (marshalAsString && (Context.Kind == MarshalKind.NativeField ||
                                            Context.Kind == MarshalKind.VTableReturnValue ||
                                            Context.Kind == MarshalKind.Variable))
                    {
                        Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
                    }
                    else
                    {
                        Context.Return.Write(Context.Parameter.Name);
                    }
                }

                return(true);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
Esempio n. 5
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));
        }
Esempio n. 6
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
                 pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
                pointer.QualifiedPointee.Qualifiers.IsConst)
            {
                Context.SupportBefore.WriteLine(
                    "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
                    Context.ArgName, Context.Parameter.Name);

                Context.Return.Write("_{0}.c_str()", Context.ArgName);
                return(true);
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;

                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                return(VisitDelegateType(function, cppTypeName));
            }

            Enumeration @enum;

            if (pointee.TryGetEnum(out @enum))
            {
                var isRef = Context.Parameter.Usage == ParameterUsage.Out ||
                            Context.Parameter.Usage == ParameterUsage.InOut;

                ArgumentPrefix.Write("&");
                Context.Return.Write("(::{0}){1}{2}", @enum.QualifiedOriginalName,
                                     isRef ? string.Empty : "*", Context.Parameter.Name);
                return(true);
            }

            Class @class;

            if (pointee.TryGetClass(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                {
                    Context.Return.Write("&");
                }
                return(pointee.Visit(this, quals));
            }

            var finalPointee = pointer.GetFinalPointee();

            if (finalPointee.IsPrimitiveType())
            {
                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return(true);
            }

            return(pointer.Pointee.Visit(this, quals));
        }
Esempio n. 7
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}");
        }
Esempio n. 8
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var param      = Context.Parameter;
            var isRefParam = param != null && (param.IsInOut || param.IsOut);

            var pointee = pointer.Pointee.Desugar();

            if (pointee.IsConstCharString())
            {
                if (param.IsOut)
                {
                    MarshalString(pointee);
                    Context.Return.Write("IntPtr.Zero");
                    Context.ArgumentPrefix.Write("&");
                    return(true);
                }
                if (param.IsInOut)
                {
                    MarshalString(pointee);
                    pointer.QualifiedPointee.Visit(this);
                    Context.ArgumentPrefix.Write("&");
                    return(true);
                }
                if (pointer.IsReference)
                {
                    Context.Return.Write($@"({typePrinter.PrintNative(
                        pointee.GetQualifiedPointee())}*) ");
                    pointer.QualifiedPointee.Visit(this);
                    Context.ArgumentPrefix.Write("&");
                    return(true);
                }
            }

            var finalPointee = (pointee.GetFinalPointee() ?? pointee).Desugar();

            if (finalPointee.IsPrimitiveType(out PrimitiveType primitive) ||
                finalPointee.IsEnumType())
            {
                if (isRefParam)
                {
                    var local = Generator.GeneratedIdentifier($@"{
                        param.Name}{Context.ParameterIndex}");
                    Context.Before.WriteLine($@"fixed ({
                        pointer.Visit(typePrinter)} {local} = &{param.Name})");
                    Context.HasCodeBlock = true;
                    Context.Before.WriteOpenBraceAndIndent();
                    Context.Return.Write(local);
                    return(true);
                }

                if (Context.Context.Options.MarshalCharAsManagedChar &&
                    primitive == PrimitiveType.Char)
                {
                    Context.Return.Write($"({typePrinter.PrintNative(pointer)}) ");
                    Context.Return.Write(param.Name);
                    return(true);
                }

                pointer.QualifiedPointee.Visit(this);

                if (Context.Parameter.IsIndirect)
                {
                    Context.ArgumentPrefix.Write("&");
                }

                bool isVoid = primitive == PrimitiveType.Void &&
                              pointee.IsAddress() && pointer.IsReference();
                if (pointer.Pointee.Desugar(false) is TemplateParameterSubstitutionType ||
                    isVoid)
                {
                    var    local = Generator.GeneratedIdentifier($@"{
                        param.Name}{Context.ParameterIndex}");
                    string cast  = isVoid ? $@"({pointee.Visit(
                        new CppTypePrinter { PrintTypeQualifiers = false })}) " : string.Empty;
                    Context.Before.WriteLine($"var {local} = {cast}{Context.Return};");
                    Context.Return.StringBuilder.Clear();
                    Context.Return.Write(local);
                }
                if (new QualifiedType(pointer, quals).IsConstRefToPrimitive())
                {
                    Context.Return.StringBuilder.Insert(0, '&');
                }

                return(true);
            }

            if (pointee.TryGetClass(out Class @class) && @class.IsValueType)
            {
                if (Context.Parameter.Usage == ParameterUsage.Out)
                {
                    var qualifiedIdentifier = (@class.OriginalClass ?? @class).Visit(typePrinter);
                    Context.Before.WriteLine("var {0} = new {1}.{2}();",
                                             Generator.GeneratedIdentifier(Context.ArgName), qualifiedIdentifier,
                                             Helpers.InternalStruct);
                }
                else
                {
                    Context.Before.WriteLine("var {0} = {1}.{2};",
                                             Generator.GeneratedIdentifier(Context.ArgName),
                                             Context.Parameter.Name,
                                             Helpers.InstanceIdentifier);
                }

                Context.Return.Write("new global::System.IntPtr(&{0})",
                                     Generator.GeneratedIdentifier(Context.ArgName));
                return(true);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
Esempio n. 9
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            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 (pointer.GetFinalQualifiedPointee().Qualifiers.IsConst !=
                    Context.ReturnType.Qualifiers.IsConst)
                {
                    var nativeTypePrinter = new CppTypePrinter(Context.Context)
                    {
                        PrintTypeQualifiers = 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.Context);
                    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.Context.TypeMaps.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.QualifiedPointee.Visit(this));
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
                return false;

            var pointee = pointer.Pointee.Desugar();

            if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
                pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
                pointer.QualifiedPointee.Qualifiers.IsConst)
            {
                Context.SupportBefore.WriteLine(
                    "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
                    Context.ArgName, Context.Parameter.Name);

                Context.Return.Write("_{0}.c_str()", Context.ArgName);
                return true;
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;

                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName = pointer.Visit(cppTypePrinter, quals);

                return VisitDelegateType(function, cppTypeName);
            }

            Enumeration @enum;
            if (pointee.TryGetEnum(out @enum))
            {
                var isRef = Context.Parameter.Usage == ParameterUsage.Out ||
                    Context.Parameter.Usage == ParameterUsage.InOut;

                ArgumentPrefix.Write("&");
                Context.Return.Write("(::{0}){1}{2}", @enum.QualifiedOriginalName,
                    isRef ? string.Empty : "*", Context.Parameter.Name);
                return true;
            }

            Class @class;
            if (pointee.TryGetClass(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                    Context.Return.Write("&");
                return pointee.Visit(this, quals);
            }

            var finalPointee = pointer.GetFinalPointee();
            if (finalPointee.IsPrimitiveType())
            {
                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return true;
            }

            return pointer.Pointee.Visit(this, quals);
        }
Esempio n. 12
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
                return false;

            var pointee = pointer.Pointee.Desugar();

            if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
                pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
                pointer.QualifiedPointee.Qualifiers.IsConst)
            {
                Context.SupportBefore.WriteLine(
                    "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
                    Context.ArgName, Context.Parameter.Name);

                Context.Return.Write("_{0}.c_str()", Context.ArgName);
                return true;
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;

                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName = pointer.Visit(cppTypePrinter, quals);

                return VisitDelegateType(function, cppTypeName);
            }

            Class @class;
            if (pointee.IsTagDecl(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                    Context.Return.Write("&");
                return pointee.Visit(this, quals);
            }

            PrimitiveType primitive;
            if (pointee.IsPrimitiveType(out primitive))
            {
                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return true;
            }

            return pointer.Pointee.Visit(this, quals);
        }