Generate getters which accept pNext chains with pointers instead of return value

This commit is contained in:
Robin Voetter
2020-11-26 14:34:29 +01:00
parent c4c0279ecc
commit 9b1e427cae

View File

@@ -145,6 +145,7 @@ fn Renderer(comptime WriterType: type) type {
const ParamType = enum { const ParamType = enum {
in_pointer, in_pointer,
out_pointer, out_pointer,
in_out_pointer,
bitflags, bitflags,
mut_buffer_len, mut_buffer_len,
buffer_len, buffer_len,
@@ -170,20 +171,36 @@ fn Renderer(comptime WriterType: type) type {
allocator: *Allocator, allocator: *Allocator,
registry: *const reg.Registry, registry: *const reg.Registry,
id_renderer: *IdRenderer, id_renderer: *IdRenderer,
declarations_by_name: std.StringHashMap(*const reg.DeclarationType),
fn init(writer: WriterType, allocator: *Allocator, registry: *const reg.Registry, id_renderer: *IdRenderer) !Self { fn init(writer: WriterType, allocator: *Allocator, registry: *const reg.Registry, id_renderer: *IdRenderer) !Self {
const tags = try allocator.alloc([]const u8, registry.tags.len); const tags = try allocator.alloc([]const u8, registry.tags.len);
errdefer allocator.free(tags);
for (tags) |*tag, i| tag.* = registry.tags[i].name; for (tags) |*tag, i| tag.* = registry.tags[i].name;
var declarations_by_name = std.StringHashMap(*const reg.DeclarationType).init(allocator);
errdefer declarations_by_name.deinit();
for (registry.decls) |*decl| {
const result = try declarations_by_name.getOrPut(decl.name);
if (result.found_existing) {
return error.InvalidRegistry;
}
result.entry.value = &decl.decl_type;
}
return Self{ return Self{
.writer = writer, .writer = writer,
.allocator = allocator, .allocator = allocator,
.registry = registry, .registry = registry,
.id_renderer = id_renderer, .id_renderer = id_renderer,
.declarations_by_name = declarations_by_name,
}; };
} }
fn deinit(self: Self) void { fn deinit(self: *Self) void {
self.declarations_by_name.deinit();
self.allocator.free(self.id_renderer.tags); self.allocator.free(self.id_renderer.tags);
self.id_renderer.deinit(); self.id_renderer.deinit();
} }
@@ -238,6 +255,50 @@ fn Renderer(comptime WriterType: type) type {
return mem.endsWith(u8, base_name, "Flags"); return mem.endsWith(u8, base_name, "Flags");
} }
fn containerHasField(self: Self, container: *const reg.Container, field_name: []const u8) bool {
for (container.fields) |field| {
if (mem.eql(u8, field, field_name)) {
return true;
}
}
return false;
}
fn isInOutPointer(self: Self, ptr: reg.Pointer) !bool {
if (ptr.child.* != .name) {
return false;
}
var name = ptr.child.name;
const decl = while (true) {
const decl = self.declarations_by_name.get(name) orelse return error.InvalidRegistry;
if (decl.* != .alias) {
break decl;
}
name = decl.alias.name;
} else unreachable;
if (decl.* != .container) {
return false;
}
const container = decl.container;
if (container.is_union) {
return false;
}
for (container.fields) |field| {
if (mem.eql(u8, field.name, "pNext")) {
return true;
}
}
return false;
}
fn classifyParam(self: Self, param: reg.Command.Param) !ParamType { fn classifyParam(self: Self, param: reg.Command.Param) !ParamType {
switch (param.param_type) { switch (param.param_type) {
.pointer => |ptr| { .pointer => |ptr| {
@@ -259,8 +320,13 @@ fn Renderer(comptime WriterType: type) type {
} }
if (ptr.size == .one and !ptr.is_optional) { if (ptr.size == .one and !ptr.is_optional) {
// Sometimes, a mutable pointer to a struct is taken, even though
// Vulkan expects this struct to be initialized. This is particularly the case
// for getting structs which include pNext chains.
if (ptr.is_const) { if (ptr.is_const) {
return .in_pointer; return .in_pointer;
} else if (try self.isInOutPointer(ptr)) {
return .in_out_pointer;
} else { } else {
return .out_pointer; return .out_pointer;
} }
@@ -860,6 +926,7 @@ fn Renderer(comptime WriterType: type) type {
try self.renderTypeInfo(param.param_type.pointer.child.*); try self.renderTypeInfo(param.param_type.pointer.child.*);
}, },
.out_pointer => continue, // Return value .out_pointer => continue, // Return value
.in_out_pointer,
.bitflags, // Special stuff handled in renderWrapperCall .bitflags, // Special stuff handled in renderWrapperCall
.buffer_len, .buffer_len,
.mut_buffer_len, .mut_buffer_len,
@@ -911,7 +978,10 @@ fn Renderer(comptime WriterType: type) type {
try self.writeIdentifierWithCase(.snake, param.name); try self.writeIdentifierWithCase(.snake, param.name);
try self.writer.writeAll(".toInt()"); try self.writer.writeAll(".toInt()");
}, },
.buffer_len, .mut_buffer_len, .other => { .in_out_pointer,
.buffer_len,
.mut_buffer_len,
.other => {
try self.writeIdentifierWithCase(.snake, param.name); try self.writeIdentifierWithCase(.snake, param.name);
}, },
} }