Skip to content

Commit

Permalink
Merge pull request #24 from Srekel/srekel-function-typedef
Browse files Browse the repository at this point in the history
Added support for function typedefs.
  • Loading branch information
lassade authored Jan 3, 2024
2 parents e3d700d + 408318c commit 96577e8
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 6 deletions.
51 changes: 45 additions & 6 deletions src/Transpiler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1594,13 +1594,10 @@ fn visitTypedefDecl(self: *Self, value: *const json.Value) !void {
self.nodes_visited += 1;

const name = value.object.get("name").?.string;
const v_inner_opt = value.object.getPtr("inner");
try self.writeDocs(v_inner_opt);

if (value.object.get("inner")) |v_inner| {
if (v_inner.array.items.len != 1) {
log.err("complex typedef `{s}`", .{name});
return;
}

if (v_inner_opt) |v_inner| {
const v_item = &v_inner.array.items[0];
const tag = v_item.object.get("kind").?.string;
if (mem.eql(u8, tag, "BuiltinType") or mem.eql(u8, tag, "TypedefType")) {
Expand Down Expand Up @@ -1652,6 +1649,16 @@ fn visitTypedefDecl(self: *Self, value: *const json.Value) !void {
self.nodes_visited += 1;
try self.out.print("pub const {s} = {s};\n\n", .{ name, typeQualifier(v_item).? });
return;
} else if (mem.eql(u8, tag, "ParenType")) {
self.nodes_visited += 1;
const parentype_inner_opt = v_inner.array.items[0].object.getPtr("inner");
if (parentype_inner_opt) |parentype_inner| {
const parentype_inner_kind = parentype_inner.array.items[0].object.get("kind").?.string;
if (mem.eql(u8, parentype_inner_kind, "FunctionProtoType")) {
try self.visitFunctionProtoType(name, &parentype_inner.array.items[0]);
}
}
return;
} else {
log.err("unhandled `{s}` in typedef `{s}`", .{ tag, name });
return;
Expand All @@ -1664,6 +1671,38 @@ fn visitTypedefDecl(self: *Self, value: *const json.Value) !void {
}
}

fn visitFunctionProtoType(self: *Self, name: []const u8, value: *const json.Value) !void {
self.nodes_visited += 1;

try self.out.print("pub const {s} = fn(", .{name});

var return_type_opt: ?*const json.Value = null;
const inner_opt = value.object.getPtr("inner");
if (inner_opt) |inner| {
for (inner.array.items, 0..) |*item, i| {
if (return_type_opt == null) {
return_type_opt = item;
continue;
}

const zig_type = try self.transpileType(typeQualifier(item).?);
defer self.allocator.free(zig_type);
try self.out.print("{s}", .{zig_type});
if (i + 1 < inner.array.items.len) {
try self.out.print(", ", .{});
}
}
}

if (return_type_opt) |return_type| {
const zig_type = try self.transpileType(typeQualifier(return_type).?);
defer self.allocator.free(zig_type);
try self.out.print(") callconv(.C) {s};\n\n", .{zig_type});
} else {
try self.out.print(") callconv(.C) {s};\n\n", .{"void"});
}
}

fn visitNamespaceDecl(self: *Self, value: *const json.Value) !void {
if (self.shouldSkip(value)) {
self.nodes_visited += nodeCount(value);
Expand Down
1 change: 1 addition & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub fn main() !void {
try clang.append("-Xclang");
try clang.append("-ast-dump=json");
try clang.append("-fsyntax-only");
try clang.append("-fparse-all-comments");

const argv = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, argv);
Expand Down

0 comments on commit 96577e8

Please sign in to comment.