forked from mirror/vulkan-zig
Split out TypeInfo to TypeInfo and DeclarationType
This commit is contained in:
@@ -24,12 +24,14 @@ fn cmpFeatureLevels(a: FeatureLevel, b: FeatureLevel) std.math.Order {
|
|||||||
const DeclarationResolver = struct {
|
const DeclarationResolver = struct {
|
||||||
const DeclarationSet = std.StringHashMap(void);
|
const DeclarationSet = std.StringHashMap(void);
|
||||||
const EnumExtensionMap = std.StringHashMap(std.ArrayList(reg.Enum.Field));
|
const EnumExtensionMap = std.StringHashMap(std.ArrayList(reg.Enum.Field));
|
||||||
|
const FieldMap = std.StringHashMap(reg.Enum.Value);
|
||||||
|
|
||||||
allocator: *Allocator,
|
allocator: *Allocator,
|
||||||
reg_arena: *Allocator,
|
reg_arena: *Allocator,
|
||||||
registry: *reg.Registry,
|
registry: *reg.Registry,
|
||||||
declarations: DeclarationSet,
|
declarations: DeclarationSet,
|
||||||
enum_extensions: EnumExtensionMap,
|
enum_extensions: EnumExtensionMap,
|
||||||
|
field_map: FieldMap,
|
||||||
|
|
||||||
fn init(allocator: *Allocator, reg_arena: *Allocator, registry: *reg.Registry) DeclarationResolver {
|
fn init(allocator: *Allocator, reg_arena: *Allocator, registry: *reg.Registry) DeclarationResolver {
|
||||||
return .{
|
return .{
|
||||||
@@ -38,6 +40,7 @@ const DeclarationResolver = struct {
|
|||||||
.registry = registry,
|
.registry = registry,
|
||||||
.declarations = DeclarationSet.init(allocator),
|
.declarations = DeclarationSet.init(allocator),
|
||||||
.enum_extensions = EnumExtensionMap.init(allocator),
|
.enum_extensions = EnumExtensionMap.init(allocator),
|
||||||
|
.field_map = FieldMap.init(allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +50,7 @@ const DeclarationResolver = struct {
|
|||||||
kv.value.deinit();
|
kv.value.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.field_map.deinit();
|
||||||
self.enum_extensions.deinit();
|
self.enum_extensions.deinit();
|
||||||
self.declarations.deinit();
|
self.declarations.deinit();
|
||||||
}
|
}
|
||||||
@@ -78,22 +82,20 @@ const DeclarationResolver = struct {
|
|||||||
// If there are no extensions for this enum, assume its valid.
|
// If there are no extensions for this enum, assume its valid.
|
||||||
const extensions = self.enum_extensions.get(name) orelse return;
|
const extensions = self.enum_extensions.get(name) orelse return;
|
||||||
|
|
||||||
// Todo: cache this in DeclarationResolver
|
self.field_map.clear();
|
||||||
var field_map = std.StringHashMap(reg.Enum.Value).init(self.allocator);
|
|
||||||
defer field_map.deinit();
|
|
||||||
|
|
||||||
for (base_enum.fields) |field| {
|
for (base_enum.fields) |field| {
|
||||||
_ = try field_map.put(field.name, field.value);
|
_ = try self.field_map.put(field.name, field.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume that if a field name clobbers, the value is the same
|
// Assume that if a field name clobbers, the value is the same
|
||||||
for (extensions.value.items) |field| {
|
for (extensions.value.items) |field| {
|
||||||
_ = try field_map.put(field.name, field.value);
|
_ = try self.field_map.put(field.name, field.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const new_fields = try self.reg_arena.alloc(reg.Enum.Field, field_map.count());
|
const new_fields = try self.reg_arena.alloc(reg.Enum.Field, self.field_map.count());
|
||||||
|
|
||||||
var it = field_map.iterator();
|
var it = self.field_map.iterator();
|
||||||
for (new_fields) |*field| {
|
for (new_fields) |*field| {
|
||||||
const kv = it.next().?;
|
const kv = it.next().?;
|
||||||
field.* = .{
|
field.* = .{
|
||||||
|
|||||||
@@ -8,7 +8,28 @@ pub const Registry = struct {
|
|||||||
|
|
||||||
pub const Declaration = struct {
|
pub const Declaration = struct {
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
decl_type: TypeInfo,
|
decl_type: DeclarationType,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DeclarationType = union(enum) {
|
||||||
|
container: Container,
|
||||||
|
enumeration: Enum,
|
||||||
|
bitmask: Bitmask,
|
||||||
|
handle: Handle,
|
||||||
|
command: Command,
|
||||||
|
alias: Alias,
|
||||||
|
foreign: Foreign,
|
||||||
|
typedef: TypeInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Alias = struct {
|
||||||
|
pub const Target = enum {
|
||||||
|
other_command,
|
||||||
|
other_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
name: []const u8,
|
||||||
|
target: Target,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ApiConstant = struct {
|
pub const ApiConstant = struct {
|
||||||
@@ -27,16 +48,11 @@ pub const Tag = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const TypeInfo = union(enum) {
|
pub const TypeInfo = union(enum) {
|
||||||
container: Container,
|
name: []const u8,
|
||||||
enumeration: Enum,
|
command_ptr: Command,
|
||||||
bitmask: Bitmask,
|
|
||||||
handle: Handle,
|
|
||||||
command: Command,
|
|
||||||
alias: []const u8, // Alias of another declaration
|
|
||||||
pointer: Pointer,
|
pointer: Pointer,
|
||||||
array: Array,
|
array: Array,
|
||||||
opaque,
|
opaque,
|
||||||
foreign: Foreign
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Container = struct {
|
pub const Container = struct {
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ pub fn parseTypedef(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Decl
|
|||||||
|
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
.name = decl.name orelse return error.MissingTypeIdentifier,
|
.name = decl.name orelse return error.MissingTypeIdentifier,
|
||||||
.decl_type = decl.decl_type,
|
.decl_type = .{.typedef = decl.decl_type},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ pub fn parseParamOrProto(allocator: *Allocator, xctok: *XmlCTokenizer) !registry
|
|||||||
}
|
}
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
.name = decl.name orelse return error.MissingTypeIdentifier,
|
.name = decl.name orelse return error.MissingTypeIdentifier,
|
||||||
.decl_type = decl.decl_type,
|
.decl_type = .{.typedef = decl.decl_type},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +307,7 @@ fn parseDeclaration(allocator: *Allocator, xctok: *XmlCTokenizer) ParseError!Dec
|
|||||||
if (tok.id != .type_name and tok.id != .id) return error.InvalidSyntax;
|
if (tok.id != .type_name and tok.id != .id) return error.InvalidSyntax;
|
||||||
const type_name = tok.text;
|
const type_name = tok.text;
|
||||||
|
|
||||||
var type_info = TypeInfo{.alias = type_name};
|
var type_info = TypeInfo{.name = type_name};
|
||||||
|
|
||||||
// Parse pointers
|
// Parse pointers
|
||||||
type_info = try parsePointers(allocator, xctok, inner_is_const, type_info);
|
type_info = try parsePointers(allocator, xctok, inner_is_const, type_info);
|
||||||
@@ -366,32 +366,24 @@ fn parseFnPtrSuffix(allocator: *Allocator, xctok: *XmlCTokenizer, return_type: T
|
|||||||
_ = try xctok.expect(.rparen);
|
_ = try xctok.expect(.rparen);
|
||||||
_ = try xctok.expect(.lparen);
|
_ = try xctok.expect(.lparen);
|
||||||
|
|
||||||
const command = try allocator.create(registry.TypeInfo);
|
const return_type_heap = try allocator.create(TypeInfo);
|
||||||
command.* = .{
|
return_type_heap.* = return_type;
|
||||||
.command = .{
|
|
||||||
|
var command_ptr = Declaration{
|
||||||
|
.name = name.text,
|
||||||
|
.decl_type = .{
|
||||||
|
.command_ptr = .{
|
||||||
.params = &[_]registry.Command.Param{},
|
.params = &[_]registry.Command.Param{},
|
||||||
.return_type = try allocator.create(TypeInfo),
|
.return_type = return_type_heap,
|
||||||
.success_codes = &[_][]const u8{},
|
.success_codes = &[_][]const u8{},
|
||||||
.error_codes = &[_][]const u8{},
|
.error_codes = &[_][]const u8{},
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
command.command.return_type.* = return_type;
|
|
||||||
const command_ptr = Declaration{
|
|
||||||
.name = name.text,
|
|
||||||
.decl_type = .{
|
|
||||||
.pointer = .{
|
|
||||||
.is_const = true,
|
|
||||||
.is_optional = false,
|
|
||||||
.size = .one,
|
|
||||||
.child = command,
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const first_param = try parseDeclaration(allocator, xctok);
|
const first_param = try parseDeclaration(allocator, xctok);
|
||||||
if (first_param.name == null) {
|
if (first_param.name == null) {
|
||||||
if (first_param.decl_type != .alias or !mem.eql(u8, first_param.decl_type.alias, "void")) {
|
if (first_param.decl_type != .name or !mem.eql(u8, first_param.decl_type.name, "void")) {
|
||||||
return error.InvalidSyntax;
|
return error.InvalidSyntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +415,7 @@ fn parseFnPtrSuffix(allocator: *Allocator, xctok: *XmlCTokenizer, return_type: T
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ = try xctok.nextNoEof();
|
_ = try xctok.nextNoEof();
|
||||||
command.command.params = params.toOwnedSlice();
|
command_ptr.decl_type.command_ptr.params = params.toOwnedSlice();
|
||||||
return command_ptr;
|
return command_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ fn parseBitmaskType(ty: *xml.Element) !registry.Declaration {
|
|||||||
const alias = ty.getAttribute("alias") orelse return error.InvalidRegistry;
|
const alias = ty.getAttribute("alias") orelse return error.InvalidRegistry;
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
.name = name,
|
.name = name,
|
||||||
.decl_type = .{.alias = alias},
|
.decl_type = .{.alias = .{.name = alias, .target = .other_type}},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
@@ -119,7 +119,7 @@ fn parseHandleType(ty: *xml.Element) !registry.Declaration {
|
|||||||
const alias = ty.getAttribute("alias") orelse return error.InvalidRegistry;
|
const alias = ty.getAttribute("alias") orelse return error.InvalidRegistry;
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
.name = name,
|
.name = name,
|
||||||
.decl_type = .{.alias = alias},
|
.decl_type = .{.alias = .{.name = alias, .target = .other_type}},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const name = ty.getCharData("name") orelse return error.InvalidRegistry;
|
const name = ty.getCharData("name") orelse return error.InvalidRegistry;
|
||||||
@@ -151,7 +151,7 @@ fn parseBaseType(allocator: *Allocator, ty: *xml.Element) !registry.Declaration
|
|||||||
// macros, which is why this part is not built into the xml/c parser.
|
// macros, which is why this part is not built into the xml/c parser.
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
.name = name,
|
.name = name,
|
||||||
.decl_type = .{.opaque = {}},
|
.decl_type = .{.typedef = .{.opaque = {}}},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +162,7 @@ fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !regi
|
|||||||
if (ty.getAttribute("alias")) |alias| {
|
if (ty.getAttribute("alias")) |alias| {
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
.name = name,
|
.name = name,
|
||||||
.decl_type = .{.alias = alias},
|
.decl_type = .{.alias = .{.name = alias, .target = .other_type}},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ fn parseCommand(allocator: *Allocator, elem: *xml.Element) !registry.Declaration
|
|||||||
const name = elem.getAttribute("name") orelse return error.InvalidRegistry;
|
const name = elem.getAttribute("name") orelse return error.InvalidRegistry;
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
.name = name,
|
.name = name,
|
||||||
.decl_type = .{.alias = alias}
|
.decl_type = .{.alias = .{.name = alias, .target = .other_command}}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,13 +360,13 @@ fn parseCommand(allocator: *Allocator, elem: *xml.Element) !registry.Declaration
|
|||||||
while (it.next()) |param| {
|
while (it.next()) |param| {
|
||||||
var xctok = xmlc.XmlCTokenizer.init(param);
|
var xctok = xmlc.XmlCTokenizer.init(param);
|
||||||
const decl = try xmlc.parseParamOrProto(allocator, &xctok);
|
const decl = try xmlc.parseParamOrProto(allocator, &xctok);
|
||||||
params[i] = .{.name = decl.name, .param_type = decl.decl_type};
|
params[i] = .{.name = decl.name, .param_type = decl.decl_type.typedef};
|
||||||
try parsePointerMeta(¶ms[i].param_type, param);
|
try parsePointerMeta(¶ms[i].param_type, param);
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const return_type = try allocator.create(registry.TypeInfo);
|
const return_type = try allocator.create(registry.TypeInfo);
|
||||||
return_type.* = command_decl.decl_type;
|
return_type.* = command_decl.decl_type.typedef;
|
||||||
|
|
||||||
const success_codes = if (elem.getAttribute("successcodes")) |codes|
|
const success_codes = if (elem.getAttribute("successcodes")) |codes|
|
||||||
try splitCommaAlloc(allocator, codes)
|
try splitCommaAlloc(allocator, codes)
|
||||||
|
|||||||
Reference in New Issue
Block a user