Beispiel #1
0
        public static Cursor Create(CXCursor handle, Cursor parent)
        {
            if (handle.IsDeclaration)
            {
                return(Decl.Create(handle, parent));
            }
            else if (handle.IsReference)
            {
                return(Ref.Create(handle, parent));
            }
            else if (handle.IsExpression)
            {
                return(Expr.Create(handle, parent));
            }
            else if (handle.IsStatement)
            {
                return(Stmt.Create(handle, parent));
            }
            else if (handle.IsAttribute)
            {
                return(Attr.Create(handle, parent));
            }

            switch (handle.Kind)
            {
            default:
            {
                Debug.WriteLine($"Unhandled cursor kind: {handle.KindSpelling}.");
                Debugger.Break();
                return(new Cursor(handle, parent));
            }
            }
        }
Beispiel #2
0
        private string GetParmModifier(Decl decl, Type type)
        {
            if (_config.GenerateUnsafeCode)
            {
                return(string.Empty);
            }

            switch (type.Kind)
            {
            case CXTypeKind.CXType_Void:
            case CXTypeKind.CXType_UShort:
            case CXTypeKind.CXType_UInt:
            case CXTypeKind.CXType_ULong:
            case CXTypeKind.CXType_ULongLong:
            case CXTypeKind.CXType_Short:
            case CXTypeKind.CXType_Int:
            case CXTypeKind.CXType_Long:
            case CXTypeKind.CXType_LongLong:
            case CXTypeKind.CXType_Double:
            case CXTypeKind.CXType_Enum:
            case CXTypeKind.CXType_Typedef:
            {
                return(string.Empty);
            }

            case CXTypeKind.CXType_Pointer:
            {
                return(GetParmModifierForPointeeType(decl, type.PointeeType));
            }

            case CXTypeKind.CXType_ConstantArray:
            case CXTypeKind.CXType_IncompleteArray:
            {
                return("out");
            }

            case CXTypeKind.CXType_Elaborated:
            {
                return(GetParmModifier(decl, type.CanonicalType));
            }

            default:
            {
                Unhandled(decl, type);
                return(string.Empty);
            }
            }
        }
Beispiel #3
0
        private string GetMarshalAttributeForPointeeType(Decl decl, Type pointeeType)
        {
            Debug.Assert(!_config.GenerateUnsafeCode);

            switch (pointeeType.Kind)
            {
            case CXTypeKind.CXType_Void:
            case CXTypeKind.CXType_UShort:
            case CXTypeKind.CXType_UInt:
            case CXTypeKind.CXType_ULong:
            case CXTypeKind.CXType_ULongLong:
            case CXTypeKind.CXType_Short:
            case CXTypeKind.CXType_Int:
            case CXTypeKind.CXType_Long:
            case CXTypeKind.CXType_LongLong:
            case CXTypeKind.CXType_Double:
            case CXTypeKind.CXType_Pointer:
            case CXTypeKind.CXType_Record:
            case CXTypeKind.CXType_Enum:
            case CXTypeKind.CXType_Typedef:
            case CXTypeKind.CXType_FunctionProto:
            {
                return(string.Empty);
            }

            case CXTypeKind.CXType_Char_S:
            {
                return("MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(StringMarshaler))");
            }

            case CXTypeKind.CXType_WChar:
            {
                return("MarshalAs(UnmanagedType.LPWStr)");
            }

            case CXTypeKind.CXType_Elaborated:
            {
                return(GetMarshalAttributeForPointeeType(decl, pointeeType.CanonicalType));
            }

            default:
            {
                Unhandled(decl, pointeeType);
                return(string.Empty);
            }
            }
        }
Beispiel #4
0
        private string GetParmModifierForPointeeType(Decl decl, Type pointeeType)
        {
            Debug.Assert(!_config.GenerateUnsafeCode);

            switch (pointeeType.Kind)
            {
            case CXTypeKind.CXType_Void:
            case CXTypeKind.CXType_Char_S:
            case CXTypeKind.CXType_WChar:
            case CXTypeKind.CXType_FunctionProto:
            {
                return(string.Empty);
            }

            case CXTypeKind.CXType_UChar:
            case CXTypeKind.CXType_UShort:
            case CXTypeKind.CXType_UInt:
            case CXTypeKind.CXType_ULong:
            case CXTypeKind.CXType_ULongLong:
            case CXTypeKind.CXType_Short:
            case CXTypeKind.CXType_Int:
            case CXTypeKind.CXType_Long:
            case CXTypeKind.CXType_LongLong:
            case CXTypeKind.CXType_Double:
            case CXTypeKind.CXType_Record:
            case CXTypeKind.CXType_Enum:
            case CXTypeKind.CXType_Pointer:
            {
                return("out");
            }

            case CXTypeKind.CXType_Typedef:
            case CXTypeKind.CXType_Elaborated:
            {
                return(GetParmModifierForPointeeType(decl, pointeeType.CanonicalType));
            }

            default:
            {
                Unhandled(decl, pointeeType);
                return(string.Empty);
            }
            }
        }
Beispiel #5
0
        private string GetTypeNameForPointeeType(Decl decl, Type pointeeType)
        {
            switch (pointeeType.Kind)
            {
            case CXTypeKind.CXType_Void:
            {
                if (_config.GenerateUnsafeCode)
                {
                    return("void*");
                }

                _outputBuilder.AddUsing("System");
                return("IntPtr");
            }

            case CXTypeKind.CXType_FunctionProto:
            {
                _outputBuilder.AddUsing("System");
                return("IntPtr");
            }

            case CXTypeKind.CXType_UShort:
            case CXTypeKind.CXType_UInt:
            case CXTypeKind.CXType_ULong:
            case CXTypeKind.CXType_ULongLong:
            case CXTypeKind.CXType_Short:
            case CXTypeKind.CXType_Int:
            case CXTypeKind.CXType_Long:
            case CXTypeKind.CXType_LongLong:
            case CXTypeKind.CXType_Pointer:
            case CXTypeKind.CXType_Record:
            case CXTypeKind.CXType_Enum:
            case CXTypeKind.CXType_Typedef:
            {
                switch (decl.Kind)
                {
                case CXCursorKind.CXCursor_FieldDecl:
                case CXCursorKind.CXCursor_FunctionDecl:
                {
                    var name = "IntPtr";

                    if (_config.GenerateUnsafeCode)
                    {
                        name  = GetTypeName(decl, pointeeType);
                        name += '*';
                    }
                    else
                    {
                        _outputBuilder.AddUsing("System");
                    }

                    return(name);
                }

                case CXCursorKind.CXCursor_ParmDecl:
                {
                    var name = GetTypeName(decl, pointeeType);

                    if (_config.GenerateUnsafeCode)
                    {
                        name += '*';
                    }
                    return(name);
                }

                case CXCursorKind.CXCursor_TypedefDecl:
                {
                    var typedefDecl    = (TypedefDecl)decl;
                    var underlyingType = typedefDecl.UnderlyingType;

                    if ((underlyingType.Kind == CXTypeKind.CXType_Pointer) && (underlyingType.PointeeType.Kind == CXTypeKind.CXType_FunctionProto))
                    {
                        goto case CXCursorKind.CXCursor_FunctionDecl;
                    }

                    var name = GetCursorName(pointeeType.DeclarationCursor);

                    if (_config.GenerateUnsafeCode)
                    {
                        name += '*';
                    }
                    return(name);
                }

                default:
                {
                    Unhandled(decl, pointeeType);
                    return(string.Empty);
                }
                }
            }

            case CXTypeKind.CXType_Char_S:
            {
                switch (decl.Kind)
                {
                case CXCursorKind.CXCursor_FieldDecl:
                case CXCursorKind.CXCursor_FunctionDecl:
                {
                    return(_config.GenerateUnsafeCode ? "byte*" : "string");
                }

                case CXCursorKind.CXCursor_ParmDecl:
                {
                    if (GetParmModifier(decl, decl.Type).Equals("out"))
                    {
                        Debug.Assert(!_config.GenerateUnsafeCode);
                        _outputBuilder.AddUsing("System");
                        return("IntPtr");
                    }

                    return(_config.GenerateUnsafeCode ? "byte*" : "string");
                }

                case CXCursorKind.CXCursor_TypedefDecl:
                {
                    return(_config.GenerateUnsafeCode ? "byte*" : "string");
                }

                default:
                {
                    Unhandled(decl, pointeeType);
                    return(string.Empty);
                }
                }
            }

            case CXTypeKind.CXType_Elaborated:
            {
                return(GetTypeNameForPointeeType(decl, pointeeType.CanonicalType));
            }

            case CXTypeKind.CXType_Attributed:
            {
                return(GetTypeNameForPointeeType(decl, pointeeType.ModifierType));
            }

            default:
            {
                Unhandled(decl, pointeeType);
                return(string.Empty);
            }
            }
        }
Beispiel #6
0
        private string GetTypeName(Decl decl, Type type)
        {
            switch (type.Kind)
            {
            case CXTypeKind.CXType_Void:
            {
                return("void");
            }

            case CXTypeKind.CXType_Bool:
            {
                return("bool");
            }

            case CXTypeKind.CXType_UChar:
            {
                return("byte");
            }

            case CXTypeKind.CXType_UShort:
            {
                return("ushort");
            }

            case CXTypeKind.CXType_UInt:
            {
                return("uint");
            }

            case CXTypeKind.CXType_ULong:
            {
                return("uint");
            }

            case CXTypeKind.CXType_ULongLong:
            {
                return("ulong");
            }

            case CXTypeKind.CXType_Char_S:
            {
                return("sbyte");
            }

            case CXTypeKind.CXType_WChar:
            {
                return("char");
            }

            case CXTypeKind.CXType_Short:
            {
                return("short");
            }

            case CXTypeKind.CXType_Int:
            {
                return("int");
            }

            case CXTypeKind.CXType_Long:
            {
                return("int");
            }

            case CXTypeKind.CXType_LongLong:
            {
                return("long");
            }

            case CXTypeKind.CXType_Float:
            {
                return("float");
            }

            case CXTypeKind.CXType_Double:
            {
                return("double");
            }

            case CXTypeKind.CXType_Pointer:
            case CXTypeKind.CXType_LValueReference:
            {
                return(GetTypeNameForPointeeType(decl, type.PointeeType));
            }

            case CXTypeKind.CXType_Record:
            case CXTypeKind.CXType_Enum:
            case CXTypeKind.CXType_FunctionProto:
            {
                var name = type.Spelling;
                Debug.Assert(!string.IsNullOrWhiteSpace(name));
                return(name);
            }

            case CXTypeKind.CXType_Typedef:
            {
                return(GetCursorName(type.DeclarationCursor));
            }

            case CXTypeKind.CXType_Elaborated:
            {
                return(GetTypeName(decl, type.CanonicalType));
            }

            case CXTypeKind.CXType_ConstantArray:
            case CXTypeKind.CXType_IncompleteArray:
            {
                return(GetTypeName(decl, type.ElementType));
            }

            default:
            {
                Unhandled(decl, type);
                return(string.Empty);
            }
            }
        }
Beispiel #7
0
        private string GetCursorName(Decl decl)
        {
            switch (decl.Kind)
            {
            case CXCursorKind.CXCursor_StructDecl:
            case CXCursorKind.CXCursor_UnionDecl:
            case CXCursorKind.CXCursor_EnumDecl:
            {
                var name = decl.Spelling;

                if (string.IsNullOrWhiteSpace(name))
                {
                    if (decl.IsAnonymous)
                    {
                        decl.Location.GetFileLocation(out var file, out var _, out var _, out var offset);
                        var fileName = Path.GetFileNameWithoutExtension(file.Name.ToString());
                        name = $"__Anonymous{decl.Type.KindSpelling}_{fileName}_{offset}";
                    }
                    else
                    {
                        name = GetTypeName(decl, decl.Type);
                    }
                }

                Debug.Assert(!string.IsNullOrWhiteSpace(name));
                return(name);
            }

            case CXCursorKind.CXCursor_FieldDecl:
            case CXCursorKind.CXCursor_EnumConstantDecl:
            case CXCursorKind.CXCursor_FunctionDecl:
            {
                var name = decl.Spelling;
                Debug.Assert(!string.IsNullOrWhiteSpace(name));
                return(name);
            }

            case CXCursorKind.CXCursor_ParmDecl:
            {
                var name = decl.Spelling;

                if (string.IsNullOrWhiteSpace(name))
                {
                    name = "param";
                }

                Debug.Assert(!string.IsNullOrWhiteSpace(name));
                return(name);
            }

            case CXCursorKind.CXCursor_TypedefDecl:
            {
                switch (decl.Spelling)
                {
                case "int8_t":
                {
                    return("sbyte");
                }

                case "int16_t":
                {
                    return("short");
                }

                case "int32_t":
                {
                    return("int");
                }

                case "int64_t":
                {
                    return("long");
                }

                case "intptr_t":
                {
                    _outputBuilder.AddUsing("System");
                    return("IntPtr");
                }

                case "size_t":
                case "SIZE_T":
                {
                    _outputBuilder.AddUsing("System");
                    return("IntPtr");
                }

                case "time_t":
                {
                    return("long");
                }

                case "uint8_t":
                {
                    return("byte");
                }

                case "uint16_t":
                {
                    return("ushort");
                }

                case "uint32_t":
                {
                    return("uint");
                }

                case "uint64_t":
                {
                    return("ulong");
                }

                case "uintptr_t":
                {
                    _outputBuilder.AddUsing("System");
                    return("UIntPtr");
                }

                default:
                {
                    var typedefDecl = (TypedefDecl)decl;
                    return(GetCursorName(typedefDecl, typedefDecl.UnderlyingType));
                }
                }
            }

            default:
            {
                Unhandled(decl);
                return(string.Empty);
            }
            }
        }