| ... | ... | @@ -3089,7 +3089,7 @@ fn transUnaryExprOrTypeTraitExpr( |
| 3089 | 3089 | .AlignOf => "@alignOf", |
| 3090 | 3090 | .PreferredAlignOf, |
| 3091 | 3091 | .VecStep, |
| 3092 | | .OpenMPRequiredSimdAlign, |
| 3092 | .OpenMPRequiredSimdAlign, |
| 3093 | 3093 | => return revertAndWarn( |
| 3094 | 3094 | rp, |
| 3095 | 3095 | error.UnsupportedTranslation, |
| ... | ... | @@ -5220,26 +5220,32 @@ pub fn freeErrors(errors: []ClangErrMsg) void { |
| 5220 | 5220 | ZigClangErrorMsg_delete(errors.ptr, errors.len); |
| 5221 | 5221 | } |
| 5222 | 5222 | |
| 5223 | | const CTokIterator = struct { |
| 5223 | const MacroCtx = struct { |
| 5224 | 5224 | source: []const u8, |
| 5225 | 5225 | list: []const CToken, |
| 5226 | 5226 | i: usize = 0, |
| 5227 | loc: ZigClangSourceLocation, |
| 5228 | name: []const u8, |
| 5227 | 5229 | |
| 5228 | | fn peek(self: *CTokIterator) ?CToken.Id { |
| 5230 | fn peek(self: *MacroCtx) ?CToken.Id { |
| 5229 | 5231 | if (self.i >= self.list.len) return null; |
| 5230 | 5232 | return self.list[self.i + 1].id; |
| 5231 | 5233 | } |
| 5232 | 5234 | |
| 5233 | | fn next(self: *CTokIterator) ?CToken.Id { |
| 5235 | fn next(self: *MacroCtx) ?CToken.Id { |
| 5234 | 5236 | if (self.i >= self.list.len) return null; |
| 5235 | 5237 | self.i += 1; |
| 5236 | 5238 | return self.list[self.i].id; |
| 5237 | 5239 | } |
| 5238 | 5240 | |
| 5239 | | fn slice(self: *CTokIterator, index: usize) []const u8 { |
| 5240 | | const tok = self.list[index]; |
| 5241 | fn slice(self: *MacroCtx) []const u8 { |
| 5242 | const tok = self.list[self.i]; |
| 5241 | 5243 | return self.source[tok.start..tok.end]; |
| 5242 | 5244 | } |
| 5245 | |
| 5246 | fn fail(self: *MacroCtx, c: *Context, comptime fmt: []const u8, args: anytype) !void { |
| 5247 | return failDecl(c, self.loc, self.name, fmt, args); |
| 5248 | } |
| 5243 | 5249 | }; |
| 5244 | 5250 | |
| 5245 | 5251 | fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| ... | ... | @@ -5286,18 +5292,21 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 5286 | 5292 | try tok_list.append(tok); |
| 5287 | 5293 | } |
| 5288 | 5294 | |
| 5289 | | var tok_it = CTokIterator{ |
| 5295 | var macro_ctx = MacroCtx{ |
| 5290 | 5296 | .source = slice, |
| 5291 | 5297 | .list = tok_list.items, |
| 5298 | .name = mangled_name, |
| 5299 | .loc = begin_loc, |
| 5292 | 5300 | }; |
| 5293 | | assert(mem.eql(u8, tok_it.slice(0), name)); |
| 5301 | assert(mem.eql(u8, macro_ctx.slice(), name)); |
| 5294 | 5302 | |
| 5295 | 5303 | var macro_fn = false; |
| 5296 | | switch (tok_it.peek().?) { |
| 5304 | switch (macro_ctx.peek().?) { |
| 5297 | 5305 | .Identifier => { |
| 5298 | 5306 | // if it equals itself, ignore. for example, from stdio.h: |
| 5299 | 5307 | // #define stdin stdin |
| 5300 | | if (mem.eql(u8, name, tok_it.slice(1))) { |
| 5308 | const tok = macro_ctx.list[1]; |
| 5309 | if (mem.eql(u8, name, slice[tok.start..tok.end])) { |
| 5301 | 5310 | continue; |
| 5302 | 5311 | } |
| 5303 | 5312 | }, |
| ... | ... | @@ -5308,15 +5317,15 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 5308 | 5317 | }, |
| 5309 | 5318 | .LParen => { |
| 5310 | 5319 | // if the name is immediately followed by a '(' then it is a function |
| 5311 | | macro_fn = tok_it.list[0].end == tok_it.list[1].start; |
| 5320 | macro_fn = macro_ctx.list[0].end == macro_ctx.list[1].start; |
| 5312 | 5321 | }, |
| 5313 | 5322 | else => {}, |
| 5314 | 5323 | } |
| 5315 | 5324 | |
| 5316 | 5325 | (if (macro_fn) |
| 5317 | | transMacroFnDefine(c, &tok_it, mangled_name, begin_loc) |
| 5326 | transMacroFnDefine(c, &macro_ctx) |
| 5318 | 5327 | else |
| 5319 | | transMacroDefine(c, &tok_it, mangled_name, begin_loc)) catch |err| switch (err) { |
| 5328 | transMacroDefine(c, &macro_ctx)) catch |err| switch (err) { |
| 5320 | 5329 | error.ParseError => continue, |
| 5321 | 5330 | error.OutOfMemory => |e| return e, |
| 5322 | 5331 | }; |
| ... | ... | @@ -5326,24 +5335,18 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 5326 | 5335 | } |
| 5327 | 5336 | } |
| 5328 | 5337 | |
| 5329 | | fn transMacroDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 5338 | fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5330 | 5339 | const scope = &c.global_scope.base; |
| 5331 | 5340 | |
| 5332 | 5341 | const visib_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 5333 | 5342 | const mut_tok = try appendToken(c, .Keyword_const, "const"); |
| 5334 | | const name_tok = try appendIdentifier(c, name); |
| 5343 | const name_tok = try appendIdentifier(c, m.name); |
| 5335 | 5344 | const eq_token = try appendToken(c, .Equal, "="); |
| 5336 | 5345 | |
| 5337 | | const init_node = try parseCExpr(c, it, source_loc, scope); |
| 5338 | | const last = it.next().?; |
| 5346 | const init_node = try parseCExpr(c, m, scope); |
| 5347 | const last = m.next().?; |
| 5339 | 5348 | if (last != .Eof and last != .Nl) |
| 5340 | | return failDecl( |
| 5341 | | c, |
| 5342 | | source_loc, |
| 5343 | | name, |
| 5344 | | "unable to translate C expr: unexpected token .{}", |
| 5345 | | .{@tagName(last)}, |
| 5346 | | ); |
| 5349 | return m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(last)}); |
| 5347 | 5350 | |
| 5348 | 5351 | const semicolon_token = try appendToken(c, .Semicolon, ";"); |
| 5349 | 5352 | const node = try ast.Node.VarDecl.create(c.arena, .{ |
| ... | ... | @@ -5355,10 +5358,10 @@ fn transMacroDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc |
| 5355 | 5358 | .eq_token = eq_token, |
| 5356 | 5359 | .init_node = init_node, |
| 5357 | 5360 | }); |
| 5358 | | _ = try c.global_scope.macro_table.put(name, &node.base); |
| 5361 | _ = try c.global_scope.macro_table.put(m.name, &node.base); |
| 5359 | 5362 | } |
| 5360 | 5363 | |
| 5361 | | fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void { |
| 5364 | fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5362 | 5365 | var block_scope = try Scope.Block.init(c, &c.global_scope.base, null); |
| 5363 | 5366 | defer block_scope.deinit(); |
| 5364 | 5367 | const scope = &block_scope.base; |
| ... | ... | @@ -5366,34 +5369,22 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l |
| 5366 | 5369 | const pub_tok = try appendToken(c, .Keyword_pub, "pub"); |
| 5367 | 5370 | const inline_tok = try appendToken(c, .Keyword_inline, "inline"); |
| 5368 | 5371 | const fn_tok = try appendToken(c, .Keyword_fn, "fn"); |
| 5369 | | const name_tok = try appendIdentifier(c, name); |
| 5372 | const name_tok = try appendIdentifier(c, m.name); |
| 5370 | 5373 | _ = try appendToken(c, .LParen, "("); |
| 5371 | 5374 | |
| 5372 | | if (it.next().? != .LParen) { |
| 5373 | | return failDecl( |
| 5374 | | c, |
| 5375 | | source_loc, |
| 5376 | | name, |
| 5377 | | "unable to translate C expr: expected '('", |
| 5378 | | .{}, |
| 5379 | | ); |
| 5375 | if (m.next().? != .LParen) { |
| 5376 | return m.fail(c, "unable to translate C expr: expected '('", .{}); |
| 5380 | 5377 | } |
| 5381 | 5378 | |
| 5382 | 5379 | var fn_params = std.ArrayList(ast.Node.FnProto.ParamDecl).init(c.gpa); |
| 5383 | 5380 | defer fn_params.deinit(); |
| 5384 | 5381 | |
| 5385 | 5382 | while (true) { |
| 5386 | | if (it.next().? != .Identifier) { |
| 5387 | | return failDecl( |
| 5388 | | c, |
| 5389 | | source_loc, |
| 5390 | | name, |
| 5391 | | "unable to translate C expr: expected identifier", |
| 5392 | | .{}, |
| 5393 | | ); |
| 5383 | if (m.next().? != .Identifier) { |
| 5384 | return m.fail(c, "unable to translate C expr: expected identifier", .{}); |
| 5394 | 5385 | } |
| 5395 | 5386 | |
| 5396 | | const mangled_name = try block_scope.makeMangledName(c, it.slice(it.i)); |
| 5387 | const mangled_name = try block_scope.makeMangledName(c, m.slice()); |
| 5397 | 5388 | const param_name_tok = try appendIdentifier(c, mangled_name); |
| 5398 | 5389 | _ = try appendToken(c, .Colon, ":"); |
| 5399 | 5390 | |
| ... | ... | @@ -5411,20 +5402,14 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l |
| 5411 | 5402 | .param_type = .{ .any_type = &any_type.base }, |
| 5412 | 5403 | }; |
| 5413 | 5404 | |
| 5414 | | if (it.peek().? != .Comma) |
| 5405 | if (m.peek().? != .Comma) |
| 5415 | 5406 | break; |
| 5416 | | _ = it.next(); |
| 5407 | _ = m.next(); |
| 5417 | 5408 | _ = try appendToken(c, .Comma, ","); |
| 5418 | 5409 | } |
| 5419 | 5410 | |
| 5420 | | if (it.next().? != .RParen) { |
| 5421 | | return failDecl( |
| 5422 | | c, |
| 5423 | | source_loc, |
| 5424 | | name, |
| 5425 | | "unable to translate C expr: expected ')'", |
| 5426 | | .{}, |
| 5427 | | ); |
| 5411 | if (m.next().? != .RParen) { |
| 5412 | return m.fail(c, "unable to translate C expr: expected ')'", .{}); |
| 5428 | 5413 | } |
| 5429 | 5414 | |
| 5430 | 5415 | _ = try appendToken(c, .RParen, ")"); |
| ... | ... | @@ -5432,16 +5417,10 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l |
| 5432 | 5417 | const type_of = try c.createBuiltinCall("@TypeOf", 1); |
| 5433 | 5418 | |
| 5434 | 5419 | const return_kw = try appendToken(c, .Keyword_return, "return"); |
| 5435 | | const expr = try parseCExpr(c, it, source_loc, scope); |
| 5436 | | const last = it.next().?; |
| 5420 | const expr = try parseCExpr(c, m, scope); |
| 5421 | const last = m.next().?; |
| 5437 | 5422 | if (last != .Eof and last != .Nl) |
| 5438 | | return failDecl( |
| 5439 | | c, |
| 5440 | | source_loc, |
| 5441 | | name, |
| 5442 | | "unable to translate C expr: unexpected token .{}", |
| 5443 | | .{@tagName(last)}, |
| 5444 | | ); |
| 5423 | return m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(last)}); |
| 5445 | 5424 | _ = try appendToken(c, .Semicolon, ";"); |
| 5446 | 5425 | const type_of_arg = if (expr.tag != .Block) expr else blk: { |
| 5447 | 5426 | const blk = @fieldParentPtr(ast.Node.Block, "base", expr); |
| ... | ... | @@ -5472,32 +5451,26 @@ fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_l |
| 5472 | 5451 | }); |
| 5473 | 5452 | mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items); |
| 5474 | 5453 | |
| 5475 | | _ = try c.global_scope.macro_table.put(name, &fn_proto.base); |
| 5454 | _ = try c.global_scope.macro_table.put(m.name, &fn_proto.base); |
| 5476 | 5455 | } |
| 5477 | 5456 | |
| 5478 | 5457 | const ParseError = Error || error{ParseError}; |
| 5479 | 5458 | |
| 5480 | | fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 5481 | | const node = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 5482 | | switch (it.next().?) { |
| 5459 | fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node { |
| 5460 | const node = try parseCPrefixOpExpr(c, m, scope); |
| 5461 | switch (m.next().?) { |
| 5483 | 5462 | .QuestionMark => { |
| 5484 | 5463 | // must come immediately after expr |
| 5485 | 5464 | _ = try appendToken(c, .RParen, ")"); |
| 5486 | 5465 | const if_node = try transCreateNodeIf(c); |
| 5487 | 5466 | if_node.condition = node; |
| 5488 | | if_node.body = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 5489 | | if (it.next().? != .Colon) { |
| 5490 | | try failDecl( |
| 5491 | | c, |
| 5492 | | source_loc, |
| 5493 | | it.slice(0), |
| 5494 | | "unable to translate C expr: expected ':'", |
| 5495 | | .{}, |
| 5496 | | ); |
| 5467 | if_node.body = try parseCPrimaryExpr(c, m, scope); |
| 5468 | if (m.next().? != .Colon) { |
| 5469 | try m.fail(c, "unable to translate C expr: expected ':'", .{}); |
| 5497 | 5470 | return error.ParseError; |
| 5498 | 5471 | } |
| 5499 | 5472 | if_node.@"else" = try transCreateNodeElse(c); |
| 5500 | | if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 5473 | if_node.@"else".?.body = try parseCPrimaryExpr(c, m, scope); |
| 5501 | 5474 | return &if_node.base; |
| 5502 | 5475 | }, |
| 5503 | 5476 | .Comma => { |
| ... | ... | @@ -5520,10 +5493,10 @@ fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation |
| 5520 | 5493 | }; |
| 5521 | 5494 | try block_scope.statements.append(&op_node.base); |
| 5522 | 5495 | |
| 5523 | | last = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 5496 | last = try parseCPrefixOpExpr(c, m, scope); |
| 5524 | 5497 | _ = try appendToken(c, .Semicolon, ";"); |
| 5525 | | if (it.next().? != .Comma) { |
| 5526 | | it.i -= 1; |
| 5498 | if (m.next().? != .Comma) { |
| 5499 | m.i -= 1; |
| 5527 | 5500 | break; |
| 5528 | 5501 | } |
| 5529 | 5502 | } |
| ... | ... | @@ -5534,16 +5507,16 @@ fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation |
| 5534 | 5507 | return &block_node.base; |
| 5535 | 5508 | }, |
| 5536 | 5509 | else => { |
| 5537 | | it.i -= 1; |
| 5510 | m.i -= 1; |
| 5538 | 5511 | return node; |
| 5539 | 5512 | }, |
| 5540 | 5513 | } |
| 5541 | 5514 | } |
| 5542 | 5515 | |
| 5543 | | fn parseCNumLit(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation) ParseError!*ast.Node { |
| 5544 | | var lit_bytes = it.slice(it.i); |
| 5516 | fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!*ast.Node { |
| 5517 | var lit_bytes = m.slice(); |
| 5545 | 5518 | |
| 5546 | | switch (it.list[it.i].id) { |
| 5519 | switch (m.list[m.i].id) { |
| 5547 | 5520 | .IntegerLiteral => |suffix| { |
| 5548 | 5521 | if (lit_bytes.len > 2 and lit_bytes[0] == '0') { |
| 5549 | 5522 | switch (lit_bytes[1]) { |
| ... | ... | @@ -5604,8 +5577,8 @@ fn parseCNumLit(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocati |
| 5604 | 5577 | } |
| 5605 | 5578 | } |
| 5606 | 5579 | |
| 5607 | | fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ![]const u8 { |
| 5608 | | var source = source_bytes; |
| 5580 | fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 { |
| 5581 | var source = m.slice(); |
| 5609 | 5582 | for (source) |c, i| { |
| 5610 | 5583 | if (c == '\"' or c == '\'') { |
| 5611 | 5584 | source = source[i..]; |
| ... | ... | @@ -5677,11 +5650,11 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const |
| 5677 | 5650 | bytes[i] = '?'; |
| 5678 | 5651 | }, |
| 5679 | 5652 | 'u', 'U' => { |
| 5680 | | try failDecl(ctx, source_loc, name, "macro tokenizing failed: TODO unicode escape sequences", .{}); |
| 5653 | try m.fail(ctx, "macro tokenizing failed: TODO unicode escape sequences", .{}); |
| 5681 | 5654 | return error.ParseError; |
| 5682 | 5655 | }, |
| 5683 | 5656 | else => { |
| 5684 | | try failDecl(ctx, source_loc, name, "macro tokenizing failed: unknown escape sequence", .{}); |
| 5657 | try m.fail(ctx, "macro tokenizing failed: unknown escape sequence", .{}); |
| 5685 | 5658 | return error.ParseError; |
| 5686 | 5659 | }, |
| 5687 | 5660 | } |
| ... | ... | @@ -5700,21 +5673,21 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const |
| 5700 | 5673 | switch (c) { |
| 5701 | 5674 | '0'...'9' => { |
| 5702 | 5675 | num = std.math.mul(u8, num, 16) catch { |
| 5703 | | try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{}); |
| 5676 | try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{}); |
| 5704 | 5677 | return error.ParseError; |
| 5705 | 5678 | }; |
| 5706 | 5679 | num += c - '0'; |
| 5707 | 5680 | }, |
| 5708 | 5681 | 'a'...'f' => { |
| 5709 | 5682 | num = std.math.mul(u8, num, 16) catch { |
| 5710 | | try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{}); |
| 5683 | try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{}); |
| 5711 | 5684 | return error.ParseError; |
| 5712 | 5685 | }; |
| 5713 | 5686 | num += c - 'a' + 10; |
| 5714 | 5687 | }, |
| 5715 | 5688 | 'A'...'F' => { |
| 5716 | 5689 | num = std.math.mul(u8, num, 16) catch { |
| 5717 | | try failDecl(ctx, source_loc, name, "macro tokenizing failed: hex literal overflowed", .{}); |
| 5690 | try m.fail(ctx, "macro tokenizing failed: hex literal overflowed", .{}); |
| 5718 | 5691 | return error.ParseError; |
| 5719 | 5692 | }; |
| 5720 | 5693 | num += c - 'A' + 10; |
| ... | ... | @@ -5741,7 +5714,7 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const |
| 5741 | 5714 | if (accept_digit) { |
| 5742 | 5715 | count += 1; |
| 5743 | 5716 | num = std.math.mul(u8, num, 8) catch { |
| 5744 | | try failDecl(ctx, source_loc, name, "macro tokenizing failed: octal literal overflowed", .{}); |
| 5717 | try m.fail(ctx, "macro tokenizing failed: octal literal overflowed", .{}); |
| 5745 | 5718 | return error.ParseError; |
| 5746 | 5719 | }; |
| 5747 | 5720 | num += c - '0'; |
| ... | ... | @@ -5764,13 +5737,13 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const |
| 5764 | 5737 | return bytes[0..i]; |
| 5765 | 5738 | } |
| 5766 | 5739 | |
| 5767 | | fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 5768 | | const tok = it.next().?; |
| 5769 | | const slice = it.slice(it.i); |
| 5740 | fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node { |
| 5741 | const tok = m.next().?; |
| 5742 | const slice = m.slice(); |
| 5770 | 5743 | switch (tok) { |
| 5771 | 5744 | .CharLiteral => { |
| 5772 | 5745 | if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) { |
| 5773 | | const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, slice, it.slice(0), source_loc)); |
| 5746 | const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, m)); |
| 5774 | 5747 | const node = try c.arena.create(ast.Node.OneToken); |
| 5775 | 5748 | node.* = .{ |
| 5776 | 5749 | .base = .{ .tag = .CharLiteral }, |
| ... | ... | @@ -5788,7 +5761,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL |
| 5788 | 5761 | } |
| 5789 | 5762 | }, |
| 5790 | 5763 | .StringLiteral => { |
| 5791 | | const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, slice, it.slice(0), source_loc)); |
| 5764 | const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, m)); |
| 5792 | 5765 | const node = try c.arena.create(ast.Node.OneToken); |
| 5793 | 5766 | node.* = .{ |
| 5794 | 5767 | .base = .{ .tag = .StringLiteral }, |
| ... | ... | @@ -5797,7 +5770,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL |
| 5797 | 5770 | return &node.base; |
| 5798 | 5771 | }, |
| 5799 | 5772 | .IntegerLiteral, .FloatLiteral => { |
| 5800 | | return parseCNumLit(c, it, source_loc); |
| 5773 | return parseCNumLit(c, m); |
| 5801 | 5774 | }, |
| 5802 | 5775 | // eventually this will be replaced by std.c.parse which will handle these correctly |
| 5803 | 5776 | .Keyword_void => return transCreateNodeIdentifierUnchecked(c, "c_void"), |
| ... | ... | @@ -5808,61 +5781,55 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL |
| 5808 | 5781 | .Keyword_float => return transCreateNodeIdentifierUnchecked(c, "f32"), |
| 5809 | 5782 | .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"), |
| 5810 | 5783 | .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "u8"), |
| 5811 | | .Keyword_unsigned => if (it.next()) |t| switch (t) { |
| 5784 | .Keyword_unsigned => if (m.next()) |t| switch (t) { |
| 5812 | 5785 | .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "u8"), |
| 5813 | 5786 | .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_ushort"), |
| 5814 | 5787 | .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_uint"), |
| 5815 | | .Keyword_long => if (it.peek() != null and it.peek().? == .Keyword_long) { |
| 5816 | | _ = it.next(); |
| 5788 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { |
| 5789 | _ = m.next(); |
| 5817 | 5790 | return transCreateNodeIdentifierUnchecked(c, "c_ulonglong"); |
| 5818 | 5791 | } else return transCreateNodeIdentifierUnchecked(c, "c_ulong"), |
| 5819 | 5792 | else => { |
| 5820 | | it.i -= 1; |
| 5793 | m.i -= 1; |
| 5821 | 5794 | return transCreateNodeIdentifierUnchecked(c, "c_uint"); |
| 5822 | 5795 | }, |
| 5823 | 5796 | } else { |
| 5824 | 5797 | return transCreateNodeIdentifierUnchecked(c, "c_uint"); |
| 5825 | 5798 | }, |
| 5826 | | .Keyword_signed => if (it.next()) |t| switch (t) { |
| 5799 | .Keyword_signed => if (m.next()) |t| switch (t) { |
| 5827 | 5800 | .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "i8"), |
| 5828 | 5801 | .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"), |
| 5829 | 5802 | .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_int"), |
| 5830 | | .Keyword_long => if (it.peek() != null and it.peek().? == .Keyword_long) { |
| 5831 | | _ = it.next(); |
| 5803 | .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) { |
| 5804 | _ = m.next(); |
| 5832 | 5805 | return transCreateNodeIdentifierUnchecked(c, "c_longlong"); |
| 5833 | 5806 | } else return transCreateNodeIdentifierUnchecked(c, "c_long"), |
| 5834 | 5807 | else => { |
| 5835 | | it.i -= 1; |
| 5808 | m.i -= 1; |
| 5836 | 5809 | return transCreateNodeIdentifierUnchecked(c, "c_int"); |
| 5837 | 5810 | }, |
| 5838 | 5811 | } else { |
| 5839 | 5812 | return transCreateNodeIdentifierUnchecked(c, "c_int"); |
| 5840 | 5813 | }, |
| 5841 | 5814 | .Identifier => { |
| 5842 | | const mangled_name = scope.getAlias(it.slice(it.i)); |
| 5815 | const mangled_name = scope.getAlias(slice); |
| 5843 | 5816 | return transCreateNodeIdentifier(c, mangled_name); |
| 5844 | 5817 | }, |
| 5845 | 5818 | .LParen => { |
| 5846 | | const inner_node = try parseCExpr(c, it, source_loc, scope); |
| 5819 | const inner_node = try parseCExpr(c, m, scope); |
| 5847 | 5820 | |
| 5848 | | const next_id = it.next().?; |
| 5821 | const next_id = m.next().?; |
| 5849 | 5822 | if (next_id != .RParen) { |
| 5850 | | try failDecl( |
| 5851 | | c, |
| 5852 | | source_loc, |
| 5853 | | it.slice(0), |
| 5854 | | "unable to translate C expr: expected ')'' instead got: {}", |
| 5855 | | .{@tagName(next_id)}, |
| 5856 | | ); |
| 5823 | try m.fail(c, "unable to translate C expr: expected ')'' instead got: {}", .{@tagName(next_id)}); |
| 5857 | 5824 | return error.ParseError; |
| 5858 | 5825 | } |
| 5859 | 5826 | var saw_l_paren = false; |
| 5860 | 5827 | var saw_integer_literal = false; |
| 5861 | | switch (it.peek().?) { |
| 5828 | switch (m.peek().?) { |
| 5862 | 5829 | // (type)(to_cast) |
| 5863 | 5830 | .LParen => { |
| 5864 | 5831 | saw_l_paren = true; |
| 5865 | | _ = it.next(); |
| 5832 | _ = m.next(); |
| 5866 | 5833 | }, |
| 5867 | 5834 | // (type)identifier |
| 5868 | 5835 | .Identifier => {}, |
| ... | ... | @@ -5876,16 +5843,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL |
| 5876 | 5843 | // hack to get zig fmt to render a comma in builtin calls |
| 5877 | 5844 | _ = try appendToken(c, .Comma, ","); |
| 5878 | 5845 | |
| 5879 | | const node_to_cast = try parseCExpr(c, it, source_loc, scope); |
| 5846 | const node_to_cast = try parseCExpr(c, m, scope); |
| 5880 | 5847 | |
| 5881 | | if (saw_l_paren and it.next().? != .RParen) { |
| 5882 | | try failDecl( |
| 5883 | | c, |
| 5884 | | source_loc, |
| 5885 | | it.slice(0), |
| 5886 | | "unable to translate C expr: expected ')''", |
| 5887 | | .{}, |
| 5888 | | ); |
| 5848 | if (saw_l_paren and m.next().? != .RParen) { |
| 5849 | try m.fail(c, "unable to translate C expr: expected ')''", .{}); |
| 5889 | 5850 | return error.ParseError; |
| 5890 | 5851 | } |
| 5891 | 5852 | |
| ... | ... | @@ -5913,13 +5874,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceL |
| 5913 | 5874 | return &group_node.base; |
| 5914 | 5875 | }, |
| 5915 | 5876 | else => { |
| 5916 | | try failDecl( |
| 5917 | | c, |
| 5918 | | source_loc, |
| 5919 | | it.slice(0), |
| 5920 | | "unable to translate C expr: unexpected token .{}", |
| 5921 | | .{@tagName(tok)}, |
| 5922 | | ); |
| 5877 | try m.fail(c, "unable to translate C expr: unexpected token .{}", .{@tagName(tok)}); |
| 5923 | 5878 | return error.ParseError; |
| 5924 | 5879 | }, |
| 5925 | 5880 | } |
| ... | ... | @@ -6026,52 +5981,40 @@ fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node { |
| 6026 | 5981 | return &group_node.base; |
| 6027 | 5982 | } |
| 6028 | 5983 | |
| 6029 | | fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 6030 | | var node = try parseCPrimaryExpr(c, it, source_loc, scope); |
| 5984 | fn parseCSuffixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node { |
| 5985 | var node = try parseCPrimaryExpr(c, m, scope); |
| 6031 | 5986 | while (true) { |
| 6032 | 5987 | var op_token: ast.TokenIndex = undefined; |
| 6033 | 5988 | var op_id: ast.Node.Tag = undefined; |
| 6034 | 5989 | var bool_op = false; |
| 6035 | | switch (it.next().?) { |
| 5990 | switch (m.next().?) { |
| 6036 | 5991 | .Period => { |
| 6037 | | if (it.next().? != .Identifier) { |
| 6038 | | try failDecl( |
| 6039 | | c, |
| 6040 | | source_loc, |
| 6041 | | it.slice(0), |
| 6042 | | "unable to translate C expr: expected identifier", |
| 6043 | | .{}, |
| 6044 | | ); |
| 5992 | if (m.next().? != .Identifier) { |
| 5993 | try m.fail(c, "unable to translate C expr: expected identifier", .{}); |
| 6045 | 5994 | return error.ParseError; |
| 6046 | 5995 | } |
| 6047 | 5996 | |
| 6048 | | node = try transCreateNodeFieldAccess(c, node, it.slice(it.i)); |
| 5997 | node = try transCreateNodeFieldAccess(c, node, m.slice()); |
| 6049 | 5998 | continue; |
| 6050 | 5999 | }, |
| 6051 | 6000 | .Arrow => { |
| 6052 | | if (it.next().? != .Identifier) { |
| 6053 | | try failDecl( |
| 6054 | | c, |
| 6055 | | source_loc, |
| 6056 | | it.slice(0), |
| 6057 | | "unable to translate C expr: expected identifier", |
| 6058 | | .{}, |
| 6059 | | ); |
| 6001 | if (m.next().? != .Identifier) { |
| 6002 | try m.fail(c, "unable to translate C expr: expected identifier", .{}); |
| 6060 | 6003 | return error.ParseError; |
| 6061 | 6004 | } |
| 6062 | 6005 | const deref = try transCreateNodePtrDeref(c, node); |
| 6063 | | node = try transCreateNodeFieldAccess(c, deref, it.slice(it.i)); |
| 6006 | node = try transCreateNodeFieldAccess(c, deref, m.slice()); |
| 6064 | 6007 | continue; |
| 6065 | 6008 | }, |
| 6066 | 6009 | .Asterisk => { |
| 6067 | | if (it.peek().? == .RParen) { |
| 6010 | if (m.peek().? == .RParen) { |
| 6068 | 6011 | // type *) |
| 6069 | 6012 | |
| 6070 | 6013 | // hack to get zig fmt to render a comma in builtin calls |
| 6071 | 6014 | _ = try appendToken(c, .Comma, ","); |
| 6072 | 6015 | |
| 6073 | 6016 | // last token of `node` |
| 6074 | | const prev_id = it.list[it.i - 1].id; |
| 6017 | const prev_id = m.list[m.i - 1].id; |
| 6075 | 6018 | |
| 6076 | 6019 | if (prev_id == .Keyword_void) { |
| 6077 | 6020 | const ptr = try transCreateNodePtrType(c, false, false, .Asterisk); |
| ... | ... | @@ -6142,17 +6085,11 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource |
| 6142 | 6085 | }, |
| 6143 | 6086 | .LBracket => { |
| 6144 | 6087 | const arr_node = try transCreateNodeArrayAccess(c, node); |
| 6145 | | arr_node.index_expr = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6088 | arr_node.index_expr = try parseCPrefixOpExpr(c, m, scope); |
| 6146 | 6089 | arr_node.rtoken = try appendToken(c, .RBracket, "]"); |
| 6147 | 6090 | node = &arr_node.base; |
| 6148 | | if (it.next().? != .RBracket) { |
| 6149 | | try failDecl( |
| 6150 | | c, |
| 6151 | | source_loc, |
| 6152 | | it.slice(0), |
| 6153 | | "unable to translate C expr: expected ']'", |
| 6154 | | .{}, |
| 6155 | | ); |
| 6091 | if (m.next().? != .RBracket) { |
| 6092 | try m.fail(c, "unable to translate C expr: expected ']'", .{}); |
| 6156 | 6093 | return error.ParseError; |
| 6157 | 6094 | } |
| 6158 | 6095 | continue; |
| ... | ... | @@ -6162,19 +6099,13 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource |
| 6162 | 6099 | var call_params = std.ArrayList(*ast.Node).init(c.gpa); |
| 6163 | 6100 | defer call_params.deinit(); |
| 6164 | 6101 | while (true) { |
| 6165 | | const arg = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6102 | const arg = try parseCPrefixOpExpr(c, m, scope); |
| 6166 | 6103 | try call_params.append(arg); |
| 6167 | | switch (it.next().?) { |
| 6104 | switch (m.next().?) { |
| 6168 | 6105 | .Comma => _ = try appendToken(c, .Comma, ","), |
| 6169 | 6106 | .RParen => break, |
| 6170 | 6107 | else => { |
| 6171 | | try failDecl( |
| 6172 | | c, |
| 6173 | | source_loc, |
| 6174 | | it.slice(0), |
| 6175 | | "unable to translate C expr: expected ',' or ')'", |
| 6176 | | .{}, |
| 6177 | | ); |
| 6108 | try m.fail(c, "unable to translate C expr: expected ',' or ')'", .{}); |
| 6178 | 6109 | return error.ParseError; |
| 6179 | 6110 | }, |
| 6180 | 6111 | } |
| ... | ... | @@ -6201,19 +6132,13 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource |
| 6201 | 6132 | defer init_vals.deinit(); |
| 6202 | 6133 | |
| 6203 | 6134 | while (true) { |
| 6204 | | const val = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6135 | const val = try parseCPrefixOpExpr(c, m, scope); |
| 6205 | 6136 | try init_vals.append(val); |
| 6206 | | switch (it.next().?) { |
| 6137 | switch (m.next().?) { |
| 6207 | 6138 | .Comma => _ = try appendToken(c, .Comma, ","), |
| 6208 | 6139 | .RBrace => break, |
| 6209 | 6140 | else => { |
| 6210 | | try failDecl( |
| 6211 | | c, |
| 6212 | | source_loc, |
| 6213 | | it.slice(0), |
| 6214 | | "unable to translate C expr: expected ',' or '}}'", |
| 6215 | | .{}, |
| 6216 | | ); |
| 6141 | try m.fail(c, "unable to translate C expr: expected ',' or '}}'", .{}); |
| 6217 | 6142 | return error.ParseError; |
| 6218 | 6143 | }, |
| 6219 | 6144 | } |
| ... | ... | @@ -6262,22 +6187,22 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource |
| 6262 | 6187 | op_id = .ArrayCat; |
| 6263 | 6188 | op_token = try appendToken(c, .PlusPlus, "++"); |
| 6264 | 6189 | |
| 6265 | | it.i -= 1; |
| 6190 | m.i -= 1; |
| 6266 | 6191 | }, |
| 6267 | 6192 | .Identifier => { |
| 6268 | 6193 | op_id = .ArrayCat; |
| 6269 | 6194 | op_token = try appendToken(c, .PlusPlus, "++"); |
| 6270 | 6195 | |
| 6271 | | it.i -= 1; |
| 6196 | m.i -= 1; |
| 6272 | 6197 | }, |
| 6273 | 6198 | else => { |
| 6274 | | it.i -= 1; |
| 6199 | m.i -= 1; |
| 6275 | 6200 | return node; |
| 6276 | 6201 | }, |
| 6277 | 6202 | } |
| 6278 | 6203 | const cast_fn = if (bool_op) macroIntToBool else macroBoolToInt; |
| 6279 | 6204 | const lhs_node = try cast_fn(c, node); |
| 6280 | | const rhs_node = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6205 | const rhs_node = try parseCPrefixOpExpr(c, m, scope); |
| 6281 | 6206 | const op_node = try c.arena.create(ast.Node.SimpleInfixOp); |
| 6282 | 6207 | op_node.* = .{ |
| 6283 | 6208 | .base = .{ .tag = op_id }, |
| ... | ... | @@ -6289,36 +6214,36 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSource |
| 6289 | 6214 | } |
| 6290 | 6215 | } |
| 6291 | 6216 | |
| 6292 | | fn parseCPrefixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node { |
| 6293 | | switch (it.next().?) { |
| 6217 | fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node { |
| 6218 | switch (m.next().?) { |
| 6294 | 6219 | .Bang => { |
| 6295 | 6220 | const node = try transCreateNodeSimplePrefixOp(c, .BoolNot, .Bang, "!"); |
| 6296 | | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6221 | node.rhs = try parseCPrefixOpExpr(c, m, scope); |
| 6297 | 6222 | return &node.base; |
| 6298 | 6223 | }, |
| 6299 | 6224 | .Minus => { |
| 6300 | 6225 | const node = try transCreateNodeSimplePrefixOp(c, .Negation, .Minus, "-"); |
| 6301 | | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6226 | node.rhs = try parseCPrefixOpExpr(c, m, scope); |
| 6302 | 6227 | return &node.base; |
| 6303 | 6228 | }, |
| 6304 | | .Plus => return try parseCPrefixOpExpr(c, it, source_loc, scope), |
| 6229 | .Plus => return try parseCPrefixOpExpr(c, m, scope), |
| 6305 | 6230 | .Tilde => { |
| 6306 | 6231 | const node = try transCreateNodeSimplePrefixOp(c, .BitNot, .Tilde, "~"); |
| 6307 | | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6232 | node.rhs = try parseCPrefixOpExpr(c, m, scope); |
| 6308 | 6233 | return &node.base; |
| 6309 | 6234 | }, |
| 6310 | 6235 | .Asterisk => { |
| 6311 | | const node = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6236 | const node = try parseCPrefixOpExpr(c, m, scope); |
| 6312 | 6237 | return try transCreateNodePtrDeref(c, node); |
| 6313 | 6238 | }, |
| 6314 | 6239 | .Ampersand => { |
| 6315 | 6240 | const node = try transCreateNodeSimplePrefixOp(c, .AddressOf, .Ampersand, "&"); |
| 6316 | | node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope); |
| 6241 | node.rhs = try parseCPrefixOpExpr(c, m, scope); |
| 6317 | 6242 | return &node.base; |
| 6318 | 6243 | }, |
| 6319 | 6244 | else => { |
| 6320 | | it.i -= 1; |
| 6321 | | return try parseCSuffixOpExpr(c, it, source_loc, scope); |
| 6245 | m.i -= 1; |
| 6246 | return try parseCSuffixOpExpr(c, m, scope); |
| 6322 | 6247 | }, |
| 6323 | 6248 | } |
| 6324 | 6249 | } |