Skip to content

Commit 618055d

Browse files
committed
c backend: use an explicit map of reserved idents
rather than unconditionally prepending double underscore to all identifiers. Also, use the prefix `zig_e_` instead of `__`. Also, avoid triggering this escaping when rendering an identifier and there has already been a prefix printed.
1 parent fbe5336 commit 618055d

File tree

1 file changed

+126
-10
lines changed

1 file changed

+126
-10
lines changed

src/codegen/c.zig

Lines changed: 126 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,129 @@ pub fn typeToCIdentifier(t: Type) std.fmt.Formatter(formatTypeAsCIdentifier) {
7272
return .{ .data = t };
7373
}
7474

75+
const reserved_idents = std.ComptimeStringMap(void, .{
76+
.{ "_Alignas", {
77+
@setEvalBranchQuota(4000);
78+
} },
79+
.{ "_Alignof", {} },
80+
.{ "_Atomic", {} },
81+
.{ "_Bool", {} },
82+
.{ "_Complex", {} },
83+
.{ "_Decimal128", {} },
84+
.{ "_Decimal32", {} },
85+
.{ "_Decimal64", {} },
86+
.{ "_Generic", {} },
87+
.{ "_Imaginary", {} },
88+
.{ "_Noreturn", {} },
89+
.{ "_Pragma", {} },
90+
.{ "_Static_assert", {} },
91+
.{ "_Thread_local", {} },
92+
.{ "alignas", {} },
93+
.{ "alignof", {} },
94+
.{ "asm", {} },
95+
.{ "atomic_bool", {} },
96+
.{ "atomic_char", {} },
97+
.{ "atomic_char16_t", {} },
98+
.{ "atomic_char32_t", {} },
99+
.{ "atomic_int", {} },
100+
.{ "atomic_int_fast16_t", {} },
101+
.{ "atomic_int_fast32_t", {} },
102+
.{ "atomic_int_fast64_t", {} },
103+
.{ "atomic_int_fast8_t", {} },
104+
.{ "atomic_int_least16_t", {} },
105+
.{ "atomic_int_least32_t", {} },
106+
.{ "atomic_int_least64_t", {} },
107+
.{ "atomic_int_least8_t", {} },
108+
.{ "atomic_intmax_t", {} },
109+
.{ "atomic_intptr_t", {} },
110+
.{ "atomic_llong", {} },
111+
.{ "atomic_long", {} },
112+
.{ "atomic_ptrdiff_t", {} },
113+
.{ "atomic_schar", {} },
114+
.{ "atomic_short", {} },
115+
.{ "atomic_size_t", {} },
116+
.{ "atomic_uchar", {} },
117+
.{ "atomic_uint", {} },
118+
.{ "atomic_uint_fast16_t", {} },
119+
.{ "atomic_uint_fast32_t", {} },
120+
.{ "atomic_uint_fast64_t", {} },
121+
.{ "atomic_uint_fast8_t", {} },
122+
.{ "atomic_uint_least16_t", {} },
123+
.{ "atomic_uint_least32_t", {} },
124+
.{ "atomic_uint_least64_t", {} },
125+
.{ "atomic_uint_least8_t", {} },
126+
.{ "atomic_uintmax_t", {} },
127+
.{ "atomic_uintptr_t", {} },
128+
.{ "atomic_ullong", {} },
129+
.{ "atomic_ulong", {} },
130+
.{ "atomic_ushort", {} },
131+
.{ "atomic_wchar_t", {} },
132+
.{ "auto", {} },
133+
.{ "bool", {} },
134+
.{ "break", {} },
135+
.{ "case", {} },
136+
.{ "char", {} },
137+
.{ "complex", {} },
138+
.{ "const", {} },
139+
.{ "continue", {} },
140+
.{ "default", {} },
141+
.{ "do", {} },
142+
.{ "double", {} },
143+
.{ "else", {} },
144+
.{ "enum", {} },
145+
.{ "extern ", {} },
146+
.{ "float", {} },
147+
.{ "for", {} },
148+
.{ "fortran", {} },
149+
.{ "goto", {} },
150+
.{ "if", {} },
151+
.{ "imaginary", {} },
152+
.{ "inline", {} },
153+
.{ "int", {} },
154+
.{ "int16_t", {} },
155+
.{ "int32_t", {} },
156+
.{ "int64_t", {} },
157+
.{ "int8_t", {} },
158+
.{ "intptr_t", {} },
159+
.{ "long", {} },
160+
.{ "noreturn", {} },
161+
.{ "register", {} },
162+
.{ "restrict", {} },
163+
.{ "return", {} },
164+
.{ "short ", {} },
165+
.{ "signed", {} },
166+
.{ "size_t", {} },
167+
.{ "sizeof", {} },
168+
.{ "ssize_t", {} },
169+
.{ "static", {} },
170+
.{ "static_assert", {} },
171+
.{ "struct", {} },
172+
.{ "switch", {} },
173+
.{ "thread_local", {} },
174+
.{ "typedef", {} },
175+
.{ "uint16_t", {} },
176+
.{ "uint32_t", {} },
177+
.{ "uint64_t", {} },
178+
.{ "uint8_t", {} },
179+
.{ "uintptr_t", {} },
180+
.{ "union", {} },
181+
.{ "unsigned", {} },
182+
.{ "void", {} },
183+
.{ "volatile", {} },
184+
.{ "while ", {} },
185+
});
186+
75187
fn formatIdent(
76188
ident: []const u8,
77189
comptime fmt: []const u8,
78190
options: std.fmt.FormatOptions,
79191
writer: anytype,
80192
) !void {
81-
_ = fmt;
82193
_ = options;
83-
try writer.writeAll("__"); // Add double underscore to avoid conflicting with C's reserved keywords
194+
const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident.
195+
if (solo and reserved_idents.has(ident)) {
196+
try writer.writeAll("zig_e_");
197+
}
84198
for (ident) |c, i| {
85199
switch (c) {
86200
'a'...'z', 'A'...'Z', '_' => try writer.writeByte(c),
@@ -612,7 +726,7 @@ pub const DeclGen = struct {
612726
const field_ty = ty.unionFields().values()[index].ty;
613727
const field_name = ty.unionFields().keys()[index];
614728
if (field_ty.hasRuntimeBits()) {
615-
try writer.print(".{} = ", .{fmtIdent(field_name)});
729+
try writer.print(".{ } = ", .{fmtIdent(field_name)});
616730
try dg.renderValue(writer, field_ty, union_obj.val);
617731
}
618732
if (ty.unionTagType()) |_| {
@@ -796,7 +910,7 @@ pub const DeclGen = struct {
796910
try buffer.appendSlice("} ");
797911

798912
const name_start = buffer.items.len;
799-
try buffer.writer().print("zig_S_{s};\n", .{fmtIdent(fqn)});
913+
try buffer.writer().print("zig_S_{};\n", .{fmtIdent(fqn)});
800914

801915
const rendered = buffer.toOwnedSlice();
802916
errdefer dg.typedefs.allocator.free(rendered);
@@ -852,7 +966,7 @@ pub const DeclGen = struct {
852966
}
853967

854968
const name_start = buffer.items.len;
855-
try buffer.writer().print("zig_U_{s};\n", .{fmtIdent(fqn)});
969+
try buffer.writer().print("zig_U_{};\n", .{fmtIdent(fqn)});
856970

857971
const rendered = buffer.toOwnedSlice();
858972
errdefer dg.typedefs.allocator.free(rendered);
@@ -1140,7 +1254,7 @@ pub const DeclGen = struct {
11401254
try w.writeByte('&');
11411255
return dg.renderDeclName(decl, w);
11421256
},
1143-
.identifier => |ident| return w.print("{}", .{fmtIdent(ident)}),
1257+
.identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}),
11441258
.bytes => |bytes| return w.writeAll(bytes),
11451259
}
11461260
}
@@ -1154,7 +1268,7 @@ pub const DeclGen = struct {
11541268
const gpa = dg.module.gpa;
11551269
const name = try decl.getFullyQualifiedName(gpa);
11561270
defer gpa.free(name);
1157-
return writer.print("{}", .{fmtIdent(name)});
1271+
return writer.print("{ }", .{fmtIdent(name)});
11581272
}
11591273
}
11601274
};
@@ -2785,12 +2899,14 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
27852899
const local = try f.allocLocal(inst_ty, .Const);
27862900
switch (struct_ptr) {
27872901
.local_ref => |i| {
2788-
try writer.print(" = {s}t{d}.{s}{};\n", .{ addrof, i, payload, fmtIdent(field_name) });
2902+
try writer.print(" = {s}t{d}.{s}{ };\n", .{
2903+
addrof, i, payload, fmtIdent(field_name),
2904+
});
27892905
},
27902906
else => {
27912907
try writer.print(" = {s}", .{addrof});
27922908
try f.writeCValue(writer, struct_ptr);
2793-
try writer.print("->{s}{};\n", .{ payload, fmtIdent(field_name) });
2909+
try writer.print("->{s}{ };\n", .{ payload, fmtIdent(field_name) });
27942910
},
27952911
}
27962912
return local;
@@ -2816,7 +2932,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
28162932
const local = try f.allocLocal(inst_ty, .Const);
28172933
try writer.writeAll(" = ");
28182934
try f.writeCValue(writer, struct_byval);
2819-
try writer.print(".{s}{};\n", .{ payload, fmtIdent(field_name) });
2935+
try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) });
28202936
return local;
28212937
}
28222938

0 commit comments

Comments
 (0)