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

            if (Context.Options.GenerateRawCBindings && !(pointee is FunctionType))
            {
                var ptrStr = ptrSelector.Match(pointer.ToNativeString()).Value;
                var d      = pointee.Desugar().ToString();
                if (ptrStr.Equals("&"))
                {
                    return($"ref {d}");
                }

                //if (d.Equals("sbyte") && ptrStr.Length == 1)
                //    return "[MarshalAs(UnmanagedType.LPStr)] string";

                var res = string.Concat(d, ptrStr);
                return(res);
            }


            if (MarshalKind == MarshalKind.NativeField)
            {
                return(IntPtrType);
            }

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

            var isManagedContext = ContextKind == TypePrinterContextKind.Managed;

            if (allowStrings && IsConstCharString(pointer))
            {
                if (isManagedContext)
                {
                    return("string");
                }
                if (Parameter == null || 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
                bool isRefParam = Parameter != null && (Parameter.IsOut || Parameter.IsInOut);
                if (isManagedContext && isRefParam)
                {
                    return(pointer.QualifiedPointee.Visit(this));
                }

                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 = pointer.QualifiedPointee.Visit(this);
                allowStrings = true;

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

            Enumeration @enum;

            if (desugared.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 ((desugared.IsDependent || desugared.TryGetClass(out @class)) &&
                ContextKind == TypePrinterContextKind.Native)
            {
                return(IntPtrType);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }