translate-c: translate C types to stage2 types

This commit is contained in:
Veikka Tuominen 2021-01-31 12:19:09 +02:00
parent 7051ef32bf
commit 6ecec4c8b7
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
2 changed files with 238 additions and 0 deletions

View File

@ -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");

View File

@ -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,