diff options
| -rw-r--r-- | src/translate_c.zig | 182 | ||||
| -rw-r--r-- | src/type.zig | 56 |
2 files changed, 238 insertions, 0 deletions
diff --git a/src/translate_c.zig b/src/translate_c.zig index a7d79e655a..e6629592ed 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -10,6 +10,7 @@ const ctok = std.c.tokenizer; const CToken = std.c.Token; const mem = std.mem; const math = std.math; +const Type = @import("type.zig").Type; const CallingConvention = std.builtin.CallingConvention; @@ -5178,6 +5179,176 @@ fn transType(rp: RestorePoint, ty: *const clang.Type, source_loc: clang.SourceLo } } +fn transType1(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Type { + switch (ty.getTypeClass()) { + .Builtin => { + const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); + return Type.initTag(switch (builtin_ty.getKind()) { + .Void => .c_void, + .Bool => .bool, + .Char_U, .UChar, .Char_S, .Char8 => .u8, + .SChar => .i8, + .UShort => .c_ushort, + .UInt => .c_uint, + .ULong => .c_ulong, + .ULongLong => .c_ulonglong, + .Short => .c_short, + .Int => .c_int, + .Long => .c_long, + .LongLong => .c_longlong, + .UInt128 => .u128, + .Int128 => .i128, + .Float => .f32, + .Double => .f64, + .Float128 => .f128, + .Float16 => .f16, + .LongDouble => .c_longdouble, + else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), + }); + }, + .FunctionProto => { + const fn_proto_ty = @ptrCast(*const clang.FunctionProtoType, ty); + return transFnProto(c, null, fn_proto_ty, source_loc, null, false); + }, + .FunctionNoProto => { + const fn_no_proto_ty = @ptrCast(*const clang.FunctionType, ty); + return transFnNoProto(c, fn_no_proto_ty, source_loc, null, false); + }, + .Paren => { + const paren_ty = @ptrCast(*const clang.ParenType, ty); + return transQualType(c, paren_ty.getInnerType(), source_loc); + }, + .Pointer => { + const child_qt = ty.getPointeeType(); + if (qualTypeChildIsFnProto(child_qt)) { + return Type.optional_single_mut_pointer.create(c.arena, try transQualType(c, child_qt, source_loc)); + } + const is_const = child_qt.isConstQualified(); + const is_volatile = child_qt.isVolatileQualified(); + const elem_type = try transQualType(c, child_qt, source_loc); + if (elem_type.zigTypeTag() == .Opaque) { + if (!is_volatile) { + if (is_const) { + return Type.optional_single_const_pointer.create(c.arena, elem_type); + } else { + return Type.optional_single_mut_pointer.create(c.arena, elem_type); + } + } + + return Type.pointer.create(c.arena, .{ + .pointee_type = elem_type, + .sentinel = null, + .@"align" = 0, + .bit_offset = 0, + .host_size = 0, + .@"allowzero" = false, + .mutable = !is_const, + .@"volatile" = true, + .size = .Single, + }); + } + + if (!is_volatile) { + if (is_const) { + return Type.c_const_pointer.create(c.arena, elem_type); + } else { + return Type.c_mut_pointer.create(c.arena, elem_type); + } + } + + return Type.pointer.create(c.arena, .{ + .pointee_type = elem_type, + .sentinel = null, + .@"align" = 0, + .bit_offset = 0, + .host_size = 0, + .@"allowzero" = false, + .mutable = !is_const, + .@"volatile" = true, + .size = .C, + }); + }, + .ConstantArray => { + const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty); + + const size_ap_int = const_arr_ty.getSize(); + const size = size_ap_int.getLimitedValue(math.maxInt(usize)); + const elem_type = try transType1(c, const_arr_ty.getElementType().getTypePtr(), source_loc); + + return Type.array.create(c.arena, .{ .len = size, .elem_type = elem_type }); + }, + .IncompleteArray => { + const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty); + + const child_qt = incomplete_array_ty.getElementType(); + const is_const = child_qt.isConstQualified(); + const is_volatile = child_qt.isVolatileQualified(); + const elem_type = try transQualType(c, child_qt, source_loc); + + if (!is_volatile) { + if (is_const) { + return Type.c_const_pointer.create(c.arena, elem_type); + } else { + return Type.c_mut_pointer.create(c.arena, elem_type); + } + } + + return Type.pointer.create(c.arena, .{ + .pointee_type = elem_type, + .sentinel = null, + .@"align" = 0, + .bit_offset = 0, + .host_size = 0, + .@"allowzero" = false, + .mutable = !is_const, + .@"volatile" = true, + .size = .C, + }); + }, + .Typedef => { + const typedef_ty = @ptrCast(*const clang.TypedefType, ty); + + const typedef_decl = typedef_ty.getDecl(); + return (try transTypeDef(c, typedef_decl, false)) orelse + fail(c, error.UnsupportedType, source_loc, "unable to translate typedef declaration", .{}); + }, + .Record => { + const record_ty = @ptrCast(*const clang.RecordType, ty); + + const record_decl = record_ty.getDecl(); + return (try transRecordDecl(c, record_decl)) orelse + fail(c, error.UnsupportedType, source_loc, "unable to resolve record declaration", .{}); + }, + .Enum => { + const enum_ty = @ptrCast(*const clang.EnumType, ty); + + const enum_decl = enum_ty.getDecl(); + return (try transEnumDecl(c, enum_decl)) orelse + fail(c, error.UnsupportedType, source_loc, "unable to translate enum declaration", .{}); + }, + .Elaborated => { + const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty); + return transQualType(c, elaborated_ty.getNamedType(), source_loc); + }, + .Decayed => { + const decayed_ty = @ptrCast(*const clang.DecayedType, ty); + return transQualType(c, decayed_ty.getDecayedType(), source_loc); + }, + .Attributed => { + const attributed_ty = @ptrCast(*const clang.AttributedType, ty); + return transQualType(c, attributed_ty.getEquivalentType(), source_loc); + }, + .MacroQualified => { + const macroqualified_ty = @ptrCast(*const clang.MacroQualifiedType, ty); + return transQualType(c, macroqualified_ty.getModifiedType(), source_loc); + }, + else => { + const type_name = c.str(ty.getTypeClassName()); + return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name}); + }, + } +} + fn qualTypeWasDemotedToOpaque(c: *Context, qt: clang.QualType) bool { const ty = qt.getTypePtr(); switch (qt.getTypeClass()) { @@ -5474,6 +5645,17 @@ fn emitWarning(c: *Context, loc: clang.SourceLocation, comptime format: []const _ = try appendTokenFmt(c, .LineComment, "// {s}: warning: " ++ format, args_prefix ++ args); } +fn fail( + rp: RestorePoint, + err: anytype, + source_loc: clang.SourceLocation, + comptime format: []const u8, + args: anytype, +) (@TypeOf(err) || error{OutOfMemory}) { + try emitWarning(c, source_loc, format, args); + return err; +} + pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) !void { // pub const name = @compileError(msg); const pub_tok = try appendToken(c, .Keyword_pub, "pub"); diff --git a/src/type.zig b/src/type.zig index e1006e554c..7d3308e403 100644 --- a/src/type.zig +++ b/src/type.zig @@ -28,6 +28,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -357,6 +359,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -506,6 +510,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -772,6 +778,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -868,6 +876,7 @@ pub const Type = extern union { .i16, .u16 => return 2, .i32, .u32 => return 4, .i64, .u64 => return 8, + .u128, .i128 => return 16, .isize, .usize, @@ -1010,6 +1019,7 @@ pub const Type = extern union { .i16, .u16 => return 2, .i32, .u32 => return 4, .i64, .u64 => return 8, + .u128, .i128 => return 16, .@"anyframe", .anyframe_T, .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8), @@ -1109,6 +1119,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -1191,6 +1203,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -1278,6 +1292,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -1359,6 +1375,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -1440,6 +1458,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -1522,6 +1542,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -1776,6 +1798,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -1856,6 +1880,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2009,6 +2035,8 @@ pub const Type = extern union { .i16, .i32, .i64, + .u128, + .i128, => true, }; } @@ -2061,6 +2089,8 @@ pub const Type = extern union { .i16, .i32, .i64, + .u128, + .i128, .optional, .optional_single_mut_pointer, .optional_single_const_pointer, @@ -2227,6 +2257,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .optional, .optional_single_mut_pointer, .optional_single_const_pointer, @@ -2333,6 +2365,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2417,6 +2451,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2500,6 +2536,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2583,6 +2621,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2663,6 +2703,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2743,6 +2785,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2793,6 +2837,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2874,6 +2920,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -2971,6 +3019,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -3060,6 +3110,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, @@ -3193,6 +3245,8 @@ pub const Type = extern union { i32, u64, i64, + u128, + i128, usize, isize, c_short, @@ -3277,6 +3331,8 @@ pub const Type = extern union { .i32, .u64, .i64, + .u128, + .i128, .usize, .isize, .c_short, |
