| ... | ... | @@ -10,6 +10,7 @@ const ctok = std.c.tokenizer; |
| 10 | 10 | const CToken = std.c.Token; |
| 11 | 11 | const mem = std.mem; |
| 12 | 12 | const math = std.math; |
| 13 | const Type = @import("type.zig").Type; |
| 13 | 14 | |
| 14 | 15 | const CallingConvention = std.builtin.CallingConvention; |
| 15 | 16 | |
| ... | ... | @@ -5178,6 +5179,176 @@ fn transType(rp: RestorePoint, ty: *const clang.Type, source_loc: clang.SourceLo |
| 5178 | 5179 | } |
| 5179 | 5180 | } |
| 5180 | 5181 | |
| 5182 | fn transType1(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Type { |
| 5183 | switch (ty.getTypeClass()) { |
| 5184 | .Builtin => { |
| 5185 | const builtin_ty = @ptrCast(*const clang.BuiltinType, ty); |
| 5186 | return Type.initTag(switch (builtin_ty.getKind()) { |
| 5187 | .Void => .c_void, |
| 5188 | .Bool => .bool, |
| 5189 | .Char_U, .UChar, .Char_S, .Char8 => .u8, |
| 5190 | .SChar => .i8, |
| 5191 | .UShort => .c_ushort, |
| 5192 | .UInt => .c_uint, |
| 5193 | .ULong => .c_ulong, |
| 5194 | .ULongLong => .c_ulonglong, |
| 5195 | .Short => .c_short, |
| 5196 | .Int => .c_int, |
| 5197 | .Long => .c_long, |
| 5198 | .LongLong => .c_longlong, |
| 5199 | .UInt128 => .u128, |
| 5200 | .Int128 => .i128, |
| 5201 | .Float => .f32, |
| 5202 | .Double => .f64, |
| 5203 | .Float128 => .f128, |
| 5204 | .Float16 => .f16, |
| 5205 | .LongDouble => .c_longdouble, |
| 5206 | else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}), |
| 5207 | }); |
| 5208 | }, |
| 5209 | .FunctionProto => { |
| 5210 | const fn_proto_ty = @ptrCast(*const clang.FunctionProtoType, ty); |
| 5211 | return transFnProto(c, null, fn_proto_ty, source_loc, null, false); |
| 5212 | }, |
| 5213 | .FunctionNoProto => { |
| 5214 | const fn_no_proto_ty = @ptrCast(*const clang.FunctionType, ty); |
| 5215 | return transFnNoProto(c, fn_no_proto_ty, source_loc, null, false); |
| 5216 | }, |
| 5217 | .Paren => { |
| 5218 | const paren_ty = @ptrCast(*const clang.ParenType, ty); |
| 5219 | return transQualType(c, paren_ty.getInnerType(), source_loc); |
| 5220 | }, |
| 5221 | .Pointer => { |
| 5222 | const child_qt = ty.getPointeeType(); |
| 5223 | if (qualTypeChildIsFnProto(child_qt)) { |
| 5224 | return Type.optional_single_mut_pointer.create(c.arena, try transQualType(c, child_qt, source_loc)); |
| 5225 | } |
| 5226 | const is_const = child_qt.isConstQualified(); |
| 5227 | const is_volatile = child_qt.isVolatileQualified(); |
| 5228 | const elem_type = try transQualType(c, child_qt, source_loc); |
| 5229 | if (elem_type.zigTypeTag() == .Opaque) { |
| 5230 | if (!is_volatile) { |
| 5231 | if (is_const) { |
| 5232 | return Type.optional_single_const_pointer.create(c.arena, elem_type); |
| 5233 | } else { |
| 5234 | return Type.optional_single_mut_pointer.create(c.arena, elem_type); |
| 5235 | } |
| 5236 | } |
| 5237 | |
| 5238 | return Type.pointer.create(c.arena, .{ |
| 5239 | .pointee_type = elem_type, |
| 5240 | .sentinel = null, |
| 5241 | .@"align" = 0, |
| 5242 | .bit_offset = 0, |
| 5243 | .host_size = 0, |
| 5244 | .@"allowzero" = false, |
| 5245 | .mutable = !is_const, |
| 5246 | .@"volatile" = true, |
| 5247 | .size = .Single, |
| 5248 | }); |
| 5249 | } |
| 5250 | |
| 5251 | if (!is_volatile) { |
| 5252 | if (is_const) { |
| 5253 | return Type.c_const_pointer.create(c.arena, elem_type); |
| 5254 | } else { |
| 5255 | return Type.c_mut_pointer.create(c.arena, elem_type); |
| 5256 | } |
| 5257 | } |
| 5258 | |
| 5259 | return Type.pointer.create(c.arena, .{ |
| 5260 | .pointee_type = elem_type, |
| 5261 | .sentinel = null, |
| 5262 | .@"align" = 0, |
| 5263 | .bit_offset = 0, |
| 5264 | .host_size = 0, |
| 5265 | .@"allowzero" = false, |
| 5266 | .mutable = !is_const, |
| 5267 | .@"volatile" = true, |
| 5268 | .size = .C, |
| 5269 | }); |
| 5270 | }, |
| 5271 | .ConstantArray => { |
| 5272 | const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty); |
| 5273 | |
| 5274 | const size_ap_int = const_arr_ty.getSize(); |
| 5275 | const size = size_ap_int.getLimitedValue(math.maxInt(usize)); |
| 5276 | const elem_type = try transType1(c, const_arr_ty.getElementType().getTypePtr(), source_loc); |
| 5277 | |
| 5278 | return Type.array.create(c.arena, .{ .len = size, .elem_type = elem_type }); |
| 5279 | }, |
| 5280 | .IncompleteArray => { |
| 5281 | const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty); |
| 5282 | |
| 5283 | const child_qt = incomplete_array_ty.getElementType(); |
| 5284 | const is_const = child_qt.isConstQualified(); |
| 5285 | const is_volatile = child_qt.isVolatileQualified(); |
| 5286 | const elem_type = try transQualType(c, child_qt, source_loc); |
| 5287 | |
| 5288 | if (!is_volatile) { |
| 5289 | if (is_const) { |
| 5290 | return Type.c_const_pointer.create(c.arena, elem_type); |
| 5291 | } else { |
| 5292 | return Type.c_mut_pointer.create(c.arena, elem_type); |
| 5293 | } |
| 5294 | } |
| 5295 | |
| 5296 | return Type.pointer.create(c.arena, .{ |
| 5297 | .pointee_type = elem_type, |
| 5298 | .sentinel = null, |
| 5299 | .@"align" = 0, |
| 5300 | .bit_offset = 0, |
| 5301 | .host_size = 0, |
| 5302 | .@"allowzero" = false, |
| 5303 | .mutable = !is_const, |
| 5304 | .@"volatile" = true, |
| 5305 | .size = .C, |
| 5306 | }); |
| 5307 | }, |
| 5308 | .Typedef => { |
| 5309 | const typedef_ty = @ptrCast(*const clang.TypedefType, ty); |
| 5310 | |
| 5311 | const typedef_decl = typedef_ty.getDecl(); |
| 5312 | return (try transTypeDef(c, typedef_decl, false)) orelse |
| 5313 | fail(c, error.UnsupportedType, source_loc, "unable to translate typedef declaration", .{}); |
| 5314 | }, |
| 5315 | .Record => { |
| 5316 | const record_ty = @ptrCast(*const clang.RecordType, ty); |
| 5317 | |
| 5318 | const record_decl = record_ty.getDecl(); |
| 5319 | return (try transRecordDecl(c, record_decl)) orelse |
| 5320 | fail(c, error.UnsupportedType, source_loc, "unable to resolve record declaration", .{}); |
| 5321 | }, |
| 5322 | .Enum => { |
| 5323 | const enum_ty = @ptrCast(*const clang.EnumType, ty); |
| 5324 | |
| 5325 | const enum_decl = enum_ty.getDecl(); |
| 5326 | return (try transEnumDecl(c, enum_decl)) orelse |
| 5327 | fail(c, error.UnsupportedType, source_loc, "unable to translate enum declaration", .{}); |
| 5328 | }, |
| 5329 | .Elaborated => { |
| 5330 | const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty); |
| 5331 | return transQualType(c, elaborated_ty.getNamedType(), source_loc); |
| 5332 | }, |
| 5333 | .Decayed => { |
| 5334 | const decayed_ty = @ptrCast(*const clang.DecayedType, ty); |
| 5335 | return transQualType(c, decayed_ty.getDecayedType(), source_loc); |
| 5336 | }, |
| 5337 | .Attributed => { |
| 5338 | const attributed_ty = @ptrCast(*const clang.AttributedType, ty); |
| 5339 | return transQualType(c, attributed_ty.getEquivalentType(), source_loc); |
| 5340 | }, |
| 5341 | .MacroQualified => { |
| 5342 | const macroqualified_ty = @ptrCast(*const clang.MacroQualifiedType, ty); |
| 5343 | return transQualType(c, macroqualified_ty.getModifiedType(), source_loc); |
| 5344 | }, |
| 5345 | else => { |
| 5346 | const type_name = c.str(ty.getTypeClassName()); |
| 5347 | return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name}); |
| 5348 | }, |
| 5349 | } |
| 5350 | } |
| 5351 | |
| 5181 | 5352 | fn qualTypeWasDemotedToOpaque(c: *Context, qt: clang.QualType) bool { |
| 5182 | 5353 | const ty = qt.getTypePtr(); |
| 5183 | 5354 | switch (qt.getTypeClass()) { |
| ... | ... | @@ -5474,6 +5645,17 @@ fn emitWarning(c: *Context, loc: clang.SourceLocation, comptime format: []const |
| 5474 | 5645 | _ = try appendTokenFmt(c, .LineComment, "// {s}: warning: " ++ format, args_prefix ++ args); |
| 5475 | 5646 | } |
| 5476 | 5647 | |
| 5648 | fn fail( |
| 5649 | rp: RestorePoint, |
| 5650 | err: anytype, |
| 5651 | source_loc: clang.SourceLocation, |
| 5652 | comptime format: []const u8, |
| 5653 | args: anytype, |
| 5654 | ) (@TypeOf(err) || error{OutOfMemory}) { |
| 5655 | try emitWarning(c, source_loc, format, args); |
| 5656 | return err; |
| 5657 | } |
| 5658 | |
| 5477 | 5659 | pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) !void { |
| 5478 | 5660 | // pub const name = @compileError(msg); |
| 5479 | 5661 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); |