Handle foreign types

This commit is contained in:
Robin Voetter
2020-06-16 02:41:05 +02:00
parent baa1a68b53
commit 1631265a1c
2 changed files with 62 additions and 27 deletions

View File

@@ -139,7 +139,7 @@ const DeclarationResolver = struct {
var write_index: usize = 0; var write_index: usize = 0;
while (read_index < self.registry.decls.len) { while (read_index < self.registry.decls.len) {
const decl = self.registry.decls[read_index]; const decl = self.registry.decls[read_index];
if (self.declarations.contains(decl.name)) { if (decl.decl_type == .foreign or self.declarations.contains(decl.name)) {
self.registry.decls[write_index] = decl; self.registry.decls[write_index] = decl;
write_index += 1; write_index += 1;
} }

View File

@@ -6,28 +6,43 @@ const Allocator = mem.Allocator;
const preamble = const preamble =
\\const std = @import("std"); \\const std = @import("std");
\\const root = @import("root");
\\ \\
; ;
const BuiltinType = struct { const builtin_types = std.ComptimeStringMap([]const u8, .{
c_name: []const u8, .{"char", @typeName(u8)},
zig_name: []const u8 .{"float", @typeName(f32)},
}; .{"double", @typeName(f64)},
.{"uint8_t", @typeName(u8)},
.{"uint16_t", @typeName(u16)},
.{"uint32_t", @typeName(u32)},
.{"uint64_t", @typeName(u64)},
.{"int32_t", @typeName(i32)},
.{"int64_t", @typeName(i64)},
.{"size_t", @typeName(usize)},
.{"int", @typeName(c_int)},
});
const builtin_types = [_]BuiltinType{ const foreign_types = std.ComptimeStringMap([]const u8, .{
.{.c_name = "void", .zig_name = @typeName(void)}, .{"Display", "@Type(.Opaque)"},
.{.c_name = "char", .zig_name = @typeName(u8)}, .{"VisualID", @typeName(c_uint)},
.{.c_name = "float", .zig_name = @typeName(f32)}, .{"Window", @typeName(c_ulong)},
.{.c_name = "double", .zig_name = @typeName(f64)}, .{"RROutput", @typeName(c_ulong)},
.{.c_name = "uint8_t", .zig_name = @typeName(u8)}, .{"wl_display", "@Type(.Opaque)"},
.{.c_name = "uint16_t", .zig_name = @typeName(u16)}, .{"wl_surface", "@Type(.Opaque)"},
.{.c_name = "uint32_t", .zig_name = @typeName(u32)}, .{"HINSTANCE", "std.os.HINSTANCE"},
.{.c_name = "uint64_t", .zig_name = @typeName(u64)}, .{"HWND", "*@Type(.Opaque)"},
.{.c_name = "int32_t", .zig_name = @typeName(i32)}, .{"HMONITOR", "*@Type(.Opaque)"},
.{.c_name = "int64_t", .zig_name = @typeName(i64)}, .{"HANDLE", "std.os.HANDLE"},
.{.c_name = "size_t", .zig_name = @typeName(usize)}, .{"SECURITY_ATTRIBUTES", "std.os.SECURITY_ATTRIBUTES"},
.{.c_name = "int", .zig_name = @typeName(c_int)}, .{"DWORD", "std.os.DWORD"},
}; .{"LPCWSTR", "std.os.LPCWSTR"},
.{"xcb_connection_t", "@Type(.Opaque)"},
.{"xcb_visualid_t", @typeName(u32)},
.{"xcb_window_t", @typeName(u32)},
.{"zx_handle_t", @typeName(u32)},
});
fn eqlIgnoreCase(lhs: []const u8, rhs: []const u8) bool { fn eqlIgnoreCase(lhs: []const u8, rhs: []const u8) bool {
if (lhs.len != rhs.len) { if (lhs.len != rhs.len) {
@@ -116,14 +131,10 @@ fn Renderer(comptime WriterType: type) type {
} }
fn renderTypeName(self: *Self, name: []const u8) !void { fn renderTypeName(self: *Self, name: []const u8) !void {
for (builtin_types) |builtin_type| { if (builtin_types.get(name)) |zig_name| {
if (mem.eql(u8, name, builtin_type.c_name)) { try self.writer.writeAll(zig_name);
try self.writer.writeAll(builtin_type.zig_name);
return; return;
} }
}
// TODO: Handle foreign types
if (mem.startsWith(u8, name, "vk")) { if (mem.startsWith(u8, name, "vk")) {
// Function type, always render with the exact same text for linking purposes. // Function type, always render with the exact same text for linking purposes.
@@ -193,6 +204,7 @@ fn Renderer(comptime WriterType: type) type {
.enumeration => |enumeration| try self.renderEnumeration(decl.name, enumeration), .enumeration => |enumeration| try self.renderEnumeration(decl.name, enumeration),
.alias => |alias| try self.renderAlias(decl.name, alias), .alias => |alias| try self.renderAlias(decl.name, alias),
.opaque => try self.renderOpaque(decl.name), .opaque => try self.renderOpaque(decl.name),
.foreign => |foreign| try self.renderForeign(decl.name, foreign),
.typedef => |type_info| try self.renderTypedef(decl.name, type_info), .typedef => |type_info| try self.renderTypedef(decl.name, type_info),
else => {}, // unhandled for now else => {}, // unhandled for now
} }
@@ -267,6 +279,10 @@ fn Renderer(comptime WriterType: type) type {
} }
fn renderAlias(self: *Self, name: []const u8, alias: reg.Alias) !void { fn renderAlias(self: *Self, name: []const u8, alias: reg.Alias) !void {
if (alias.target == .other_command) {
return; // Skip these for now
}
try self.writer.writeAll("const "); try self.writer.writeAll("const ");
try self.renderTypeName(name); try self.renderTypeName(name);
try self.writer.writeAll(" = "); try self.writer.writeAll(" = ");
@@ -280,6 +296,25 @@ fn Renderer(comptime WriterType: type) type {
try self.writer.writeAll(" = @Type(.Opaque);\n"); try self.writer.writeAll(" = @Type(.Opaque);\n");
} }
fn renderForeign(self: *Self, name: []const u8, foreign: reg.Foreign) !void {
if (mem.eql(u8, foreign.depends, "vk_platform")) {
return; // Skip built-in types, they are handled differently
}
try self.writer.writeAll("const ");
try self.writeIdentifier(name);
try self.writer.print(" = if (@hasDecl(root, \"{}\")) root.", .{name});
try self.writeIdentifier(name);
try self.writer.writeAll(" else ");
if (foreign_types.get(name)) |default| {
try self.writer.writeAll(default);
try self.writer.writeAll(";\n");
} else {
try self.writer.print("@compileError(\"Missing type definition of '{}'\");\n", .{name});
}
}
fn renderTypedef(self: *Self, name: []const u8, type_info: reg.TypeInfo) !void { fn renderTypedef(self: *Self, name: []const u8, type_info: reg.TypeInfo) !void {
try self.writer.writeAll("const "); try self.writer.writeAll("const ");
try self.renderTypeName(name); try self.renderTypeName(name);