예제 #1
0
        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(string.Format("{0}^", 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 = @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));
        }