Skip to content

Commit e4856b9

Browse files
committed
translate-c: translate C types to stage2 types
1 parent cb6c477 commit e4856b9

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

@@ -5089,6 +5090,176 @@ fn transType(rp: RestorePoint, ty: *const clang.Type, source_loc: clang.SourceLo
50895090
}
50905091
}
50915092

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

5559+
fn fail(
5560+
rp: RestorePoint,
5561+
err: anytype,
5562+
source_loc: clang.SourceLocation,
5563+
comptime format: []const u8,
5564+
args: anytype,
5565+
) (@TypeOf(err) || error{OutOfMemory}) {
5566+
try emitWarning(c, source_loc, format, args);
5567+
return err;
5568+
}
5569+
53885570
pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) !void {
53895571
// pub const name = @compileError(msg);
53905572
const pub_tok = try appendToken(c, .Keyword_pub, "pub");

0 commit comments

Comments
 (0)