| ... | @@ -139,7 +139,7 @@ pub fn translate( | ... | @@ -139,7 +139,7 @@ pub fn translate( |
| 139 | // For memory that has the same lifetime as the Ast that we return | 139 | // For memory that has the same lifetime as the Ast that we return |
| 140 | // from this function. | 140 | // from this function. |
| 141 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); | 141 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); |
| 142 | errdefer arena_allocator.deinit(); | 142 | defer arena_allocator.deinit(); |
| 143 | const arena = arena_allocator.allocator(); | 143 | const arena = arena_allocator.allocator(); |
| 144 | | 144 | |
| 145 | var context = Context{ | 145 | var context = Context{ |
| ... | @@ -5497,6 +5497,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void { | ... | @@ -5497,6 +5497,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void { |
| 5497 | const str_node = try Tag.string_literal.create(c.arena, "\"\""); | 5497 | const str_node = try Tag.string_literal.create(c.arena, "\"\""); |
| 5498 | const var_decl = try Tag.pub_var_simple.create(c.arena, .{ .name = name, .init = str_node }); | 5498 | const var_decl = try Tag.pub_var_simple.create(c.arena, .{ .name = name, .init = str_node }); |
| 5499 | try c.global_scope.macro_table.put(name, var_decl); | 5499 | try c.global_scope.macro_table.put(name, var_decl); |
| | 5500 | try c.global_scope.blank_macros.put(name, {}); |
| 5500 | continue; | 5501 | continue; |
| 5501 | }, | 5502 | }, |
| 5502 | .LParen => { | 5503 | .LParen => { |
| ... | @@ -5527,6 +5528,29 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -5527,6 +5528,29 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5527 | .invalid_arg_usage => unreachable, // no args | 5528 | .invalid_arg_usage => unreachable, // no args |
| 5528 | }; | 5529 | }; |
| 5529 | | 5530 | |
| | 5531 | // Check if the macro only uses other blank macros. |
| | 5532 | while (true) { |
| | 5533 | switch (m.peek().?) { |
| | 5534 | .Identifier => { |
| | 5535 | const tok = m.list[m.i + 1]; |
| | 5536 | const slice = m.source[tok.start..tok.end]; |
| | 5537 | if (c.global_scope.blank_macros.contains(slice)) { |
| | 5538 | m.i += 1; |
| | 5539 | continue; |
| | 5540 | } |
| | 5541 | }, |
| | 5542 | .Eof, .Nl => { |
| | 5543 | try c.global_scope.blank_macros.put(m.name, {}); |
| | 5544 | const init_node = try Tag.string_literal.create(c.arena, "\"\""); |
| | 5545 | const var_decl = try Tag.pub_var_simple.create(c.arena, .{ .name = m.name, .init = init_node }); |
| | 5546 | try c.global_scope.macro_table.put(m.name, var_decl); |
| | 5547 | return; |
| | 5548 | }, |
| | 5549 | else => {}, |
| | 5550 | } |
| | 5551 | break; |
| | 5552 | } |
| | 5553 | |
| 5530 | const init_node = try parseCExpr(c, m, scope); | 5554 | const init_node = try parseCExpr(c, m, scope); |
| 5531 | const last = m.next().?; | 5555 | const last = m.next().?; |
| 5532 | if (last != .Eof and last != .Nl) | 5556 | if (last != .Eof and last != .Nl) |
| ... | @@ -5960,6 +5984,9 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N | ... | @@ -5960,6 +5984,9 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N |
| 5960 | return parseCNumLit(c, m); | 5984 | return parseCNumLit(c, m); |
| 5961 | }, | 5985 | }, |
| 5962 | .Identifier => { | 5986 | .Identifier => { |
| | 5987 | if (c.global_scope.blank_macros.contains(slice)) { |
| | 5988 | return parseCPrimaryExprInner(c, m, scope); |
| | 5989 | } |
| 5963 | const mangled_name = scope.getAlias(slice); | 5990 | const mangled_name = scope.getAlias(slice); |
| 5964 | if (builtin_typedef_map.get(mangled_name)) |ty| return Tag.type.create(c.arena, ty); | 5991 | if (builtin_typedef_map.get(mangled_name)) |ty| return Tag.type.create(c.arena, ty); |
| 5965 | const identifier = try Tag.identifier.create(c.arena, mangled_name); | 5992 | const identifier = try Tag.identifier.create(c.arena, mangled_name); |
| ... | @@ -5992,10 +6019,19 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5992,10 +6019,19 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5992 | // after a primary expression. | 6019 | // after a primary expression. |
| 5993 | while (true) { | 6020 | while (true) { |
| 5994 | switch (m.peek().?) { | 6021 | switch (m.peek().?) { |
| 5995 | .StringLiteral, .Identifier => {}, | 6022 | .StringLiteral => {}, |
| | 6023 | .Identifier => { |
| | 6024 | const tok = m.list[m.i + 1]; |
| | 6025 | const slice = m.source[tok.start..tok.end]; |
| | 6026 | if (c.global_scope.blank_macros.contains(slice)) { |
| | 6027 | m.i += 1; |
| | 6028 | continue; |
| | 6029 | } |
| | 6030 | }, |
| 5996 | else => break, | 6031 | else => break, |
| 5997 | } | 6032 | } |
| 5998 | node = try Tag.array_cat.create(c.arena, .{ .lhs = node, .rhs = try parseCPrimaryExprInner(c, m, scope) }); | 6033 | const rhs = try parseCPrimaryExprInner(c, m, scope); |
| | 6034 | node = try Tag.array_cat.create(c.arena, .{ .lhs = node, .rhs = rhs }); |
| 5999 | } | 6035 | } |
| 6000 | return node; | 6036 | return node; |
| 6001 | } | 6037 | } |
| ... | @@ -6211,7 +6247,24 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -6211,7 +6247,24 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 6211 | switch (m.next().?) { | 6247 | switch (m.next().?) { |
| 6212 | .LParen => { | 6248 | .LParen => { |
| 6213 | if (try parseCTypeName(c, m, scope, true)) |type_name| { | 6249 | if (try parseCTypeName(c, m, scope, true)) |type_name| { |
| 6214 | try m.skip(c, .RParen); | 6250 | while (true) { |
| | 6251 | const next_token = m.next().?; |
| | 6252 | switch (next_token) { |
| | 6253 | .RParen => break, |
| | 6254 | else => |next_tag| { |
| | 6255 | // Skip trailing blank defined before the RParen. |
| | 6256 | if (next_tag == .Identifier and c.global_scope.blank_macros.contains(m.slice())) { |
| | 6257 | continue; |
| | 6258 | } |
| | 6259 | try m.fail( |
| | 6260 | c, |
| | 6261 | "unable to translate C expr: expected ')' instead got '{s}'", |
| | 6262 | .{next_token.symbol()}, |
| | 6263 | ); |
| | 6264 | return error.ParseError; |
| | 6265 | }, |
| | 6266 | } |
| | 6267 | } |
| 6215 | if (m.peek().? == .LBrace) { | 6268 | if (m.peek().? == .LBrace) { |
| 6216 | // initializer list | 6269 | // initializer list |
| 6217 | return parseCPostfixExpr(c, m, scope, type_name); | 6270 | return parseCPostfixExpr(c, m, scope, type_name); |
| ... | @@ -6239,6 +6292,9 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_ | ... | @@ -6239,6 +6292,9 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_ |
| 6239 | const tok = m.next().?; | 6292 | const tok = m.next().?; |
| 6240 | switch (tok) { | 6293 | switch (tok) { |
| 6241 | .Identifier => { | 6294 | .Identifier => { |
| | 6295 | if (c.global_scope.blank_macros.contains(m.slice())) { |
| | 6296 | return try parseCSpecifierQualifierList(c, m, scope, allow_fail); |
| | 6297 | } |
| 6242 | const mangled_name = scope.getAlias(m.slice()); | 6298 | const mangled_name = scope.getAlias(m.slice()); |
| 6243 | if (!allow_fail or c.typedefs.contains(mangled_name)) { | 6299 | if (!allow_fail or c.typedefs.contains(mangled_name)) { |
| 6244 | if (builtin_typedef_map.get(mangled_name)) |ty| return try Tag.type.create(c.arena, ty); | 6300 | if (builtin_typedef_map.get(mangled_name)) |ty| return try Tag.type.create(c.arena, ty); |