def test_void_int(self) -> None: parser = cpptypeinfo.TypeParser() cpptypeinfo.parse_source(parser, 'void func(int a);', debug=True) func = parser.root_namespace.functions[0] self.assertEqual(TypeRef(cpptypeinfo.Void(), False), func.result) self.assertEqual(1, len(func.params)) self.assertEqual(TypeRef(cpptypeinfo.Int32()), func.params[0].typeref)
def test_excpt(self) -> None: parser = cpptypeinfo.TypeParser() cpptypeinfo.parse_source(parser, ''' int __cdecl __C_specific_handler( struct _EXCEPTION_RECORD* ExceptionRecord, void* EstablisherFrame, struct _CONTEXT* ContextRecord, struct _DISPATCHER_CONTEXT* DispatcherContext ); ''', debug=True) func = parser.root_namespace.functions[0] self.assertEqual(TypeRef(cpptypeinfo.Void(), False), func.result) self.assertEqual(1, len(func.params)) self.assertEqual(TypeRef(cpptypeinfo.Int32()), func.params[0].typeref)
def parse_functionproto(self, c: cindex.Cursor) -> Function: children = [child for child in c.get_children()] def to_param(child): decl = self.cindex_type_to_cpptypeinfo(child.type, child) ref = TypeRef(decl, child.type.is_const_qualified()) return Param(child.spelling, ref) params = [] result: cpptypeinfo.Type = cpptypeinfo.Void() for child in children: if child.kind == cindex.CursorKind.TYPE_REF: result = self.get(child.referenced) elif child.kind == cindex.CursorKind.PARM_DECL: params.append(to_param(child)) return Function(result, params)
def get_type_from_hash(self, t: cindex.Type, c: cindex.Cursor) -> TypeRef: ''' 登録済みの型をhashから取得する ''' if t.kind in (cindex.TypeKind.ELABORATED, cindex.TypeKind.RECORD, cindex.TypeKind.TYPEDEF, cindex.TypeKind.ENUM): # structなど children = [child for child in c.get_children()] for child in children: if child.kind in (cindex.CursorKind.STRUCT_DECL, cindex.CursorKind.UNION_DECL): decl = self.get(child) if decl: return TypeRef(decl, t.is_const_qualified()) raise Exception() elif child.kind == cindex.CursorKind.TYPE_REF: if not self.has(child.referenced): self.parse_cursor(child.referenced) decl = self.get(child.referenced) if decl: return TypeRef(decl, t.is_const_qualified()) raise Exception() elif child.kind in (cindex.CursorKind.UNEXPOSED_ATTR, cindex.CursorKind.DLLIMPORT_ATTR): pass else: raise Exception() raise Exception() if t.kind == cindex.TypeKind.FUNCTIONPROTO: return TypeRef(cpptypeinfo.Void(), t.is_const_qualified()) children = [child for child in c.get_children()] raise Exception()
def parse_typedef(self, c: cindex.Cursor) -> None: if self.has(c): # already exists return underlying, stack = strip_nest_type(c.underlying_typedef_type) primitive = get_primitive_type(underlying) if primitive: typedef = self.parser.typedef(c.spelling, restore_nest_type(primitive, stack)) typedef.file = pathlib.Path(c.location.file.name) typedef.line = c.location.line self.add(c, typedef) return elaborated = self.typedef_elaborated_type(underlying, c) if elaborated: typedef = self.parser.typedef(c.spelling, restore_nest_type(elaborated, stack)) typedef.file = pathlib.Path(c.location.file.name) typedef.line = c.location.line self.add(c, typedef) return if underlying.kind == cindex.TypeKind.TYPEDEF: children = [child for child in c.get_children()] for child in children: if child.kind == cindex.CursorKind.TYPE_REF: if not self.has(child.referenced): self.parse_cursor(child.referenced) usertype = self.get(child.referenced) if usertype: typedef = self.parser.typedef( c.spelling, restore_nest_type(usertype, stack)) typedef.file = pathlib.Path(c.location.file.name) typedef.line = c.location.line self.add(c, typedef) return raise Exception() if underlying.kind == cindex.TypeKind.FUNCTIONPROTO: function = self.parse_functionproto(c) typedef = self.parser.typedef( c.spelling, TypeRef(function, c.type.is_const_qualified())) typedef.file = pathlib.Path(c.location.file.name) typedef.line = c.location.line self.add(c, typedef) return if underlying.kind == cindex.TypeKind.UNEXPOSED: # typedef decltype(__nullptr) nullptr_t; children = [child for child in c.get_children()] if c.spelling == 'nullptr_t': typedef = self.parser.typedef(c.spelling, TypeRef(cpptypeinfo.Void())) typedef.file = pathlib.Path(c.location.file.name) typedef.line = c.location.line self.add(c, typedef) return raise Exception() raise Exception()
def get_primitive_type(t: cindex.Type) -> Optional[TypeRef]: ''' TypeKind.VOID = TypeKind(2) TypeKind.BOOL = TypeKind(3) TypeKind.CHAR_U = TypeKind(4) TypeKind.UCHAR = TypeKind(5) TypeKind.CHAR16 = TypeKind(6) TypeKind.CHAR32 = TypeKind(7) TypeKind.USHORT = TypeKind(8) TypeKind.UINT = TypeKind(9) TypeKind.ULONG = TypeKind(10) TypeKind.ULONGLONG = TypeKind(11) TypeKind.UINT128 = TypeKind(12) TypeKind.CHAR_S = TypeKind(13) TypeKind.SCHAR = TypeKind(14) TypeKind.WCHAR = TypeKind(15) TypeKind.SHORT = TypeKind(16) TypeKind.INT = TypeKind(17) TypeKind.LONG = TypeKind(18) TypeKind.LONGLONG = TypeKind(19) TypeKind.INT128 = TypeKind(20) TypeKind.FLOAT = TypeKind(21) TypeKind.DOUBLE = TypeKind(22) TypeKind.LONGDOUBLE = TypeKind(23) TypeKind.NULLPTR = TypeKind(24) ''' # void if t.kind == cindex.TypeKind.VOID: # void return TypeRef(cpptypeinfo.Void(), t.is_const_qualified()) # bool elif t.kind == cindex.TypeKind.BOOL: # void assert (t.get_size() == 1) return TypeRef(cpptypeinfo.Bool(), t.is_const_qualified()) # int elif t.kind == cindex.TypeKind.CHAR_S: # char assert (t.get_size() == 1) return TypeRef(cpptypeinfo.Int8(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.SCHAR: # signed char assert (t.get_size() == 1) return TypeRef(cpptypeinfo.Int8(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.SHORT: # short assert (t.get_size() == 2) return TypeRef(cpptypeinfo.Int16(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.INT: # int assert (t.get_size() == 4) return TypeRef(cpptypeinfo.Int32(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.LONG: # long assert (t.get_size() == 4) return TypeRef(cpptypeinfo.Int32(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.LONGLONG: # long long assert (t.get_size() == 8) return TypeRef(cpptypeinfo.Int64(), t.is_const_qualified()) # unsigned elif t.kind == cindex.TypeKind.UCHAR: # unsigned char assert (t.get_size() == 1) return TypeRef(cpptypeinfo.UInt8(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.WCHAR: # wchar_t assert (t.get_size() == 2) return TypeRef(cpptypeinfo.UInt16(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.USHORT: # unsigned short assert (t.get_size() == 2) return TypeRef(cpptypeinfo.UInt16(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.UINT: # unsigned int assert (t.get_size() == 4) return TypeRef(cpptypeinfo.UInt32(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.ULONG: # unsigned long assert (t.get_size() == 4) return TypeRef(cpptypeinfo.UInt32(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.ULONGLONG: # unsigned __int64 assert (t.get_size() == 8) return TypeRef(cpptypeinfo.UInt64(), t.is_const_qualified()) # float elif t.kind == cindex.TypeKind.FLOAT: # float assert (t.get_size() == 4) return TypeRef(cpptypeinfo.Float(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.DOUBLE: # double assert (t.get_size() == 8) return TypeRef(cpptypeinfo.Double(), t.is_const_qualified()) elif t.kind == cindex.TypeKind.LONGDOUBLE: # double size = t.get_size() assert (size == 8) return TypeRef(cpptypeinfo.Double(), t.is_const_qualified()) return None
cpptypeinfo.Int8(): CSMarshalType('sbyte'), cpptypeinfo.Int16(): CSMarshalType('short'), cpptypeinfo.Int32(): CSMarshalType('int'), cpptypeinfo.Int64(): CSMarshalType('long'), cpptypeinfo.UInt8(): CSMarshalType('byte'), cpptypeinfo.UInt16(): CSMarshalType('ushort'), cpptypeinfo.UInt32(): CSMarshalType('uint'), cpptypeinfo.UInt64(): CSMarshalType('ulong'), cpptypeinfo.Float(): CSMarshalType('float'), cpptypeinfo.Double(): CSMarshalType('double'), cpptypeinfo.Bool(): CSMarshalType('bool', 'MarshalAs(UnmanagedType.U1)'), } # for function param cstype_pointer_map: Dict[cpptypeinfo.Type, CSMarshalType] = { cpptypeinfo.Void(): CSMarshalType('IntPtr'), cpptypeinfo.Int8(): CSMarshalType('string', 'MarshalAs(UnmanagedType.LPUTF8Str)'), cpptypeinfo.Bool(): CSMarshalType('ref bool', 'MarshalAs(UnmanagedType.U1)'), cpptypeinfo.Float(): CSMarshalType('ref float'), } class ExportFlag(enum.Flag): StructField = enum.auto() FunctionReturn = enum.auto() FunctionParam = enum.auto() All = StructField | FunctionReturn | FunctionParam
float r; float g; float b; float a; } ''' snippet_map = { 'd3d11': D3D11_SNIPPET, 'd2d1': D2D1_SNIPPET, 'd2dbasetypes': D2D_BASETYPES, } dlang_map: Dict[cpptypeinfo.Type, str] = { cpptypeinfo.Void(): 'void', cpptypeinfo.Int8(): 'byte', cpptypeinfo.Int16(): 'short', cpptypeinfo.Int32(): 'int', cpptypeinfo.Int64(): 'long', cpptypeinfo.UInt8(): 'ubyte', cpptypeinfo.UInt16(): 'ushort', cpptypeinfo.UInt32(): 'uint', cpptypeinfo.UInt64(): 'ulong', cpptypeinfo.Float(): 'float', cpptypeinfo.Double(): 'double', } def is_const(typeref: TypeRef) -> bool: if typeref.is_const:
'ImGuiOnceUponAFrame': parser.parse('struct ImGuiOnceUponAFrame'), 'ImGuiPayload': parser.parse('struct ImGuiPayload'), 'ImGuiSizeCallbackData': parser.parse('struct ImGuiSizeCallbackData'), 'ImGuiStorage': parser.parse('struct ImGuiStorage'), 'ImGuiStyle': parser.parse('struct ImGuiStyle'), 'ImGuiTextBuffer': parser.parse('struct ImGuiTextBuffer'), 'ImGuiTextFilter': parser.parse('struct ImGuiTextFilter'), 'ImTextureID': parser.typedef('ImTextureID', Pointer(cpptypeinfo.Void())), 'ImGuiID': parser.typedef('ImGuiID', cpptypeinfo.UInt32()), 'ImWchar': parser.typedef('ImWchar', cpptypeinfo.UInt16()), 'ImGuiCol': parser.typedef('ImGuiCol', cpptypeinfo.Int32()), 'ImGuiCond': parser.typedef('ImGuiCond', cpptypeinfo.Int32()), 'ImGuiDataType': parser.typedef('ImGuiDataType', cpptypeinfo.Int32()), 'ImGuiDir': parser.typedef('ImGuiDir', cpptypeinfo.Int32()), 'ImGuiKey': parser.typedef('ImGuiKey', cpptypeinfo.Int32()), 'ImGuiNavInput':