parse pointers in function pointer declarations always as optional

This commit is contained in:
Robin Voetter
2021-12-17 20:13:19 +01:00
parent c169871f96
commit 7c2d1d466b
2 changed files with 19 additions and 19 deletions

View File

@@ -241,9 +241,9 @@ pub const XmlCTokenizer = struct {
}; };
// TYPEDEF = kw_typedef DECLARATION ';' // TYPEDEF = kw_typedef DECLARATION ';'
pub fn parseTypedef(allocator: Allocator, xctok: *XmlCTokenizer) !registry.Declaration { pub fn parseTypedef(allocator: Allocator, xctok: *XmlCTokenizer, ptrs_optional: bool) !registry.Declaration {
_ = try xctok.expect(.kw_typedef); _ = try xctok.expect(.kw_typedef);
const decl = try parseDeclaration(allocator, xctok); const decl = try parseDeclaration(allocator, xctok, ptrs_optional);
_ = try xctok.expect(.semicolon); _ = try xctok.expect(.semicolon);
if (try xctok.peek()) |_| { if (try xctok.peek()) |_| {
return error.InvalidSyntax; return error.InvalidSyntax;
@@ -256,8 +256,8 @@ pub fn parseTypedef(allocator: Allocator, xctok: *XmlCTokenizer) !registry.Decla
} }
// MEMBER = DECLARATION (':' int)? // MEMBER = DECLARATION (':' int)?
pub fn parseMember(allocator: Allocator, xctok: *XmlCTokenizer) !registry.Container.Field { pub fn parseMember(allocator: Allocator, xctok: *XmlCTokenizer, ptrs_optional: bool) !registry.Container.Field {
const decl = try parseDeclaration(allocator, xctok); const decl = try parseDeclaration(allocator, xctok, ptrs_optional);
var field = registry.Container.Field{ var field = registry.Container.Field{
.name = decl.name orelse return error.MissingTypeIdentifier, .name = decl.name orelse return error.MissingTypeIdentifier,
.field_type = decl.decl_type, .field_type = decl.decl_type,
@@ -284,8 +284,8 @@ pub fn parseMember(allocator: Allocator, xctok: *XmlCTokenizer) !registry.Contai
return field; return field;
} }
pub fn parseParamOrProto(allocator: Allocator, xctok: *XmlCTokenizer) !registry.Declaration { pub fn parseParamOrProto(allocator: Allocator, xctok: *XmlCTokenizer, ptrs_optional: bool) !registry.Declaration {
const decl = try parseDeclaration(allocator, xctok); const decl = try parseDeclaration(allocator, xctok, ptrs_optional);
if (try xctok.peek()) |_| { if (try xctok.peek()) |_| {
return error.InvalidSyntax; return error.InvalidSyntax;
} }
@@ -315,7 +315,7 @@ pub const ParseError = error{
// DECLARATION = kw_const? type_name DECLARATOR // DECLARATION = kw_const? type_name DECLARATOR
// DECLARATOR = POINTERS (id | name)? ('[' ARRAY_DECLARATOR ']')* // DECLARATOR = POINTERS (id | name)? ('[' ARRAY_DECLARATOR ']')*
// | POINTERS '(' FNPTRSUFFIX // | POINTERS '(' FNPTRSUFFIX
fn parseDeclaration(allocator: Allocator, xctok: *XmlCTokenizer) ParseError!Declaration { fn parseDeclaration(allocator: Allocator, xctok: *XmlCTokenizer, ptrs_optional: bool) ParseError!Declaration {
// Parse declaration constness // Parse declaration constness
var tok = try xctok.nextNoEof(); var tok = try xctok.nextNoEof();
const inner_is_const = tok.kind == .kw_const; const inner_is_const = tok.kind == .kw_const;
@@ -333,11 +333,11 @@ fn parseDeclaration(allocator: Allocator, xctok: *XmlCTokenizer) ParseError!Decl
var type_info = TypeInfo{ .name = 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, ptrs_optional);
// Parse name / fn ptr // Parse name / fn ptr
if (try parseFnPtrSuffix(allocator, xctok, type_info)) |decl| { if (try parseFnPtrSuffix(allocator, xctok, type_info, ptrs_optional)) |decl| {
return decl; return decl;
} }
@@ -377,7 +377,7 @@ fn parseDeclaration(allocator: Allocator, xctok: *XmlCTokenizer) ParseError!Decl
} }
// FNPTRSUFFIX = kw_vkapi_ptr '*' name' ')' '(' ('void' | (DECLARATION (',' DECLARATION)*)?) ')' // FNPTRSUFFIX = kw_vkapi_ptr '*' name' ')' '(' ('void' | (DECLARATION (',' DECLARATION)*)?) ')'
fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: TypeInfo) !?Declaration { fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: TypeInfo, ptrs_optional: bool) !?Declaration {
const lparen = try xctok.peek(); const lparen = try xctok.peek();
if (lparen == null or lparen.?.kind != .lparen) { if (lparen == null or lparen.?.kind != .lparen) {
return null; return null;
@@ -404,7 +404,7 @@ fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: Ty
}, },
}; };
const first_param = try parseDeclaration(allocator, xctok); const first_param = try parseDeclaration(allocator, xctok, ptrs_optional);
if (first_param.name == null) { if (first_param.name == null) {
if (first_param.decl_type != .name or !mem.eql(u8, first_param.decl_type.name, "void")) { if (first_param.decl_type != .name or !mem.eql(u8, first_param.decl_type.name, "void")) {
return error.InvalidSyntax; return error.InvalidSyntax;
@@ -431,7 +431,7 @@ fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: Ty
else => return error.InvalidSyntax, else => return error.InvalidSyntax,
} }
const decl = try parseDeclaration(allocator, xctok); const decl = try parseDeclaration(allocator, xctok, ptrs_optional);
try params.append(.{ try params.append(.{
.name = decl.name orelse return error.MissingTypeIdentifier, .name = decl.name orelse return error.MissingTypeIdentifier,
.param_type = decl.decl_type, .param_type = decl.decl_type,
@@ -445,7 +445,7 @@ fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: Ty
} }
// POINTERS = (kw_const? '*')* // POINTERS = (kw_const? '*')*
fn parsePointers(allocator: Allocator, xctok: *XmlCTokenizer, inner_const: bool, inner: TypeInfo) !TypeInfo { fn parsePointers(allocator: Allocator, xctok: *XmlCTokenizer, inner_const: bool, inner: TypeInfo, ptrs_optional: bool) !TypeInfo {
var type_info = inner; var type_info = inner;
var first_const = inner_const; var first_const = inner_const;
@@ -474,7 +474,7 @@ fn parsePointers(allocator: Allocator, xctok: *XmlCTokenizer, inner_const: bool,
type_info = .{ type_info = .{
.pointer = .{ .pointer = .{
.is_const = is_const or first_const, .is_const = is_const or first_const,
.is_optional = false, // set elsewhere .is_optional = ptrs_optional, // set elsewhere
.size = .one, // set elsewhere .size = .one, // set elsewhere
.child = child, .child = child,
}, },

View File

@@ -163,7 +163,7 @@ fn parseBaseType(allocator: Allocator, ty: *xml.Element) !registry.Declaration {
const name = ty.getCharData("name") orelse return error.InvalidRegistry; const name = ty.getCharData("name") orelse return error.InvalidRegistry;
if (ty.getCharData("type")) |_| { if (ty.getCharData("type")) |_| {
var tok = cparse.XmlCTokenizer.init(ty); var tok = cparse.XmlCTokenizer.init(ty);
return try cparse.parseTypedef(allocator, &tok); return try cparse.parseTypedef(allocator, &tok, false);
} else { } else {
// Either ANativeWindow, AHardwareBuffer or CAMetalLayer. The latter has a lot of // Either ANativeWindow, AHardwareBuffer or CAMetalLayer. The latter has a lot of
// 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.
@@ -193,7 +193,7 @@ fn parseContainer(allocator: Allocator, ty: *xml.Element, is_union: bool) !regis
var maybe_stype: ?[]const u8 = null; var maybe_stype: ?[]const u8 = null;
while (it.next()) |member| { while (it.next()) |member| {
var xctok = cparse.XmlCTokenizer.init(member); var xctok = cparse.XmlCTokenizer.init(member);
members[i] = try cparse.parseMember(allocator, &xctok); members[i] = try cparse.parseMember(allocator, &xctok, false);
if (mem.eql(u8, members[i].name, "sType")) { if (mem.eql(u8, members[i].name, "sType")) {
if (member.getAttribute("values")) |stype| { if (member.getAttribute("values")) |stype| {
maybe_stype = stype; maybe_stype = stype;
@@ -238,7 +238,7 @@ fn parseContainer(allocator: Allocator, ty: *xml.Element, is_union: bool) !regis
fn parseFuncPointer(allocator: Allocator, ty: *xml.Element) !registry.Declaration { fn parseFuncPointer(allocator: Allocator, ty: *xml.Element) !registry.Declaration {
var xctok = cparse.XmlCTokenizer.init(ty); var xctok = cparse.XmlCTokenizer.init(ty);
return try cparse.parseTypedef(allocator, &xctok); return try cparse.parseTypedef(allocator, &xctok, true);
} }
// For some reason, the DeclarationType cannot be passed to lenToPointerSize, as // For some reason, the DeclarationType cannot be passed to lenToPointerSize, as
@@ -449,7 +449,7 @@ fn parseCommand(allocator: Allocator, elem: *xml.Element) !registry.Declaration
const proto = elem.findChildByTag("proto") orelse return error.InvalidRegistry; const proto = elem.findChildByTag("proto") orelse return error.InvalidRegistry;
var proto_xctok = cparse.XmlCTokenizer.init(proto); var proto_xctok = cparse.XmlCTokenizer.init(proto);
const command_decl = try cparse.parseParamOrProto(allocator, &proto_xctok); const command_decl = try cparse.parseParamOrProto(allocator, &proto_xctok, false);
var params = try allocator.alloc(registry.Command.Param, elem.children.items.len); var params = try allocator.alloc(registry.Command.Param, elem.children.items.len);
@@ -457,7 +457,7 @@ fn parseCommand(allocator: Allocator, elem: *xml.Element) !registry.Declaration
var it = elem.findChildrenByTag("param"); var it = elem.findChildrenByTag("param");
while (it.next()) |param| { while (it.next()) |param| {
var xctok = cparse.XmlCTokenizer.init(param); var xctok = cparse.XmlCTokenizer.init(param);
const decl = try cparse.parseParamOrProto(allocator, &xctok); const decl = try cparse.parseParamOrProto(allocator, &xctok, false);
params[i] = .{ params[i] = .{
.name = decl.name, .name = decl.name,
.param_type = decl.decl_type.typedef, .param_type = decl.decl_type.typedef,