コード例 #1
0
        public override TypePrinterResult VisitTypedefType(TypedefType typedef,
                                                           TypeQualifiers quals)
        {
            var qual = GetStringQuals(quals);

            if (ResolveTypedefs && !typedef.Declaration.Type.IsPointerTo(out FunctionType _))
            {
                TypePrinterResult type = typedef.Declaration.QualifiedType.Visit(this);
                return(new TypePrinterResult
                {
                    Type = $"{qual}{type.Type}",
                    NamePrefix = type.NamePrefix,
                    NameSuffix = type.NameSuffix
                });
            }

            var result = typedef.Declaration.Visit(this);

            if (result.NamePrefix.Length > 0)
            {
                result.NamePrefix.Append($"{qual}");
            }

            return(result);
        }
コード例 #2
0
        public override TypePrinterResult VisitFieldDecl(Field field)
        {
            var cSharpSourcesDummy = new CSharpSources(Context, new List <TranslationUnit>());
            var safeIdentifier     = cSharpSourcesDummy.SafeIdentifier(field.Name);

            if (safeIdentifier.All(c => c.Equals('_')))
            {
                safeIdentifier = cSharpSourcesDummy.SafeIdentifier(field.Name);
            }

            PushMarshalKind(MarshalKind.NativeField);
            var fieldTypePrinted = field.QualifiedType.Visit(this);

            PopMarshalKind();

            var returnTypePrinter = new TypePrinterResult();

            if (!string.IsNullOrWhiteSpace(fieldTypePrinted.NameSuffix))
            {
                returnTypePrinter.NameSuffix = fieldTypePrinted.NameSuffix;
            }

            returnTypePrinter.Type = $"{fieldTypePrinted.Type} {safeIdentifier}";

            return(returnTypePrinter);
        }
コード例 #3
0
        public override TypePrinterResult VisitArrayType(ArrayType array,
                                                         TypeQualifiers quals)
        {
            var arraySuffix = string.Empty;

            switch (array.SizeType)
            {
            case ArrayType.ArraySize.Constant:
                arraySuffix = $"[{array.Size}]";
                break;

            case ArrayType.ArraySize.Variable:
            case ArrayType.ArraySize.Dependent:
            case ArrayType.ArraySize.Incomplete:
                arraySuffix = $"{(PrintVariableArrayAsPointers ? "*" : "[]")}";
                break;

            default:
                throw new NotImplementedException();
            }

            var result = new TypePrinterResult
            {
                Type       = array.Type.Visit(this),
                NameSuffix = new System.Text.StringBuilder(arraySuffix)
            };

            return(result);
        }
コード例 #4
0
        public override TypePrinterResult VisitClassTemplateSpecializationDecl(
            ClassTemplateSpecialization specialization)
        {
            TypePrinterResult typePrinterResult = VisitClassDecl(specialization);

            if (ContextKind != TypePrinterContextKind.Native)
            {
                typePrinterResult.NameSuffix.Append($@"<{string.Join(", ",
                    specialization.Arguments.Select(VisitTemplateArgument))}>");
            }
            return(typePrinterResult);
        }
コード例 #5
0
        private void TakeFunctionAddress(Function function, string wrapper)
        {
            string @namespace = function.OriginalNamespace.Visit(cppTypePrinter);

            if (function.Access == AccessSpecifier.Protected)
            {
                Write($"class {wrapper}{function.Namespace.Name} : public {@namespace} {{ public: ");
                Write("static constexpr ");
            }
            cppTypePrinter.PrintTags = true;
            TypePrinterResult returnType = function.OriginalReturnType.Visit(cppTypePrinter);
            string            signature  = GetSignature(function);

            cppTypePrinter.PrintTags = false;

            string functionName = GetFunctionName(function);

            if (function.FriendKind != FriendKind.None)
            {
                WriteRedeclaration(function, returnType, signature, functionName);
            }

            var method = function as Method;

            if (function.Namespace.Access == AccessSpecifier.Protected)
            {
                Write($@"class {wrapper}{function.Namespace.Name} : public {
                    function.Namespace.Namespace.Visit(cppTypePrinter)} {{ ");
            }

            string variable = $@"({(method?.IsStatic == false ?
                (@namespace + "::") : string.Empty)}*{wrapper}){signature}";

            returnType.NameSuffix.Append(' ').Append(variable);
            Write(returnType);

            if (function.Access == AccessSpecifier.Protected)
            {
                Write($" = &{wrapper}{function.Namespace.Name}::{function.OriginalName};");
                WriteLine(" };");
                Write($"auto {wrapper}Protected = {wrapper}{function.Namespace.Name}::{wrapper};");
            }
            else
            {
                Write($" = &{functionName};");
            }
            if (function.Namespace.Access == AccessSpecifier.Protected)
            {
                Write(" };");
            }
            NewLine();
        }
コード例 #6
0
        public override TypePrinterResult VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
        {
            FunctionType func;
            var          qual = GetStringQuals(quals);

            if (ResolveTypedefs && !typedef.Declaration.Type.IsPointerTo(out func))
            {
                TypePrinterResult type = typedef.Declaration.QualifiedType.Visit(this);
                return(new TypePrinterResult {
                    Type = $"{qual}{type.Type}", NamePrefix = type.NamePrefix, NameSuffix = type.NameSuffix
                });
            }
            return($"{qual}{typedef.Declaration.Visit(this)}");
        }
コード例 #7
0
        public override TypePrinterResult VisitFieldDecl(Field field)
        {
            PushMarshalKind(MarshalKind.NativeField);
            var fieldTypePrinted = field.QualifiedType.Visit(this);

            PopMarshalKind();

            var returnTypePrinter = new TypePrinterResult();

            returnTypePrinter.NameSuffix.Append(fieldTypePrinted.NameSuffix);

            returnTypePrinter.Type = $"{fieldTypePrinted.Type} {field.Name}";

            return(returnTypePrinter);
        }
コード例 #8
0
        public override TypePrinterResult VisitClassDecl(Class @class)
        {
            if (ContextKind == TypePrinterContextKind.Native)
            {
                return($@"{VisitDeclaration(@class.OriginalClass ?? @class)}.{
                    Helpers.InternalStruct}{Helpers.GetSuffixForInternal(@class)}");
            }

            TypePrinterResult printed = VisitDeclaration(@class);

            if (@class.IsTemplate)
            {
                printed.NameSuffix.Append($@"<{string.Join(", ",
                    @class.TemplateParameters.Select(p => p.Name))}>");
            }
            return(printed);
        }
コード例 #9
0
        public override TypePrinterResult VisitClassDecl(Class @class)
        {
            if (ContextKind == TypePrinterContextKind.Native)
            {
                return($"{VisitDeclaration(@class.OriginalClass ?? @class)}.{Helpers.InternalStruct}");
            }

            var typePrinterResult = new TypePrinterResult();

            typePrinterResult.Type = VisitDeclaration(@class).Type;
            if (@class.IsDependent)
            {
                typePrinterResult.NameSuffix = $@"<{
                    string.Join(", ", @class.TemplateParameters.Select(p => p.Name))}>";
            }
            return(typePrinterResult);
        }
コード例 #10
0
        public override TypePrinterResult VisitFieldDecl(Field field)
        {
            PushMarshalKind(MarshalKind.NativeField);
            var fieldTypePrinted = field.QualifiedType.Visit(this);

            PopMarshalKind();

            var returnTypePrinter = new TypePrinterResult();

            if (!string.IsNullOrWhiteSpace(fieldTypePrinted.NameSuffix))
            {
                returnTypePrinter.NameSuffix = fieldTypePrinted.NameSuffix;
            }

            returnTypePrinter.Type = $"{fieldTypePrinted.Type} {field.Name}";

            return(returnTypePrinter);
        }
コード例 #11
0
        public bool FindTypeMap(CppSharp.AST.Type type, out TypePrinterResult result)
        {
            result = null;

            if (!ResolveTypeMaps)
            {
                return(false);
            }

            TypeMap typeMap;

            if (!TypeMapDatabase.FindTypeMap(type, out typeMap) || typeMap.IsIgnored)
            {
                return(false);
            }

            var typePrinterContext = new TypePrinterContext
            {
                Type        = type,
                Kind        = Kind,
                MarshalKind = MarshalKind
            };

            var typePrinter = new CppTypePrinter(Context)
            {
                PrintFlavorKind     = PrintFlavorKind,
                ScopeKind           = ScopeKind,
                PrintTypeQualifiers = PrintTypeQualifiers,
                PrintTypeModifiers  = PrintTypeModifiers,
                ResolveTypeMaps     = false
            };

            typePrinter.PushContext(ContextKind);

            var typeName = typeMap.CppSignatureType(typePrinterContext).Visit(typePrinter);

            result = new TypePrinterResult(typeName)
            {
                TypeMap = typeMap
            };

            return(true);
        }
コード例 #12
0
        public override TypePrinterResult VisitTemplateSpecializationType(
            TemplateSpecializationType template, TypeQualifiers quals)
        {
            var decl = template.GetClassTemplateSpecialization() ??
                       template.Template.TemplatedDecl;

            TypeMap typeMap;

            if (!TypeMapDatabase.FindTypeMap(template, out typeMap))
            {
                if (ContextKind == TypePrinterContextKind.Managed &&
                    decl == template.Template.TemplatedDecl &&
                    template.Arguments.All(IsValid))
                {
                    List <TemplateArgument> args = template.Arguments;
                    var @class = (Class)template.Template.TemplatedDecl;
                    TemplateArgument  lastArg           = args.Last();
                    TypePrinterResult typePrinterResult = VisitDeclaration(decl);
                    typePrinterResult.NameSuffix.Append($@"<{string.Join(", ",
                       args.Concat(Enumerable.Range(0, @class.TemplateParameters.Count - args.Count).Select(
                           i => lastArg)).Select(this.VisitTemplateArgument))}>");
                    return(typePrinterResult);
                }

                if (ContextKind == TypePrinterContextKind.Native)
                {
                    return(template.Desugared.Visit(this));
                }

                return(decl.Visit(this));
            }

            typeMap.Type = template;

            var typePrinterContext = new TypePrinterContext
            {
                Type        = template,
                Kind        = ContextKind,
                MarshalKind = MarshalKind
            };

            return(typeMap.CSharpSignatureType(typePrinterContext).ToString());
        }
コード例 #13
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();
        }
コード例 #14
0
        public virtual TypePrinterResult GetDeclName(Declaration declaration,
                                                     TypePrintScopeKind scope)
        {
            switch (scope)
            {
            case TypePrintScopeKind.Local:
            {
                if (ContextKind == TypePrinterContextKind.Managed)
                {
                    return(PrintLogicalNames ? declaration.LogicalName : declaration.Name);
                }

                if (PrefixSpecialFunctions)
                {
                    if (declaration is Function {
                            IsOperator : true
                        } function)
                    {
                        return($"operator_{function.OperatorKind}");
                    }
                }

                return(PrintLogicalNames ? declaration.LogicalOriginalName
                            : declaration.OriginalName);
            }

            case TypePrintScopeKind.Qualified:
            {
                if (ContextKind == TypePrinterContextKind.Managed)
                {
                    var outputNamespace = GlobalNamespace(declaration);
                    if (!string.IsNullOrEmpty(outputNamespace))
                    {
                        return($"{outputNamespace}{NamespaceSeparator}{declaration.QualifiedName}");
                    }

                    return(declaration.QualifiedName);
                }

                if (declaration.Namespace is Class)
                {
                    var  declName  = GetDeclName(declaration, TypePrintScopeKind.Local);
                    bool printTags = PrintTags;
                    PrintTags = false;
                    TypePrinterResult declContext = declaration.Namespace.Visit(this);
                    PrintTags = printTags;
                    return($"{declContext}{NamespaceSeparator}{declName}");
                }

                return(PrintLogicalNames ? declaration.QualifiedLogicalOriginalName
                            : declaration.QualifiedOriginalName);
            }

            case TypePrintScopeKind.GlobalQualified:
            {
                var name = (ContextKind == TypePrinterContextKind.Managed) ?
                           declaration.Name : declaration.OriginalName;

                if (declaration.Namespace is Class)
                {
                    return($"{declaration.Namespace.Visit(this)}{NamespaceSeparator}{name}");
                }

                var qualifier = HasGlobalNamespacePrefix ? NamespaceSeparator : string.Empty;
                return(qualifier + GetDeclName(declaration, TypePrintScopeKind.Qualified));
            }
            }

            throw new NotSupportedException();
        }
コード例 #15
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($"fixed {@enum.BuiltinType}",
                                                 $"[{array.Size}]"));
                }

                if (arrayType.IsClass())
                {
                    return(new TypePrinterResult($"fixed byte", $"[{array.GetSizeInBytes()}]"));
                }

                TypePrinterResult arrayElemType = array.QualifiedType.Visit(this);

                // 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(fixedKeyword + arrayElemType.Type,
                                             $"[{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)] ";
                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}");
        }