Commit 7684423c08
Changed files (2)
test
cases
translate_c
src/translate_c.zig
@@ -5724,7 +5724,7 @@ fn escapeUnprintables(ctx: *Context, m: *MacroCtx) ![]const u8 {
};
}
-fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
+fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
const tok = m.next().?;
const slice = m.slice();
switch (tok) {
@@ -5754,7 +5754,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
},
.identifier, .extended_identifier => {
if (c.global_scope.blank_macros.contains(slice)) {
- return parseCPrimaryExprInner(c, m, scope);
+ return parseCPrimaryExpr(c, m, scope);
}
const mangled_name = scope.getAlias(slice);
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
}
}
-fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
- var node = try parseCPrimaryExprInner(c, m, scope);
- // In C the preprocessor would handle concatting strings while expanding macros.
- // This should do approximately the same by concatting any strings and identifiers
- // after a primary expression.
- while (true) {
- switch (m.peek().?) {
- .string_literal,
- .string_literal_utf_16,
- .string_literal_utf_8,
- .string_literal_utf_32,
- .string_literal_wide,
- => {},
- .identifier, .extended_identifier => {
- const tok = m.list[m.i + 1];
- const slice = m.source[tok.start..tok.end];
- if (c.global_scope.blank_macros.contains(slice)) {
- m.i += 1;
- continue;
- }
- },
- else => break,
- }
- const rhs = try parseCPrimaryExprInner(c, m, scope);
- node = try Tag.array_cat.create(c.arena, .{ .lhs = node, .rhs = rhs });
- }
- return node;
-}
-
fn macroIntFromBool(c: *Context, node: Node) !Node {
if (!isBoolRes(node)) {
return node;
@@ -6241,6 +6212,35 @@ fn parseCAbstractDeclarator(c: *Context, m: *MacroCtx, node: Node) ParseError!No
}
fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) ParseError!Node {
+ var node = try parseCPostfixExprInner(c, m, scope, type_name);
+ // In C the preprocessor would handle concatting strings while expanding macros.
+ // This should do approximately the same by concatting any strings and identifiers
+ // after a primary or postfix expression.
+ while (true) {
+ switch (m.peek().?) {
+ .string_literal,
+ .string_literal_utf_16,
+ .string_literal_utf_8,
+ .string_literal_utf_32,
+ .string_literal_wide,
+ => {},
+ .identifier, .extended_identifier => {
+ const tok = m.list[m.i + 1];
+ const slice = m.source[tok.start..tok.end];
+ if (c.global_scope.blank_macros.contains(slice)) {
+ m.i += 1;
+ continue;
+ }
+ },
+ else => break,
+ }
+ const rhs = try parseCPostfixExprInner(c, m, scope, type_name);
+ node = try Tag.array_cat.create(c.arena, .{ .lhs = node, .rhs = rhs });
+ }
+ return node;
+}
+
+fn parseCPostfixExprInner(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) ParseError!Node {
var node = type_name orelse try parseCPrimaryExpr(c, m, scope);
while (true) {
switch (m.next().?) {
test/cases/translate_c/macro_function_string_concat.c
@@ -0,0 +1,11 @@
+#define bar() ""
+#define FOO bar() "," bar()
+
+// translate-c
+// target=x86_64-linux
+// c_frontend=clang
+//
+// pub inline fn bar() @TypeOf("") {
+// return "";
+// }
+// pub const FOO = bar() ++ "," ++ bar();