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)); } } }
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); } } }
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); } } }
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); } } }
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); } } }
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); } } }
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); } } }