Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.

Commit 0a146cc

Browse files
authored
Merge pull request #226 from ziglang/macro
Check that struct_identifier in macro is defined
2 parents a22b208 + 6f3f0e5 commit 0a146cc

File tree

9 files changed

+52
-12
lines changed

9 files changed

+52
-12
lines changed

build/Translator.zig

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,23 @@ pub fn addSystemFrameworkPath(t: *const Translator, path: Build.LazyPath) void {
200200
/// Exposes the embed path `path` to both translate-c and to `t.mod`.
201201
pub fn addEmbedPath(t: *const Translator, path: Build.LazyPath) void {
202202
t.mod.addEmbedPath(path);
203-
t.run.appendPrefixedFileArg("--embed-dir=", path);
203+
t.run.addPrefixedDirectoryArg("--embed-dir=", path);
204204
}
205205
/// Exposes the config header generaeted by `ch` to both translate-c and to `t.mod`.
206206
pub fn addConfigHeader(t: *const Translator, ch: *Build.Step.ConfigHeader) void {
207207
t.mod.addConfigHeader(ch);
208208
appendIncludeArg(t.run, "-I", ch.getOutputDir());
209209
}
210210

211+
/// If the value is omitted, it is set to 1.
212+
/// `name` and `value` need not live longer than the function call.
213+
pub fn defineCMacro(t: *const Translator, name: []const u8, value: ?[]const u8) void {
214+
const b = t.mod.owner;
215+
const macro = b.fmt("-D{s}={s}", .{ name, value orelse "1" });
216+
t.mod.c_macros.append(b.allocator, macro) catch @panic("OOM");
217+
t.run.addArg(macro);
218+
}
219+
211220
/// Helper function for adding things like `-I /path/to/include/dir` to arg vectors.
212221
fn appendIncludeArg(run: *Build.Step.Run, arg: []const u8, path: Build.LazyPath) void {
213222
run.addArg(arg);

examples/compile_c/build.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn build(b: *std.Build) !void {
1616
.target = target,
1717
.optimize = optimize,
1818
});
19-
trans.run.addArg("-D__TRANSLATE_C__");
19+
trans.defineCMacro("__TRANSLATE_C__", null);
2020
// Build an executable from `trans.mod` (the Zig module containing the translated code).
2121
const translated_exe = b.addExecutable(.{
2222
.name = "translated-exe",

src/MacroTranslator.zig

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ pub fn transFnMacro(mt: *MacroTranslator) ParseError!void {
7979
try block_scope.discardVariable(mangled_name);
8080
}
8181

82+
// #define FOO(x)
83+
if (mt.peek() == .eof) {
84+
try block_scope.statements.append(mt.t.gpa, ZigTag.return_void.init());
85+
86+
const fn_decl = try ZigTag.pub_inline_fn.create(mt.t.arena, .{
87+
.name = mt.name,
88+
.params = fn_params,
89+
.return_type = ZigTag.void_type.init(),
90+
.body = try block_scope.complete(),
91+
});
92+
try mt.t.addTopLevelDecl(mt.name, fn_decl);
93+
return;
94+
}
95+
8296
const expr = try mt.parseCExpr(scope);
8397
const last = mt.peek();
8498
if (last != .eof)
@@ -252,7 +266,7 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
252266
const lit_bytes = mt.tokSlice();
253267
mt.i += 1;
254268

255-
var bytes = try std.ArrayListUnmanaged(u8).initCapacity(arena, lit_bytes.len + 3);
269+
var bytes = try std.ArrayList(u8).initCapacity(arena, lit_bytes.len + 3);
256270

257271
const prefix = aro.Tree.Token.NumberPrefix.fromString(lit_bytes);
258272
switch (prefix) {
@@ -974,7 +988,12 @@ fn parseCSpecifierQualifierList(mt: *MacroTranslator, scope: *Scope) ParseError!
974988
try mt.expect(.identifier);
975989

976990
const name = try std.fmt.allocPrint(mt.t.arena, "{s}_{s}", .{ tag_name, identifier });
977-
return try ZigTag.identifier.create(mt.t.arena, name);
991+
if (!mt.t.global_scope.contains(name)) {
992+
try mt.fail("unable to translate C expr: '{s}' not found", .{name});
993+
return error.ParseError;
994+
}
995+
996+
return try ZigTag.identifier.create(mt.t.arena, try mt.t.arena.dupe(u8, name));
978997
},
979998
else => {},
980999
}

src/Scope.zig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ const Translator = @import("Translator.zig");
88
const Scope = @This();
99

1010
pub const SymbolTable = std.StringArrayHashMapUnmanaged(ast.Node);
11-
pub const AliasList = std.ArrayListUnmanaged(struct {
11+
pub const AliasList = std.ArrayList(struct {
1212
alias: []const u8,
1313
name: []const u8,
1414
});
1515

1616
/// Associates a container (structure or union) with its relevant member functions.
1717
pub const ContainerMemberFns = struct {
1818
container_decl_ptr: *ast.Node,
19-
member_fns: std.ArrayListUnmanaged(*ast.Payload.Func) = .empty,
19+
member_fns: std.ArrayList(*ast.Payload.Func) = .empty,
2020
};
2121
pub const ContainerMemberFnsHashMap = std.AutoArrayHashMapUnmanaged(aro.QualType, ContainerMemberFns);
2222

@@ -55,7 +55,7 @@ pub const Condition = struct {
5555
pub const Block = struct {
5656
base: Scope,
5757
translator: *Translator,
58-
statements: std.ArrayListUnmanaged(ast.Node),
58+
statements: std.ArrayList(ast.Node),
5959
variables: AliasList,
6060
mangle_count: u32 = 0,
6161
label: ?[]const u8 = null,
@@ -195,7 +195,7 @@ pub const Root = struct {
195195
translator: *Translator,
196196
sym_table: SymbolTable,
197197
blank_macros: std.StringArrayHashMapUnmanaged(void),
198-
nodes: std.ArrayListUnmanaged(ast.Node),
198+
nodes: std.ArrayList(ast.Node),
199199
container_member_fns_map: ContainerMemberFnsHashMap,
200200

201201
pub fn init(t: *Translator) Root {
@@ -300,7 +300,7 @@ pub const Root = struct {
300300
for (members.member_fns.items) |func| {
301301
const func_name = func.data.name.?;
302302
const func_name_trimmed = std.mem.trimEnd(u8, func_name, "_");
303-
const last_idx = std.mem.lastIndexOf(u8, func_name_trimmed, "_") orelse continue;
303+
const last_idx = std.mem.findLast(u8, func_name_trimmed, "_") orelse continue;
304304
const func_name_alias = func_name[last_idx + 1 ..];
305305
const member_name_slot = try member_names.getOrPutValue(gpa, func_name_alias, {});
306306
if (member_name_slot.found_existing) continue;

src/Translator.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3583,7 +3583,7 @@ fn transArrayInit(
35833583
const array_item_qt = array_init.container_qt.childType(t.comp);
35843584
const array_item_type = try t.transType(scope, array_item_qt, array_init.l_brace_tok);
35853585
var maybe_lhs: ?ZigNode = null;
3586-
var val_list: std.ArrayListUnmanaged(ZigNode) = .empty;
3586+
var val_list: std.ArrayList(ZigNode) = .empty;
35873587
defer val_list.deinit(t.gpa);
35883588
var i: usize = 0;
35893589
while (i < array_init.items.len) {

src/ast.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ const Context = struct {
879879
gpa: Allocator,
880880
buf: std.ArrayList(u8) = .empty,
881881
nodes: std.zig.Ast.NodeList = .empty,
882-
extra_data: std.ArrayListUnmanaged(u32) = .empty,
882+
extra_data: std.ArrayList(u32) = .empty,
883883
tokens: std.zig.Ast.TokenList = .empty,
884884

885885
fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {

src/main.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
123123
break :args args[0..i];
124124
};
125125
const user_macros = macros: {
126-
var macro_buf: std.ArrayListUnmanaged(u8) = .empty;
126+
var macro_buf: std.ArrayList(u8) = .empty;
127127
defer macro_buf.deinit(gpa);
128128

129129
var discard_buf: [256]u8 = undefined;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#define FOO
2+
#define BAR(x)
23

34
// translate
45
//
56
// pub const FOO = "";
7+
//
8+
// pub inline fn BAR(x: anytype) void {
9+
// _ = &x;
10+
// return;
11+
// }
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#define FOO(x) x
2+
#define BAR(x) struct FOO(x)
3+
4+
// translate
5+
//
6+
// pub const BAR = @compileError("unable to translate C expr: 'struct_FOO' not found");

0 commit comments

Comments
 (0)