Skip to content

Commit d63ac84

Browse files
committed
translate-c: translate C types to stage2 types
1 parent 4d08197 commit d63ac84

File tree

2 files changed

+238
-0
lines changed

2 files changed

+238
-0
lines changed

src/translate_c.zig

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const ctok = std.c.tokenizer;
1010
const CToken = std.c.Token;
1111
const mem = std.mem;
1212
const math = std.math;
13+
const Type = @import("type.zig").Type;
1314

1415
const CallingConvention = std.builtin.CallingConvention;
1516

@@ -5115,6 +5116,176 @@ fn transType(rp: RestorePoint, ty: *const clang.Type, source_loc: clang.SourceLo
51155116
}
51165117
}
51175118

5119+
fn transType1(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Type {
5120+
switch (ty.getTypeClass()) {
5121+
.Builtin => {
5122+
const builtin_ty = @ptrCast(*const clang.BuiltinType, ty);
5123+
return Type.initTag(switch (builtin_ty.getKind()) {
5124+
.Void => .c_void,
5125+
.Bool => .bool,
5126+
.Char_U, .UChar, .Char_S, .Char8 => .u8,
5127+
.SChar => .i8,
5128+
.UShort => .c_ushort,
5129+
.UInt => .c_uint,
5130+
.ULong => .c_ulong,
5131+
.ULongLong => .c_ulonglong,
5132+
.Short => .c_short,
5133+
.Int => .c_int,
5134+
.Long => .c_long,
5135+
.LongLong => .c_longlong,
5136+
.UInt128 => .u128,
5137+
.Int128 => .i128,
5138+
.Float => .f32,
5139+
.Double => .f64,
5140+
.Float128 => .f128,
5141+
.Float16 => .f16,
5142+
.LongDouble => .c_longdouble,
5143+
else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
5144+
});
5145+
},
5146+
.FunctionProto => {
5147+
const fn_proto_ty = @ptrCast(*const clang.FunctionProtoType, ty);
5148+
return transFnProto(c, null, fn_proto_ty, source_loc, null, false);
5149+
},
5150+
.FunctionNoProto => {
5151+
const fn_no_proto_ty = @ptrCast(*const clang.FunctionType, ty);
5152+
return transFnNoProto(c, fn_no_proto_ty, source_loc, null, false);
5153+
},
5154+
.Paren => {
5155+
const paren_ty = @ptrCast(*const clang.ParenType, ty);
5156+
return transQualType(c, paren_ty.getInnerType(), source_loc);
5157+
},
5158+
.Pointer => {
5159+
const child_qt = ty.getPointeeType();
5160+
if (qualTypeChildIsFnProto(child_qt)) {
5161+
return Type.optional_single_mut_pointer.create(c.arena, try transQualType(c, child_qt, source_loc));
5162+
}
5163+
const is_const = child_qt.isConstQualified();
5164+
const is_volatile = child_qt.isVolatileQualified();
5165+
const elem_type = try transQualType(c, child_qt, source_loc);
5166+
if (elem_type.zigTypeTag() == .Opaque) {
5167+
if (!is_volatile) {
5168+
if (is_const) {
5169+
return Type.optional_single_const_pointer.create(c.arena, elem_type);
5170+
} else {
5171+
return Type.optional_single_mut_pointer.create(c.arena, elem_type);
5172+
}
5173+
}
5174+
5175+
return Type.pointer.create(c.arena, .{
5176+
.pointee_type = elem_type,
5177+
.sentinel = null,
5178+
.@"align" = 0,
5179+
.bit_offset = 0,
5180+
.host_size = 0,
5181+
.@"allowzero" = false,
5182+
.mutable = !is_const,
5183+
.@"volatile" = true,
5184+
.size = .Single,
5185+
});
5186+
}
5187+
5188+
if (!is_volatile) {
5189+
if (is_const) {
5190+
return Type.c_const_pointer.create(c.arena, elem_type);
5191+
} else {
5192+
return Type.c_mut_pointer.create(c.arena, elem_type);
5193+
}
5194+
}
5195+
5196+
return Type.pointer.create(c.arena, .{
5197+
.pointee_type = elem_type,
5198+
.sentinel = null,
5199+
.@"align" = 0,
5200+
.bit_offset = 0,
5201+
.host_size = 0,
5202+
.@"allowzero" = false,
5203+
.mutable = !is_const,
5204+
.@"volatile" = true,
5205+
.size = .C,
5206+
});
5207+
},
5208+
.ConstantArray => {
5209+
const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty);
5210+
5211+
const size_ap_int = const_arr_ty.getSize();
5212+
const size = size_ap_int.getLimitedValue(math.maxInt(usize));
5213+
const elem_type = try transType1(c, const_arr_ty.getElementType().getTypePtr(), source_loc);
5214+
5215+
return Type.array.create(c.arena, .{ .len = size, .elem_type = elem_type });
5216+
},
5217+
.IncompleteArray => {
5218+
const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty);
5219+
5220+
const child_qt = incomplete_array_ty.getElementType();
5221+
const is_const = child_qt.isConstQualified();
5222+
const is_volatile = child_qt.isVolatileQualified();
5223+
const elem_type = try transQualType(c, child_qt, source_loc);
5224+
5225+
if (!is_volatile) {
5226+
if (is_const) {
5227+
return Type.c_const_pointer.create(c.arena, elem_type);
5228+
} else {
5229+
return Type.c_mut_pointer.create(c.arena, elem_type);
5230+
}
5231+
}
5232+
5233+
return Type.pointer.create(c.arena, .{
5234+
.pointee_type = elem_type,
5235+
.sentinel = null,
5236+
.@"align" = 0,
5237+
.bit_offset = 0,
5238+
.host_size = 0,
5239+
.@"allowzero" = false,
5240+
.mutable = !is_const,
5241+
.@"volatile" = true,
5242+
.size = .C,
5243+
});
5244+
},
5245+
.Typedef => {
5246+
const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
5247+
5248+
const typedef_decl = typedef_ty.getDecl();
5249+
return (try transTypeDef(c, typedef_decl, false)) orelse
5250+
fail(c, error.UnsupportedType, source_loc, "unable to translate typedef declaration", .{});
5251+
},
5252+
.Record => {
5253+
const record_ty = @ptrCast(*const clang.RecordType, ty);
5254+
5255+
const record_decl = record_ty.getDecl();
5256+
return (try transRecordDecl(c, record_decl)) orelse
5257+
fail(c, error.UnsupportedType, source_loc, "unable to resolve record declaration", .{});
5258+
},
5259+
.Enum => {
5260+
const enum_ty = @ptrCast(*const clang.EnumType, ty);
5261+
5262+
const enum_decl = enum_ty.getDecl();
5263+
return (try transEnumDecl(c, enum_decl)) orelse
5264+
fail(c, error.UnsupportedType, source_loc, "unable to translate enum declaration", .{});
5265+
},
5266+
.Elaborated => {
5267+
const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty);
5268+
return transQualType(c, elaborated_ty.getNamedType(), source_loc);
5269+
},
5270+
.Decayed => {
5271+
const decayed_ty = @ptrCast(*const clang.DecayedType, ty);
5272+
return transQualType(c, decayed_ty.getDecayedType(), source_loc);
5273+
},
5274+
.Attributed => {
5275+
const attributed_ty = @ptrCast(*const clang.AttributedType, ty);
5276+
return transQualType(c, attributed_ty.getEquivalentType(), source_loc);
5277+
},
5278+
.MacroQualified => {
5279+
const macroqualified_ty = @ptrCast(*const clang.MacroQualifiedType, ty);
5280+
return transQualType(c, macroqualified_ty.getModifiedType(), source_loc);
5281+
},
5282+
else => {
5283+
const type_name = c.str(ty.getTypeClassName());
5284+
return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name});
5285+
},
5286+
}
5287+
}
5288+
51185289
fn qualTypeWasDemotedToOpaque(c: *Context, qt: clang.QualType) bool {
51195290
const ty = qt.getTypePtr();
51205291
switch (qt.getTypeClass()) {
@@ -5411,6 +5582,17 @@ fn emitWarning(c: *Context, loc: clang.SourceLocation, comptime format: []const
54115582
_ = try appendTokenFmt(c, .LineComment, "// {s}: warning: " ++ format, args_prefix ++ args);
54125583
}
54135584

5585+
fn fail(
5586+
rp: RestorePoint,
5587+
err: anytype,
5588+
source_loc: clang.SourceLocation,
5589+
comptime format: []const u8,
5590+
args: anytype,
5591+
) (@TypeOf(err) || error{OutOfMemory}) {
5592+
try emitWarning(c, source_loc, format, args);
5593+
return err;
5594+
}
5595+
54145596
pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) !void {
54155597
// pub const name = @compileError(msg);
54165598
const pub_tok = try appendToken(c, .Keyword_pub, "pub");

0 commit comments

Comments
 (0)