コード例 #1
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();
            bool marshalPointeeAsString = CSharpTypePrinter.IsConstCharString(pointee) && isRefParam;

            if ((CSharpTypePrinter.IsConstCharString(pointer) && !MarshalsParameter) ||
                marshalPointeeAsString)
            {
                Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName,
                                                            pointer.GetFinalPointee().Desugar() as BuiltinType));
                return(true);
            }

            var           finalPointee = pointer.GetFinalPointee();
            PrimitiveType primitive;

            if (finalPointee.IsPrimitiveType(out primitive) || finalPointee.IsEnumType())
            {
                if (isRefParam)
                {
                    Context.Return.Write("_{0}", param.Name);
                    return(true);
                }

                if (Context.Context.Options.MarshalCharAsManagedChar &&
                    primitive == PrimitiveType.Char)
                {
                    Context.Return.Write($"({pointer}) ");
                }

                var type = Context.ReturnType.Type.Desugar(
                    resolveTemplateSubstitution: false);
                if (Context.Function != null &&
                    Context.Function.OperatorKind == CXXOperatorKind.Subscript &&
                    type.IsPrimitiveType(primitive))
                {
                    var substitute = type as TemplateParameterSubstitutionType;
                    if (substitute != null)
                    {
                        Context.Return.Write($@"({
                            substitute.ReplacedParameter.Parameter.Name}) (object) ");
                    }
                    Context.Return.Write("*");
                }

                Context.Return.Write(Context.ReturnVarName);
                return(true);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
コード例 #2
0
ファイル: NAPIMarshal.cs プロジェクト: tornado12345/CppSharp
        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));
        }
コード例 #3
0
ファイル: CLIMarshal.cs プロジェクト: barukai/CppSharp
        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));
        }
コード例 #4
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 (pointer.IsConstCharString())
            {
                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));
        }
コード例 #5
0
        public string 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 (pointee.IsPrimitiveType(PrimitiveType.Char) && quals.IsConst)
            {
                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
                var param = Context.Parameter;
                if (param != null && (param.IsOut || param.IsInOut) &&
                    pointee == finalPointee)
                {
                    return(pointee.Visit(this, quals));
                }

                return(pointee.Visit(this, quals) + "*");
            }

            Enumeration @enum;

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

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

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

            return(pointer.Pointee.Visit(this, quals));
        }
コード例 #6
0
ファイル: CSharpMarshal.cs プロジェクト: wuscier/CppSharp
        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();
            bool marshalPointeeAsString = CSharpTypePrinter.IsConstCharString(pointee) && isRefParam;

            if ((CSharpTypePrinter.IsConstCharString(pointer) && !MarshalsParameter) ||
                marshalPointeeAsString)
            {
                Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName,
                                                            pointer.GetFinalPointee().Desugar() as BuiltinType));
                return(true);
            }

            var           finalPointee = pointer.GetFinalPointee();
            PrimitiveType primitive;

            if (finalPointee.IsPrimitiveType(out primitive) || finalPointee.IsEnumType())
            {
                if (isRefParam)
                {
                    Context.Return.Write("_{0}", param.Name);
                    return(true);
                }

                if (Context.Context.Options.MarshalCharAsManagedChar && primitive == PrimitiveType.Char)
                {
                    Context.Return.Write(string.Format("({0}) ", pointer));
                }
                Context.Return.Write(Context.ReturnVarName);
                return(true);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
コード例 #7
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (pointer.IsConstCharString())
            {
                return(true);
            }

            var pointee = pointer.GetFinalPointee().Desugar();

            if (!pointee.TryGetClass(out _))
            {
                Diagnostics.Warning($"Unsupported decl: {decl.QualifiedName}");
                return(false);
            }

            return(true);
        }
コード例 #8
0
        public override TypePrinterResult VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            Type pointee = pointer.GetFinalPointee();

            if (pointee != null)
            {
                if ((pointee is BuiltinType) && pointer.IsPointer())
                {
                    if ((pointee as BuiltinType).Type == PrimitiveType.Void)
                    {
                        return(NodeV8IsTypedBuffer);
                    }
                }

                TypePrinterResult pointeeType = pointee.Visit(this);
                return(pointeeType);
            }

            throw new NotSupportedException();
        }
コード例 #9
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();
            bool marshalPointeeAsString = CSharpTypePrinter.IsConstCharString(pointee) && isRefParam;

            if (CSharpTypePrinter.IsConstCharString(pointer) || marshalPointeeAsString)
            {
                if (param.IsOut)
                {
                    Context.Return.Write("IntPtr.Zero");
                    CSharpContext.ArgumentPrefix.Write("&");
                }
                else if (param.IsInOut)
                {
                    Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
                    CSharpContext.ArgumentPrefix.Write("&");
                }
                else
                {
                    Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
                    CSharpContext.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)
                {
                    Context.SupportBefore.WriteLine("var {0} = new {1}.Internal();",
                                                    Generator.GeneratedIdentifier(Context.ArgName), @class.Name);
                }
                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           finalPointee = pointer.GetFinalPointee();
            PrimitiveType primitive;

            if (finalPointee.IsPrimitiveType(out primitive) || finalPointee.IsEnumType())
            {
                // 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
                {
                    Context.Return.Write(Context.Parameter.Name);
                }

                return(true);
            }

            return(pointer.Pointee.Visit(this, quals));
        }
コード例 #10
0
ファイル: CSharpMarshal.cs プロジェクト: yonkahlon/CppSharp
        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();
            var finalPointee = pointer.GetFinalPointee().Desugar();
            var type         = Context.ReturnType.Type.Desugar(
                resolveTemplateSubstitution: false);
            PrimitiveType primitive;

            if ((pointee.IsConstCharString() && (isRefParam || type.IsReference())) ||
                (!finalPointee.IsPrimitiveType(out primitive) &&
                 !finalPointee.IsEnumType()))
            {
                return(pointer.QualifiedPointee.Visit(this));
            }

            if (isRefParam)
            {
                Context.Return.Write(Generator.GeneratedIdentifier(param.Name));
                return(true);
            }

            if (Context.Context.Options.MarshalCharAsManagedChar &&
                primitive == PrimitiveType.Char)
            {
                Context.Return.Write($"({pointer}) ");
            }

            if (Context.Function != null &&
                Context.Function.OperatorKind == CXXOperatorKind.Subscript)
            {
                if (type.IsPrimitiveType(primitive))
                {
                    Context.Return.Write("*");
                }
                else
                {
                    var substitution = pointer.Pointee.Desugar(
                        resolveTemplateSubstitution: false) as TemplateParameterSubstitutionType;
                    if (substitution != null)
                    {
                        Context.Return.Write($@"({
                            substitution.ReplacedParameter.Parameter.Name}) (object) *");
                    }
                }
            }

            if (new QualifiedType(pointer, quals).IsConstRefToPrimitive())
            {
                Context.Return.Write("*");
            }

            Context.Return.Write(Context.ReturnVarName);
            return(true);
        }
コード例 #11
0
ファイル: CSharpMarshal.cs プロジェクト: galek/CppSharp
        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();
            var finalPointee = pointer.GetFinalPointee().Desugar();
            var returnType   = Context.ReturnType.Type.Desugar(
                resolveTemplateSubstitution: false);

            if ((pointee.IsConstCharString() && (isRefParam || returnType.IsReference())) ||
                (!finalPointee.IsPrimitiveType(out PrimitiveType primitive) &&
                 !finalPointee.IsEnumType()))
            {
                if (Context.MarshalKind != MarshalKind.NativeField &&
                    pointee.IsPointerTo(out Type type) &&
                    type.Desugar().TryGetClass(out Class c))
                {
                    string ret = Generator.GeneratedIdentifier(Context.ReturnVarName);
                    Context.Before.WriteLine($@"{typePrinter.IntPtrType} {ret} = {
                        Context.ReturnVarName} == {typePrinter.IntPtrType}.Zero ? {
                        typePrinter.IntPtrType}.Zero : new {
                        typePrinter.IntPtrType}(*(void**) {Context.ReturnVarName});");
                    Context.ReturnVarName = ret;
                }
                return(pointer.QualifiedPointee.Visit(this));
            }

            if (isRefParam)
            {
                Context.Return.Write(Generator.GeneratedIdentifier(param.Name));
                return(true);
            }

            if (Context.Context.Options.MarshalCharAsManagedChar &&
                primitive == PrimitiveType.Char)
            {
                Context.Return.Write($"({pointer}) ");
            }

            if (Context.Function != null &&
                Context.Function.OperatorKind == CXXOperatorKind.Subscript)
            {
                if (returnType.IsPrimitiveType(primitive))
                {
                    Context.Return.Write("*");
                }
                else
                {
                    var substitution = pointer.Pointee.Desugar(
                        resolveTemplateSubstitution: false) as TemplateParameterSubstitutionType;
                    if (substitution != null)
                    {
                        Context.Return.Write($@"({
                            substitution.ReplacedParameter.Parameter.Name}) (object) *");
                    }
                }
            }

            if (new QualifiedType(pointer, quals).IsConstRefToPrimitive())
            {
                if (finalPointee.IsPrimitiveType(PrimitiveType.Void))
                {
                    Context.Return.Write($"new {typePrinter.IntPtrType}(*{Context.ReturnVarName})");
                    return(true);
                }
                Context.Return.Write("*");
                if (Context.MarshalKind == MarshalKind.NativeField)
                {
                    Context.Return.Write($"({pointer.QualifiedPointee.Visit(typePrinter)}*) ");
                }
            }

            Context.Return.Write(Context.ReturnVarName);
            return(true);
        }
コード例 #12
0
ファイル: CLITypePrinter.cs プロジェクト: uzbekdev1/CppSharp
        public override TypePrinterResult VisitPointerType(PointerType pointer,
                                                           TypeQualifiers quals)
        {
            TypeMap typeMap;

            if (Context.TypeMaps.FindTypeMap(pointer.Desugar(), out typeMap))
            {
                var typePrinterContext = new TypePrinterContext
                {
                    Kind        = ContextKind,
                    MarshalKind = MarshalKind,
                    Type        = pointer
                };

                return(typeMap.CLISignatureType(typePrinterContext).Visit(this));
            }

            var pointee = pointer.Pointee.Desugar();

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

            // 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 = VisitDeclaration(@enum, quals);

                // Skip one indirection if passed by reference
                if (Parameter != null && (Parameter.Type.IsReference() ||
                                          ((Parameter.IsOut || Parameter.IsInOut) &&
                                           pointee == finalPointee)))
                {
                    return(typeName);
                }

                return($"{typeName}*");
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
コード例 #13
0
ファイル: CLIMarshal.cs プロジェクト: newlysoft/CppSharp
        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));
        }
コード例 #14
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var qualifiedPointer = new QualifiedType(pointer, quals);

            var         templateSubstitution = pointer.Pointee as TemplateParameterSubstitutionType;
            PointerType realPointer          = null;

            if (templateSubstitution != null)
            {
                realPointer = templateSubstitution.Replacement.Type.Desugar() as PointerType;
            }
            realPointer = realPointer ?? pointer;
            if (Context.Function != null &&
                (realPointer.IsPrimitiveTypeConvertibleToRef() ||
                 (templateSubstitution != null && realPointer.Pointee.IsEnumType())) &&
                Context.MarshalKind != MarshalKind.VTableReturnValue)
            {
                var refParamPtr = $"__refParamPtr{Context.ParameterIndex}";
                if (templateSubstitution != null)
                {
                    var castParam = $"__{Context.Parameter.Name}{Context.ParameterIndex}";
                    Context.Before.Write($"var {castParam} = ({templateSubstitution}) ");
                    if (realPointer != pointer)
                    {
                        Context.Before.Write($"({CSharpTypePrinter.IntPtrType}) ");
                    }
                    Context.Before.WriteLine($"(object) {Context.Parameter.Name};");
                    Context.Before.Write($"var {refParamPtr} = ");
                    if (realPointer == pointer)
                    {
                        Context.Before.Write("&");
                    }
                    Context.Before.WriteLine($"{castParam};");
                    Context.Return.Write(refParamPtr);
                    return(true);
                }
                if (Context.Function.OperatorKind != CXXOperatorKind.Subscript)
                {
                    if (Context.Parameter.Kind == ParameterKind.PropertyValue ||
                        qualifiedPointer.IsConstRefToPrimitive())
                    {
                        Context.Return.Write($"&{Context.Parameter.Name}");
                    }
                    else
                    {
                        Context.Before.WriteLine(
                            $"fixed ({realPointer} {refParamPtr} = &{Context.Parameter.Name})");
                        Context.HasCodeBlock = true;
                        Context.Before.WriteOpenBraceAndIndent();
                        Context.Return.Write(refParamPtr);
                    }
                    return(true);
                }
            }

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

            var pointee = pointer.Pointee.Desugar();

            if (pointee.IsConstCharString() && isRefParam)
            {
                if (param.IsOut)
                {
                    Context.Return.Write("IntPtr.Zero");
                    Context.ArgumentPrefix.Write("&");
                    return(true);
                }
                pointer.QualifiedPointee.Visit(this);
                if (param.IsInOut)
                {
                    Context.ArgumentPrefix.Write("&");
                }
                else
                {
                    Context.Cleanup.WriteLine("Marshal.FreeHGlobal({0});", Context.ArgName);
                }
                return(true);
            }

            if (pointee is FunctionType)
            {
                return(VisitDelegateType());
            }

            Class @class;

            if (pointee.TryGetClass(out @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);
            }

            var           finalPointee = pointer.GetFinalPointee();
            PrimitiveType primitive;

            if (finalPointee.IsPrimitiveType(out primitive) || finalPointee.IsEnumType())
            {
                // 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 (Context.Function.OperatorKind == CXXOperatorKind.Subscript)
                    {
                        Context.Return.Write(param.Name);
                    }
                    else
                    {
                        if (param.IsInOut)
                        {
                            Context.Before.WriteLine($"{typeName} _{param.Name} = {param.Name};");
                        }
                        else
                        {
                            Context.Before.WriteLine($"{typeName} _{param.Name};");
                        }

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

                    if (qualifiedPointer.IsConstRefToPrimitive())
                    {
                        Context.Return.Write("&");
                    }
                    Context.Return.Write(Context.Parameter.Name);
                }

                return(true);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
コード例 #15
0
ファイル: CLIMarshal.cs プロジェクト: corefan/CppSharp
        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);
        }
コード例 #16
0
        public override TypePrinterResult VisitPointerType(PointerType pointer,
                                                           TypeQualifiers quals)
        {
            if (MarshalKind == MarshalKind.NativeField && !pointer.Pointee.IsEnumType())
            {
                return(IntPtrType);
            }

            if (pointer.Pointee is FunctionType)
            {
                return(pointer.Pointee.Visit(this, quals));
            }

            var isManagedContext = ContextKind == TypePrinterContextKind.Managed;

            if (allowStrings && pointer.IsConstCharString())
            {
                TypeMap typeMap;
                TypeMapDatabase.FindTypeMap(pointer, out typeMap);
                var typePrinterContext = new TypePrinterContext()
                {
                    Kind        = Kind,
                    MarshalKind = MarshalKind,
                    Type        = pointer.Pointee,
                    Parameter   = Parameter
                };
                return(typeMap.CSharpSignatureType(typePrinterContext).Visit(this));
            }

            var pointee = pointer.Pointee.Desugar();

            if (isManagedContext &&
                new QualifiedType(pointer, quals).IsConstRefToPrimitive())
            {
                return(pointee.Visit(this));
            }

            // 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 (isManagedContext && isRefParam)
                {
                    return(pointer.QualifiedPointee.Visit(this));
                }

                if (pointee.IsPrimitiveType(PrimitiveType.Void))
                {
                    return(IntPtrType);
                }

                if (pointee.IsConstCharString() && isRefParam)
                {
                    return(IntPtrType + "*");
                }

                // Do not allow strings inside primitive arrays case, else we'll get invalid types
                // like string* for const char **.
                allowStrings = isRefParam;
                var result = pointer.QualifiedPointee.Visit(this);
                allowStrings = true;

                return(!isRefParam && result.Type == IntPtrType ? "void**" : result + "*");
            }

            Enumeration @enum;

            if (pointee.TryGetEnum(out @enum))
            {
                // Skip one indirection if passed by reference
                if (isManagedContext && Parameter != null && (Parameter.IsOut || Parameter.IsInOut) &&
                    pointee == finalPointee)
                {
                    return(pointer.QualifiedPointee.Visit(this));
                }

                return(pointer.QualifiedPointee.Visit(this) + "*");
            }

            Class @class;

            if ((pointee.IsDependent || pointee.TryGetClass(out @class)) &&
                ContextKind == TypePrinterContextKind.Native)
            {
                return(IntPtrType);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
コード例 #17
0
        public CSharpTypePrinterResult VisitPointerType(PointerType pointer,
                                                        TypeQualifiers quals)
        {
            var pointee = pointer.Pointee;

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

            var isManagedContext = ContextKind == CSharpTypePrinterContextKind.Managed;

            if (AllowStrings && IsConstCharString(pointer))
            {
                return(isManagedContext ? "string" : "global::System.IntPtr");
            }

            var desugared = pointee.Desugar();

            // 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
                var  param      = Context.Parameter;
                bool isRefParam = param != null && (param.IsOut || param.IsInOut);
                if (isManagedContext && isRefParam)
                {
                    return(pointee.Visit(this, quals));
                }

                if (ContextKind == CSharpTypePrinterContextKind.GenericDelegate ||
                    pointee.IsPrimitiveType(PrimitiveType.Void))
                {
                    return("global::System.IntPtr");
                }

                // Do not allow strings inside primitive arrays case, else we'll get invalid types
                // like string* for const char **.
                AllowStrings = isRefParam;
                var result = pointee.Visit(this, quals);
                AllowStrings = true;

                return(!isRefParam && result.Type == "global::System.IntPtr" ? "void**" : result + "*");
            }

            Enumeration @enum;

            if (desugared.TryGetEnum(out @enum))
            {
                // Skip one indirection if passed by reference
                var param = Context.Parameter;
                if (isManagedContext && param != null && (param.IsOut || param.IsInOut) &&
                    pointee == finalPointee)
                {
                    return(pointee.Visit(this, quals));
                }

                return(pointee.Visit(this, quals) + "*");
            }

            Class @class;

            if ((desugared.IsDependent || desugared.TryGetClass(out @class)) &&
                ContextKind == CSharpTypePrinterContextKind.Native)
            {
                return("global::System.IntPtr");
            }

            return(pointee.Visit(this, quals));
        }
コード例 #18
0
ファイル: CSharpMarshal.cs プロジェクト: fangsunjian/CppSharp
        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();
            bool marshalPointeeAsString = CSharpTypePrinter.IsConstCharString(pointee) && isRefParam;

            if (CSharpTypePrinter.IsConstCharString(pointer) || marshalPointeeAsString)
            {
                if (param.IsOut)
                {
                    Context.Return.Write("IntPtr.Zero");
                    CSharpContext.ArgumentPrefix.Write("&");
                }
                else if (param.IsInOut)
                {
                    Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
                    CSharpContext.ArgumentPrefix.Write("&");
                }
                else
                {
                    Context.Return.Write(MarshalStringToUnmanaged(Context.Parameter.Name));
                    CSharpContext.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)
                {
                    Context.SupportBefore.WriteLine("var {0} = new {1}.Internal();",
                        Generator.GeneratedIdentifier(Context.ArgName), @class.Name);
                }
                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 finalPointee = pointer.GetFinalPointee();
            PrimitiveType primitive;
            if (finalPointee.IsPrimitiveType(out primitive) || finalPointee.IsEnumType())
            {
                // 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
                    Context.Return.Write(Context.Parameter.Name);

                return true;
            }

            return pointer.Pointee.Visit(this, quals);
        }
コード例 #19
0
        public CSharpTypePrinterResult VisitPointerType(PointerType pointer,
                                                        TypeQualifiers quals)
        {
            var pointee = pointer.Pointee;

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

            var isManagedContext = ContextKind == CSharpTypePrinterContextKind.Managed;

            if (allowStrings && IsConstCharString(pointer))
            {
                if (isManagedContext || MarshalKind == CSharpMarshalKind.GenericDelegate)
                {
                    return("string");
                }
                if (TypePrinterContext.Parameter == null || TypePrinterContext.Parameter.Name == Helpers.ReturnIdentifier)
                {
                    return(IntPtrType);
                }
                if (Options.Encoding == Encoding.ASCII)
                {
                    return(string.Format("[MarshalAs(UnmanagedType.LPStr)] string"));
                }
                if (Options.Encoding == Encoding.Unicode ||
                    Options.Encoding == Encoding.BigEndianUnicode)
                {
                    return(string.Format("[MarshalAs(UnmanagedType.LPWStr)] string"));
                }
                throw new NotSupportedException(string.Format("{0} is not supported yet.",
                                                              Options.Encoding.EncodingName));
            }

            var desugared = pointee.Desugar();

            // 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
                var  param      = TypePrinterContext.Parameter;
                bool isRefParam = param != null && (param.IsOut || param.IsInOut);
                if (isManagedContext && isRefParam)
                {
                    return(pointee.Visit(this, quals));
                }

                if (pointee.IsPrimitiveType(PrimitiveType.Void))
                {
                    return(IntPtrType);
                }

                if (IsConstCharString(pointee) && isRefParam)
                {
                    return(IntPtrType + "*");
                }

                // Do not allow strings inside primitive arrays case, else we'll get invalid types
                // like string* for const char **.
                allowStrings = isRefParam;
                var result = pointee.Visit(this, quals);
                allowStrings = true;

                return(!isRefParam && result.Type == IntPtrType ? "void**" : result + "*");
            }

            Enumeration @enum;

            if (desugared.TryGetEnum(out @enum))
            {
                // Skip one indirection if passed by reference
                var param = TypePrinterContext.Parameter;
                if (isManagedContext && param != null && (param.IsOut || param.IsInOut) &&
                    pointee == finalPointee)
                {
                    return(pointee.Visit(this, quals));
                }

                return(pointee.Visit(this, quals) + "*");
            }

            Class @class;

            if ((desugared.IsDependent || desugared.TryGetClass(out @class) ||
                 (desugared is ArrayType && TypePrinterContext.Parameter != null)) &&
                ContextKind == CSharpTypePrinterContextKind.Native)
            {
                return(IntPtrType);
            }

            return(pointee.Visit(this, quals));
        }
コード例 #20
0
ファイル: CSharpMarshal.cs プロジェクト: fangsunjian/CppSharp
        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();
            bool marshalPointeeAsString = CSharpTypePrinter.IsConstCharString(pointee) && isRefParam;

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

            var finalPointee = pointer.GetFinalPointee();
            PrimitiveType primitive;
            if (finalPointee.IsPrimitiveType(out primitive) || finalPointee.IsEnumType())
            {
                if (isRefParam)
                {
                    Context.Return.Write("_{0}", param.Name);
                    return true;
                }

                Context.Return.Write(Context.ReturnVarName);
                return true;
            }

            return pointer.Pointee.Visit(this, quals);
        }
コード例 #21
0
ファイル: CSharpMarshal.cs プロジェクト: wuscier/CppSharp
        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));
        }
コード例 #22
0
        public CSharpTypePrinterResult VisitPointerType(PointerType pointer,
                                                        TypeQualifiers quals)
        {
            var pointee = pointer.Pointee;

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

            var isManagedContext = ContextKind == CSharpTypePrinterContextKind.Managed;

            if (IsConstCharString(pointer))
            {
                return(isManagedContext ? "string" : "global::System.IntPtr");
            }

            var desugared = pointee.Desugar();

            // 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
                var param = Context.Parameter;
                if (isManagedContext && param != null && (param.IsOut || param.IsInOut) &&
                    pointee == finalPointee)
                {
                    return(pointee.Visit(this, quals));
                }

                if (ContextKind == CSharpTypePrinterContextKind.GenericDelegate)
                {
                    return("global::System.IntPtr");
                }

                return(pointee.Visit(this, quals) + "*");
            }

            Enumeration @enum;

            if (desugared.IsTagDecl(out @enum))
            {
                return(@enum.Name + "*");
            }

            Class @class;

            if ((desugared.IsDependent || desugared.IsTagDecl(out @class)) &&
                ContextKind == CSharpTypePrinterContextKind.Native)
            {
                return("global::System.IntPtr");
            }

            return(pointee.Visit(this, quals));
        }