authorgravatar for iodizon@163.comHydroH <iodizon@163.com> 2024-03-26 23:24:47+08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-26 21:16:53-07:00
log7684423c0846acb553d8287d0edc8fe6b1f8ca57
tree7f5ce6ebd190958bc07eaf032dff0117bb323845
parent5140f2726ae6e09381d9d44a72626dfe319f068b

translate-c: handle string concatenation of function calls


2 files changed, 42 insertions(+), 31 deletions(-)

src/translate_c.zig+31-31
...@@ -5724,7 +5724,7 @@ fn escapeUnprintables(ctx: *Context, m: *MacroCtx) ![]const u8 {...@@ -5724,7 +5724,7 @@ fn escapeUnprintables(ctx: *Context, m: *MacroCtx) ![]const u8 {
5724 };5724 };
5725}5725}
57265726
5727fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {5727fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
5728 const tok = m.next().?;5728 const tok = m.next().?;
5729 const slice = m.slice();5729 const slice = m.slice();
5730 switch (tok) {5730 switch (tok) {
...@@ -5754,7 +5754,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N...@@ -5754,7 +5754,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
5754 },5754 },
5755 .identifier, .extended_identifier => {5755 .identifier, .extended_identifier => {
5756 if (c.global_scope.blank_macros.contains(slice)) {5756 if (c.global_scope.blank_macros.contains(slice)) {
5757 return parseCPrimaryExprInner(c, m, scope);5757 return parseCPrimaryExpr(c, m, scope);
5758 }5758 }
5759 const mangled_name = scope.getAlias(slice);5759 const mangled_name = scope.getAlias(slice);
5760 if (builtin_typedef_map.get(mangled_name)) |ty| return Tag.type.create(c.arena, ty);5760 if (builtin_typedef_map.get(mangled_name)) |ty| return Tag.type.create(c.arena, ty);
...@@ -5781,35 +5781,6 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N...@@ -5781,35 +5781,6 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
5781 }5781 }
5782}5782}
57835783
5784fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
5785 var node = try parseCPrimaryExprInner(c, m, scope);
5786 // In C the preprocessor would handle concatting strings while expanding macros.
5787 // This should do approximately the same by concatting any strings and identifiers
5788 // after a primary expression.
5789 while (true) {
5790 switch (m.peek().?) {
5791 .string_literal,
5792 .string_literal_utf_16,
5793 .string_literal_utf_8,
5794 .string_literal_utf_32,
5795 .string_literal_wide,
5796 => {},
5797 .identifier, .extended_identifier => {
5798 const tok = m.list[m.i + 1];
5799 const slice = m.source[tok.start..tok.end];
5800 if (c.global_scope.blank_macros.contains(slice)) {
5801 m.i += 1;
5802 continue;
5803 }
5804 },
5805 else => break,
5806 }
5807 const rhs = try parseCPrimaryExprInner(c, m, scope);
5808 node = try Tag.array_cat.create(c.arena, .{ .lhs = node, .rhs = rhs });
5809 }
5810 return node;
5811}
5812
5813fn macroIntFromBool(c: *Context, node: Node) !Node {5784fn macroIntFromBool(c: *Context, node: Node) !Node {
5814 if (!isBoolRes(node)) {5785 if (!isBoolRes(node)) {
5815 return node;5786 return node;
...@@ -6241,6 +6212,35 @@ fn parseCAbstractDeclarator(c: *Context, m: *MacroCtx, node: Node) ParseError!No...@@ -6241,6 +6212,35 @@ fn parseCAbstractDeclarator(c: *Context, m: *MacroCtx, node: Node) ParseError!No
6241}6212}
62426213
6243fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) ParseError!Node {6214fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) ParseError!Node {
6215 var node = try parseCPostfixExprInner(c, m, scope, type_name);
6216 // In C the preprocessor would handle concatting strings while expanding macros.
6217 // This should do approximately the same by concatting any strings and identifiers
6218 // after a primary or postfix expression.
6219 while (true) {
6220 switch (m.peek().?) {
6221 .string_literal,
6222 .string_literal_utf_16,
6223 .string_literal_utf_8,
6224 .string_literal_utf_32,
6225 .string_literal_wide,
6226 => {},
6227 .identifier, .extended_identifier => {
6228 const tok = m.list[m.i + 1];
6229 const slice = m.source[tok.start..tok.end];
6230 if (c.global_scope.blank_macros.contains(slice)) {
6231 m.i += 1;
6232 continue;
6233 }
6234 },
6235 else => break,
6236 }
6237 const rhs = try parseCPostfixExprInner(c, m, scope, type_name);
6238 node = try Tag.array_cat.create(c.arena, .{ .lhs = node, .rhs = rhs });
6239 }
6240 return node;
6241}
6242
6243fn parseCPostfixExprInner(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) ParseError!Node {
6244 var node = type_name orelse try parseCPrimaryExpr(c, m, scope);6244 var node = type_name orelse try parseCPrimaryExpr(c, m, scope);
6245 while (true) {6245 while (true) {
6246 switch (m.next().?) {6246 switch (m.next().?) {
test/cases/translate_c/macro_function_string_concat.c created+11
...@@ -0,0 +1,11 @@
1#define bar() ""
2#define FOO bar() "," bar()
3
4// translate-c
5// target=x86_64-linux
6// c_frontend=clang
7//
8// pub inline fn bar() @TypeOf("") {
9// return "";
10// }
11// pub const FOO = bar() ++ "," ++ bar();