Ejemplo n.º 1
0
        private void MarshalArray(ArrayType array)
        {
            Type arrayType = array.Type.Desugar();

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

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

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

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

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

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

            Context.Before.UnindentAndWriteCloseBrace();

            Context.Return.Write(intermediateArray);
        }
Ejemplo n.º 2
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();
        }
Ejemplo n.º 3
0
        public bool FindTypeMap(Type type, out TypeMap typeMap)
        {
            typeMap = null;

            while (true)
            {
                var typePrinter = new CppTypePrinter(this);
                var output      = type.Visit(typePrinter);

                if (FindTypeMap(output, out typeMap))
                {
                    return(true);
                }

                // Try to strip the global scope resolution operator.
                if (output.StartsWith("::"))
                {
                    output = output.Substring(2);
                }

                if (FindTypeMap(output, out typeMap))
                {
                    return(true);
                }

                var desugaredType = type.Desugar();
                if (desugaredType == type)
                {
                    return(false);
                }

                type = desugaredType;
            }

            return(true);
        }
Ejemplo n.º 4
0
 public string ToString(Type type)
 {
     return(type.Visit(this));
 }
Ejemplo n.º 5
0
 public override string ToString(Type type)
 {
     return(type.Visit(this).Type);
 }
 protected override string TypePrinterDelegate(CppSharp.AST.Type type)
 {
     return(type.Visit(TypePrinter).ToString());
 }
Ejemplo n.º 7
0
 private string TypePrinterDelegate(CppSharp.AST.Type type)
 {
     return(type.Visit(new CSharpTypePrinter(Driver.Context)).Type);
 }
Ejemplo n.º 8
0
 public T Visit <T>(ITypeVisitor <T> visitor)
 {
     return(Type.Visit(visitor, Qualifiers));
 }
Ejemplo n.º 9
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}");
        }
Ejemplo n.º 10
0
 public string ToString(CppSharp.AST.Type type)
 {
     return(type.Visit(this));
 }
Ejemplo n.º 11
0
        public bool FindTypeMap(Type type, out TypeMap typeMap)
        {
            if (typeMaps.ContainsKey(type))
            {
                typeMap = typeMaps[type];
                return(typeMap.IsEnabled);
            }

            var template = type as TemplateSpecializationType;

            if (template != null)
            {
                var specialization = template.GetClassTemplateSpecialization();
                if (specialization != null &&
                    FindTypeMap(specialization, out typeMap))
                {
                    return(true);
                }
                if (template.Template.TemplatedDecl != null)
                {
                    if (FindTypeMap(template.Template.TemplatedDecl,
                                    out typeMap))
                    {
                        typeMap.Type = type;
                        return(true);
                    }
                    return(false);
                }
            }

            Type desugared = type.Desugar();

            desugared = (desugared.GetFinalPointee() ?? desugared).Desugar();
            bool printExtra = desugared.IsPrimitiveType() ||
                              (desugared.GetFinalPointee() ?? desugared).Desugar().IsPrimitiveType();
            var typePrinter = new CppTypePrinter
            {
                PrintTypeQualifiers = printExtra,
                PrintTypeModifiers  = printExtra,
                PrintLogicalNames   = true
            };

            foreach (var resolveTypeDefs in new[] { true, false })
            {
                foreach (var typePrintScopeKind in
                         new[] { TypePrintScopeKind.Local, TypePrintScopeKind.Qualified })
                {
                    typePrinter.ResolveTypedefs = resolveTypeDefs;
                    typePrinter.ScopeKind       = typePrintScopeKind;
                    if (FindTypeMap(type.Visit(typePrinter), out typeMap))
                    {
                        typeMap.Type   = type;
                        typeMaps[type] = typeMap;
                        return(true);
                    }
                }
            }

            typeMap = null;
            var typedef = type as TypedefType;

            return(typedef != null && FindTypeMap(typedef.Declaration.Type, out typeMap));
        }
Ejemplo n.º 12
0
        public override bool VisitClassDecl(Class @class)
        {
            var  originalClass = @class.OriginalClass ?? @class;
            Type returnType    = Context.ReturnType.Type.Desugar();

            // if the class is an abstract impl, use the original for the object map
            var qualifiedClass = originalClass.Visit(typePrinter);

            var   finalType = (returnType.GetFinalPointee() ?? returnType).Desugar();
            Class returnedClass;

            if (finalType.TryGetClass(out returnedClass) && returnedClass.IsDependent)
            {
                Context.Return.Write($"({returnType.Visit(typePrinter)}) (object) ");
            }

            // these two aren't the same for members of templates
            if (Context.Function?.OriginalReturnType.Type.Desugar().IsAddress() == true ||
                returnType.IsAddress())
            {
                Context.Return.Write(HandleReturnedPointer(@class, qualifiedClass));
            }
            else
            {
                if (Context.MarshalKind == MarshalKind.NativeField ||
                    Context.MarshalKind == MarshalKind.Variable ||
                    Context.MarshalKind == MarshalKind.ReturnVariableArray ||
                    !originalClass.HasNonTrivialDestructor)
                {
                    Context.Return.Write($"{qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName})");
                }
                else
                {
                    Context.Before.WriteLine($@"var __{Context.ReturnVarName} = {
                        qualifiedClass}.{Helpers.CreateInstanceIdentifier}({Context.ReturnVarName});");
                    Method dtor = originalClass.Destructors.First();
                    if (dtor.IsVirtual)
                    {
                        var i           = VTables.GetVTableIndex(dtor);
                        int vtableIndex = 0;
                        if (Context.Context.ParserOptions.IsMicrosoftAbi)
                        {
                            vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.First(
                                                                             v => v.Layout.Components.Any(c => c.Method == dtor)));
                        }
                        string instance = $"new {typePrinter.IntPtrType}(&{Context.ReturnVarName})";
                        Context.Before.WriteLine($@"var __vtables = new IntPtr[] {{ {
                            string.Join(", ", originalClass.Layout.VTablePointers.Select(
                                x => $"*({typePrinter.IntPtrType}*) ({instance} + {x.Offset})"))} }};");
                        Context.Before.WriteLine($@"var __slot = *({typePrinter.IntPtrType}*) (__vtables[{
                            vtableIndex}] + {i} * sizeof({typePrinter.IntPtrType}));");
                        Context.Before.Write($"Marshal.GetDelegateForFunctionPointer<{dtor.FunctionType}>(__slot)({instance}");
                        if (dtor.GatherInternalParams(Context.Context.ParserOptions.IsItaniumLikeAbi).Count > 1)
                        {
                            Context.Before.Write(", 0");
                        }
                        Context.Before.WriteLine(");");
                    }
                    else
                    {
                        string suffix         = string.Empty;
                        var    specialization = @class as ClassTemplateSpecialization;
                        if (specialization != null)
                        {
                            suffix = Helpers.GetSuffixFor(specialization);
                        }
                        Context.Before.WriteLine($@"{typePrinter.PrintNative(originalClass)}.dtor{
                            suffix}(new {typePrinter.IntPtrType}(&{Context.ReturnVarName}));");
                    }
                    Context.Return.Write($"__{Context.ReturnVarName}");
                }
            }

            return(true);
        }
Ejemplo n.º 13
0
        public bool FindTypeMap(Type type, out TypeMap typeMap)
        {
            var typePrinter = new CppTypePrinter(this);

            var template = type as TemplateSpecializationType;
            if (template != null)
                return FindTypeMap(template.Template.TemplatedDecl, type,
                    out typeMap);

            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            typePrinter.PrintKind = CppTypePrintKind.Qualified;
            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            return false;
        }
Ejemplo n.º 14
0
        public bool FindTypeMap(Type type, out TypeMap typeMap)
        {
            // Looks up the type in the cache map.
            if (typeMaps.ContainsKey(type))
            {
                typeMap      = typeMaps[type];
                typeMap.Type = type;
                return(typeMap.IsEnabled);
            }

            var template = type as TemplateSpecializationType;

            if (template != null)
            {
                var specialization = template.GetClassTemplateSpecialization();
                if (specialization != null &&
                    FindTypeMap(specialization, out typeMap))
                {
                    return(true);
                }

                if (template.Template.TemplatedDecl != null)
                {
                    if (FindTypeMap(template.Template.TemplatedDecl,
                                    out typeMap))
                    {
                        typeMap.Type = type;
                        return(true);
                    }

                    return(false);
                }
            }

            Type desugared = type.Desugar();

            desugared = (desugared.GetFinalPointee() ?? desugared).Desugar();

            bool printExtra = desugared.IsPrimitiveType() ||
                              (desugared.GetFinalPointee() ?? desugared).Desugar().IsPrimitiveType();

            var typePrinter = new CppTypePrinter(Context)
            {
                ResolveTypeMaps     = false,
                PrintTypeQualifiers = printExtra,
                PrintTypeModifiers  = printExtra,
                PrintLogicalNames   = true
            };

            typePrinter.PushContext(TypePrinterContextKind.Native);

            foreach (var resolveTypeDefs in new[] { false, true })
            {
                foreach (var typePrintScopeKind in
                         new[] { TypePrintScopeKind.Local, TypePrintScopeKind.Qualified })
                {
                    typePrinter.ResolveTypedefs = resolveTypeDefs;
                    typePrinter.PushScope(typePrintScopeKind);
                    var typeName = type.Visit(typePrinter);
                    typePrinter.PopScope();
                    if (FindTypeMap(typeName, out typeMap))
                    {
                        typeMap.Type   = type;
                        typeMaps[type] = typeMap;
                        return(true);
                    }
                }
            }

            typeMap = null;
            return(false);
        }
Ejemplo n.º 15
0
        public bool FindTypeMap(Type type, out TypeMap typeMap)
        {
            var typePrinter = new CppTypePrinter
            {
                PrintTypeQualifiers = false,
                PrintTypeModifiers = false,
                PrintLogicalNames = true
            };

            var template = type as TemplateSpecializationType;
            if (template != null)
            {
                var specialization = template.GetClassTemplateSpecialization();
                if (specialization != null && FindTypeMap(specialization, type, out typeMap))
                    return true;
                if (template.Template.TemplatedDecl != null)
                    return FindTypeMap(template.Template.TemplatedDecl, type,
                        out typeMap);
            }

            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            typePrinter.PrintScopeKind = CppTypePrintScopeKind.Qualified;
            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            var typedef = type as TypedefType;
            return typedef != null && FindTypeMap(typedef.Declaration, type, out typeMap);
        }