authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-27 15:19:07+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-07-27 15:38:56+03:00
loge7007fa7bd94b3290982b1c39933f700e4ee133f
treec054a9bce4e55f76106c98644b18e986d207a36a
parent9f6401c69275f5c80b92c2c4c18c9b73321b82aa
signature Commit is signed but in an unrecognized format.

translate-c: use ArrayList for macro tokens


3 files changed, 302 insertions(+), 323 deletions(-)

lib/std/c.zig+4
......@@ -8,6 +8,10 @@ pub const Tokenizer = tokenizer.Tokenizer;
88pub const parse = @import("c/parse.zig").parse;
99pub const ast = @import("c/ast.zig");
1010
11test "" {
12 _ = tokenizer;
13}
14
1115pub usingnamespace @import("os/bits.zig");
1216
1317pub usingnamespace switch (std.Target.current.os.tag) {
lib/std/c/tokenizer.zig+76-115
......@@ -1,19 +1,10 @@
11const std = @import("std");
22const mem = std.mem;
33
4pub const Source = struct {
5 buffer: []const u8,
6 file_name: []const u8,
7 tokens: TokenList,
8
9 pub const TokenList = std.SegmentedList(Token, 64);
10};
11
124pub const Token = struct {
135 id: Id,
146 start: usize,
157 end: usize,
16 source: *Source,
178
189 pub const Id = union(enum) {
1910 Invalid,
......@@ -251,31 +242,6 @@ pub const Token = struct {
251242 }
252243 };
253244
254 pub fn eql(a: Token, b: Token) bool {
255 // do we really need this cast here
256 if (@as(@TagType(Id), a.id) != b.id) return false;
257 return mem.eql(u8, a.slice(), b.slice());
258 }
259
260 pub fn slice(tok: Token) []const u8 {
261 return tok.source.buffer[tok.start..tok.end];
262 }
263
264 pub const Keyword = struct {
265 bytes: []const u8,
266 id: Id,
267 hash: u32,
268
269 fn init(bytes: []const u8, id: Id) Keyword {
270 @setEvalBranchQuota(2000);
271 return .{
272 .bytes = bytes,
273 .id = id,
274 .hash = std.hash_map.hashString(bytes),
275 };
276 }
277 };
278
279245 // TODO extensions
280246 pub const keywords = std.ComptimeStringMap(Id, .{
281247 .{ "auto", .Keyword_auto },
......@@ -355,26 +321,26 @@ pub const Token = struct {
355321 }
356322
357323 pub const NumSuffix = enum {
358 None,
359 F,
360 L,
361 U,
362 LU,
363 LL,
364 LLU,
324 none,
325 f,
326 l,
327 u,
328 lu,
329 ll,
330 llu,
365331 };
366332
367333 pub const StrKind = enum {
368 None,
369 Wide,
370 Utf8,
371 Utf16,
372 Utf32,
334 none,
335 wide,
336 utf_8,
337 utf_16,
338 utf_32,
373339 };
374340};
375341
376342pub const Tokenizer = struct {
377 source: *Source,
343 buffer: []const u8,
378344 index: usize = 0,
379345 prev_tok_id: @TagType(Token.Id) = .Invalid,
380346 pp_directive: bool = false,
......@@ -385,7 +351,6 @@ pub const Tokenizer = struct {
385351 .id = .Eof,
386352 .start = self.index,
387353 .end = undefined,
388 .source = self.source,
389354 };
390355 var state: enum {
391356 Start,
......@@ -446,8 +411,8 @@ pub const Tokenizer = struct {
446411 } = .Start;
447412 var string = false;
448413 var counter: u32 = 0;
449 while (self.index < self.source.buffer.len) : (self.index += 1) {
450 const c = self.source.buffer[self.index];
414 while (self.index < self.buffer.len) : (self.index += 1) {
415 const c = self.buffer[self.index];
451416 switch (state) {
452417 .Start => switch (c) {
453418 '\n' => {
......@@ -460,11 +425,11 @@ pub const Tokenizer = struct {
460425 state = .Cr;
461426 },
462427 '"' => {
463 result.id = .{ .StringLiteral = .None };
428 result.id = .{ .StringLiteral = .none };
464429 state = .StringLiteral;
465430 },
466431 '\'' => {
467 result.id = .{ .CharLiteral = .None };
432 result.id = .{ .CharLiteral = .none };
468433 state = .CharLiteralStart;
469434 },
470435 'u' => {
......@@ -641,11 +606,11 @@ pub const Tokenizer = struct {
641606 state = .u8;
642607 },
643608 '\'' => {
644 result.id = .{ .CharLiteral = .Utf16 };
609 result.id = .{ .CharLiteral = .utf_16 };
645610 state = .CharLiteralStart;
646611 },
647612 '\"' => {
648 result.id = .{ .StringLiteral = .Utf16 };
613 result.id = .{ .StringLiteral = .utf_16 };
649614 state = .StringLiteral;
650615 },
651616 else => {
......@@ -655,7 +620,7 @@ pub const Tokenizer = struct {
655620 },
656621 .u8 => switch (c) {
657622 '\"' => {
658 result.id = .{ .StringLiteral = .Utf8 };
623 result.id = .{ .StringLiteral = .utf_8 };
659624 state = .StringLiteral;
660625 },
661626 else => {
......@@ -665,11 +630,11 @@ pub const Tokenizer = struct {
665630 },
666631 .U => switch (c) {
667632 '\'' => {
668 result.id = .{ .CharLiteral = .Utf32 };
633 result.id = .{ .CharLiteral = .utf_32 };
669634 state = .CharLiteralStart;
670635 },
671636 '\"' => {
672 result.id = .{ .StringLiteral = .Utf32 };
637 result.id = .{ .StringLiteral = .utf_32 };
673638 state = .StringLiteral;
674639 },
675640 else => {
......@@ -679,11 +644,11 @@ pub const Tokenizer = struct {
679644 },
680645 .L => switch (c) {
681646 '\'' => {
682 result.id = .{ .CharLiteral = .Wide };
647 result.id = .{ .CharLiteral = .wide };
683648 state = .CharLiteralStart;
684649 },
685650 '\"' => {
686 result.id = .{ .StringLiteral = .Wide };
651 result.id = .{ .StringLiteral = .wide };
687652 state = .StringLiteral;
688653 },
689654 else => {
......@@ -808,7 +773,7 @@ pub const Tokenizer = struct {
808773 .Identifier => switch (c) {
809774 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
810775 else => {
811 result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier;
776 result.id = Token.getKeyword(self.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier;
812777 if (self.prev_tok_id == .Hash)
813778 self.pp_directive = true;
814779 break;
......@@ -1137,7 +1102,7 @@ pub const Tokenizer = struct {
11371102 state = .IntegerSuffixL;
11381103 },
11391104 else => {
1140 result.id = .{ .IntegerLiteral = .None };
1105 result.id = .{ .IntegerLiteral = .none };
11411106 break;
11421107 },
11431108 },
......@@ -1146,7 +1111,7 @@ pub const Tokenizer = struct {
11461111 state = .IntegerSuffixUL;
11471112 },
11481113 else => {
1149 result.id = .{ .IntegerLiteral = .U };
1114 result.id = .{ .IntegerLiteral = .u };
11501115 break;
11511116 },
11521117 },
......@@ -1155,34 +1120,34 @@ pub const Tokenizer = struct {
11551120 state = .IntegerSuffixLL;
11561121 },
11571122 'u', 'U' => {
1158 result.id = .{ .IntegerLiteral = .LU };
1123 result.id = .{ .IntegerLiteral = .lu };
11591124 self.index += 1;
11601125 break;
11611126 },
11621127 else => {
1163 result.id = .{ .IntegerLiteral = .L };
1128 result.id = .{ .IntegerLiteral = .l };
11641129 break;
11651130 },
11661131 },
11671132 .IntegerSuffixLL => switch (c) {
11681133 'u', 'U' => {
1169 result.id = .{ .IntegerLiteral = .LLU };
1134 result.id = .{ .IntegerLiteral = .llu };
11701135 self.index += 1;
11711136 break;
11721137 },
11731138 else => {
1174 result.id = .{ .IntegerLiteral = .LL };
1139 result.id = .{ .IntegerLiteral = .ll };
11751140 break;
11761141 },
11771142 },
11781143 .IntegerSuffixUL => switch (c) {
11791144 'l', 'L' => {
1180 result.id = .{ .IntegerLiteral = .LLU };
1145 result.id = .{ .IntegerLiteral = .llu };
11811146 self.index += 1;
11821147 break;
11831148 },
11841149 else => {
1185 result.id = .{ .IntegerLiteral = .LU };
1150 result.id = .{ .IntegerLiteral = .lu };
11861151 break;
11871152 },
11881153 },
......@@ -1230,26 +1195,26 @@ pub const Tokenizer = struct {
12301195 },
12311196 .FloatSuffix => switch (c) {
12321197 'l', 'L' => {
1233 result.id = .{ .FloatLiteral = .L };
1198 result.id = .{ .FloatLiteral = .l };
12341199 self.index += 1;
12351200 break;
12361201 },
12371202 'f', 'F' => {
1238 result.id = .{ .FloatLiteral = .F };
1203 result.id = .{ .FloatLiteral = .f };
12391204 self.index += 1;
12401205 break;
12411206 },
12421207 else => {
1243 result.id = .{ .FloatLiteral = .None };
1208 result.id = .{ .FloatLiteral = .none };
12441209 break;
12451210 },
12461211 },
12471212 }
1248 } else if (self.index == self.source.buffer.len) {
1213 } else if (self.index == self.buffer.len) {
12491214 switch (state) {
12501215 .Start => {},
12511216 .u, .u8, .U, .L, .Identifier => {
1252 result.id = Token.getKeyword(self.source.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier;
1217 result.id = Token.getKeyword(self.buffer[result.start..self.index], self.prev_tok_id == .Hash and !self.pp_directive) orelse .Identifier;
12531218 },
12541219
12551220 .Cr,
......@@ -1270,11 +1235,11 @@ pub const Tokenizer = struct {
12701235 .MacroString,
12711236 => result.id = .Invalid,
12721237
1273 .FloatExponentDigits => result.id = if (counter == 0) .Invalid else .{ .FloatLiteral = .None },
1238 .FloatExponentDigits => result.id = if (counter == 0) .Invalid else .{ .FloatLiteral = .none },
12741239
12751240 .FloatFraction,
12761241 .FloatFractionHex,
1277 => result.id = .{ .FloatLiteral = .None },
1242 => result.id = .{ .FloatLiteral = .none },
12781243
12791244 .IntegerLiteralOct,
12801245 .IntegerLiteralBinary,
......@@ -1282,13 +1247,13 @@ pub const Tokenizer = struct {
12821247 .IntegerLiteral,
12831248 .IntegerSuffix,
12841249 .Zero,
1285 => result.id = .{ .IntegerLiteral = .None },
1286 .IntegerSuffixU => result.id = .{ .IntegerLiteral = .U },
1287 .IntegerSuffixL => result.id = .{ .IntegerLiteral = .L },
1288 .IntegerSuffixLL => result.id = .{ .IntegerLiteral = .LL },
1289 .IntegerSuffixUL => result.id = .{ .IntegerLiteral = .LU },
1250 => result.id = .{ .IntegerLiteral = .none },
1251 .IntegerSuffixU => result.id = .{ .IntegerLiteral = .u },
1252 .IntegerSuffixL => result.id = .{ .IntegerLiteral = .l },
1253 .IntegerSuffixLL => result.id = .{ .IntegerLiteral = .ll },
1254 .IntegerSuffixUL => result.id = .{ .IntegerLiteral = .lu },
12901255
1291 .FloatSuffix => result.id = .{ .FloatLiteral = .None },
1256 .FloatSuffix => result.id = .{ .FloatLiteral = .none },
12921257 .Equal => result.id = .Equal,
12931258 .Bang => result.id = .Bang,
12941259 .Minus => result.id = .Minus,
......@@ -1466,7 +1431,7 @@ test "preprocessor keywords" {
14661431 .Hash,
14671432 .Identifier,
14681433 .AngleBracketLeft,
1469 .{ .IntegerLiteral = .None },
1434 .{ .IntegerLiteral = .none },
14701435 .Nl,
14711436 .Hash,
14721437 .Keyword_ifdef,
......@@ -1499,18 +1464,18 @@ test "line continuation" {
14991464 .Identifier,
15001465 .Identifier,
15011466 .Nl,
1502 .{ .StringLiteral = .None },
1467 .{ .StringLiteral = .none },
15031468 .Nl,
15041469 .Hash,
15051470 .Keyword_define,
1506 .{ .StringLiteral = .None },
1471 .{ .StringLiteral = .none },
15071472 .Nl,
1508 .{ .StringLiteral = .None },
1473 .{ .StringLiteral = .none },
15091474 .Nl,
15101475 .Hash,
15111476 .Keyword_define,
1512 .{ .StringLiteral = .None },
1513 .{ .StringLiteral = .None },
1477 .{ .StringLiteral = .none },
1478 .{ .StringLiteral = .none },
15141479 });
15151480}
15161481
......@@ -1527,23 +1492,23 @@ test "string prefix" {
15271492 \\L'foo'
15281493 \\
15291494 , &[_]Token.Id{
1530 .{ .StringLiteral = .None },
1495 .{ .StringLiteral = .none },
15311496 .Nl,
1532 .{ .StringLiteral = .Utf16 },
1497 .{ .StringLiteral = .utf_16 },
15331498 .Nl,
1534 .{ .StringLiteral = .Utf8 },
1499 .{ .StringLiteral = .utf_8 },
15351500 .Nl,
1536 .{ .StringLiteral = .Utf32 },
1501 .{ .StringLiteral = .utf_32 },
15371502 .Nl,
1538 .{ .StringLiteral = .Wide },
1503 .{ .StringLiteral = .wide },
15391504 .Nl,
1540 .{ .CharLiteral = .None },
1505 .{ .CharLiteral = .none },
15411506 .Nl,
1542 .{ .CharLiteral = .Utf16 },
1507 .{ .CharLiteral = .utf_16 },
15431508 .Nl,
1544 .{ .CharLiteral = .Utf32 },
1509 .{ .CharLiteral = .utf_32 },
15451510 .Nl,
1546 .{ .CharLiteral = .Wide },
1511 .{ .CharLiteral = .wide },
15471512 .Nl,
15481513 });
15491514}
......@@ -1555,33 +1520,29 @@ test "num suffixes" {
15551520 \\ 1u 1ul 1ull 1
15561521 \\
15571522 , &[_]Token.Id{
1558 .{ .FloatLiteral = .F },
1559 .{ .FloatLiteral = .L },
1560 .{ .FloatLiteral = .None },
1561 .{ .FloatLiteral = .None },
1562 .{ .FloatLiteral = .None },
1523 .{ .FloatLiteral = .f },
1524 .{ .FloatLiteral = .l },
1525 .{ .FloatLiteral = .none },
1526 .{ .FloatLiteral = .none },
1527 .{ .FloatLiteral = .none },
15631528 .Nl,
1564 .{ .IntegerLiteral = .L },
1565 .{ .IntegerLiteral = .LU },
1566 .{ .IntegerLiteral = .LL },
1567 .{ .IntegerLiteral = .LLU },
1568 .{ .IntegerLiteral = .None },
1529 .{ .IntegerLiteral = .l },
1530 .{ .IntegerLiteral = .lu },
1531 .{ .IntegerLiteral = .ll },
1532 .{ .IntegerLiteral = .llu },
1533 .{ .IntegerLiteral = .none },
15691534 .Nl,
1570 .{ .IntegerLiteral = .U },
1571 .{ .IntegerLiteral = .LU },
1572 .{ .IntegerLiteral = .LLU },
1573 .{ .IntegerLiteral = .None },
1535 .{ .IntegerLiteral = .u },
1536 .{ .IntegerLiteral = .lu },
1537 .{ .IntegerLiteral = .llu },
1538 .{ .IntegerLiteral = .none },
15741539 .Nl,
15751540 });
15761541}
15771542
15781543fn expectTokens(source: []const u8, expected_tokens: []const Token.Id) void {
15791544 var tokenizer = Tokenizer{
1580 .source = &Source{
1581 .buffer = source,
1582 .file_name = undefined,
1583 .tokens = undefined,
1584 },
1545 .buffer = source,
15851546 };
15861547 for (expected_tokens) |expected_token_id| {
15871548 const token = tokenizer.next();
src-self-hosted/translate_c.zig+222-208
......@@ -8,7 +8,6 @@ const Token = std.zig.Token;
88usingnamespace @import("clang.zig");
99const ctok = std.c.tokenizer;
1010const CToken = std.c.Token;
11const CTokenList = std.c.tokenizer.Source.TokenList;
1211const mem = std.mem;
1312const math = std.math;
1413
......@@ -5196,16 +5195,39 @@ pub fn freeErrors(errors: []ClangErrMsg) void {
51965195 ZigClangErrorMsg_delete(errors.ptr, errors.len);
51975196}
51985197
5198const CTokIterator = struct {
5199 source: []const u8,
5200 list: []const CToken,
5201 i: usize = 0,
5202
5203 fn peek(self: *CTokIterator) ?CToken.Id {
5204 if (self.i >= self.list.len) return null;
5205 return self.list[self.i + 1].id;
5206 }
5207
5208 fn next(self: *CTokIterator) ?CToken.Id {
5209 if (self.i >= self.list.len) return null;
5210 self.i += 1;
5211 return self.list[self.i].id;
5212 }
5213
5214 fn slice(self: *CTokIterator, index: usize) []const u8 {
5215 const tok = self.list[index];
5216 return self.source[tok.start..tok.end];
5217 }
5218};
5219
51995220fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
52005221 // TODO if we see #undef, delete it from the table
52015222 var it = ZigClangASTUnit_getLocalPreprocessingEntities_begin(unit);
52025223 const it_end = ZigClangASTUnit_getLocalPreprocessingEntities_end(unit);
5203 var tok_list = CTokenList.init(c.arena);
5224 var tok_list = std.ArrayList(CToken).init(c.gpa);
5225 defer tok_list.deinit();
52045226 const scope = c.global_scope;
52055227
52065228 while (it.I != it_end.I) : (it.I += 1) {
52075229 const entity = ZigClangPreprocessingRecord_iterator_deref(it);
5208 tok_list.shrink(0);
5230 tok_list.items.len = 0;
52095231 switch (ZigClangPreprocessedEntity_getKind(entity)) {
52105232 .MacroDefinitionKind => {
52115233 const macro = @ptrCast(*ZigClangMacroDefinitionRecord, entity);
......@@ -5223,38 +5245,34 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
52235245 const begin_c = ZigClangSourceManager_getCharacterData(c.source_manager, begin_loc);
52245246 const slice = begin_c[0..mem.len(begin_c)];
52255247
5226 tok_list.shrink(0);
52275248 var tokenizer = std.c.Tokenizer{
5228 .source = &std.c.tokenizer.Source{
5229 .buffer = slice,
5230 .file_name = undefined,
5231 .tokens = undefined,
5232 },
5249 .buffer = slice,
52335250 };
52345251 while (true) {
52355252 const tok = tokenizer.next();
52365253 switch (tok.id) {
52375254 .Nl, .Eof => {
5238 try tok_list.push(tok);
5255 try tok_list.append(tok);
52395256 break;
52405257 },
52415258 .LineComment, .MultiLineComment => continue,
52425259 else => {},
52435260 }
5244 try tok_list.push(tok);
5261 try tok_list.append(tok);
52455262 }
52465263
5247 var tok_it = tok_list.iterator(0);
5248 const first_tok = tok_it.next().?;
5249 assert(mem.eql(u8, slice[first_tok.start..first_tok.end], name));
5264 var tok_it = CTokIterator{
5265 .source = slice,
5266 .list = tok_list.items,
5267 };
5268 assert(mem.eql(u8, tok_it.slice(0), name));
52505269
52515270 var macro_fn = false;
5252 const next = tok_it.peek().?;
5253 switch (next.id) {
5271 switch (tok_it.peek().?) {
52545272 .Identifier => {
52555273 // if it equals itself, ignore. for example, from stdio.h:
52565274 // #define stdin stdin
5257 if (mem.eql(u8, name, slice[next.start..next.end])) {
5275 if (mem.eql(u8, name, tok_it.slice(1))) {
52585276 continue;
52595277 }
52605278 },
......@@ -5265,15 +5283,15 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
52655283 },
52665284 .LParen => {
52675285 // if the name is immediately followed by a '(' then it is a function
5268 macro_fn = first_tok.end == next.start;
5286 macro_fn = tok_it.list[0].end == tok_it.list[1].start;
52695287 },
52705288 else => {},
52715289 }
52725290
52735291 (if (macro_fn)
5274 transMacroFnDefine(c, &tok_it, slice, mangled_name, begin_loc)
5292 transMacroFnDefine(c, &tok_it, mangled_name, begin_loc)
52755293 else
5276 transMacroDefine(c, &tok_it, slice, mangled_name, begin_loc)) catch |err| switch (err) {
5294 transMacroDefine(c, &tok_it, mangled_name, begin_loc)) catch |err| switch (err) {
52775295 error.ParseError => continue,
52785296 error.OutOfMemory => |e| return e,
52795297 };
......@@ -5283,7 +5301,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
52835301 }
52845302}
52855303
5286fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
5304fn transMacroDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
52875305 const scope = &c.global_scope.base;
52885306
52895307 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
......@@ -5291,15 +5309,15 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n
52915309 const name_tok = try appendIdentifier(c, name);
52925310 const eq_token = try appendToken(c, .Equal, "=");
52935311
5294 const init_node = try parseCExpr(c, it, source, source_loc, scope);
5312 const init_node = try parseCExpr(c, it, source_loc, scope);
52955313 const last = it.next().?;
5296 if (last.id != .Eof and last.id != .Nl)
5314 if (last != .Eof and last != .Nl)
52975315 return failDecl(
52985316 c,
52995317 source_loc,
53005318 name,
53015319 "unable to translate C expr: unexpected token .{}",
5302 .{@tagName(last.id)},
5320 .{@tagName(last)},
53035321 );
53045322
53055323 const semicolon_token = try appendToken(c, .Semicolon, ";");
......@@ -5315,7 +5333,7 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n
53155333 _ = try c.global_scope.macro_table.put(name, &node.base);
53165334}
53175335
5318fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
5336fn transMacroFnDefine(c: *Context, it: *CTokIterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
53195337 var block_scope = try Scope.Block.init(c, &c.global_scope.base, null);
53205338 defer block_scope.deinit();
53215339 const scope = &block_scope.base;
......@@ -5326,7 +5344,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
53265344 const name_tok = try appendIdentifier(c, name);
53275345 _ = try appendToken(c, .LParen, "(");
53285346
5329 if (it.next().?.id != .LParen) {
5347 if (it.next().? != .LParen) {
53305348 return failDecl(
53315349 c,
53325350 source_loc,
......@@ -5340,8 +5358,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
53405358 defer fn_params.deinit();
53415359
53425360 while (true) {
5343 const param_tok = it.next().?;
5344 if (param_tok.id != .Identifier) {
5361 if (it.next().? != .Identifier) {
53455362 return failDecl(
53465363 c,
53475364 source_loc,
......@@ -5351,7 +5368,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
53515368 );
53525369 }
53535370
5354 const mangled_name = try block_scope.makeMangledName(c, source[param_tok.start..param_tok.end]);
5371 const mangled_name = try block_scope.makeMangledName(c, it.slice(it.i));
53555372 const param_name_tok = try appendIdentifier(c, mangled_name);
53565373 _ = try appendToken(c, .Colon, ":");
53575374
......@@ -5369,13 +5386,13 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
53695386 .param_type = .{ .any_type = &any_type.base },
53705387 };
53715388
5372 if (it.peek().?.id != .Comma)
5389 if (it.peek().? != .Comma)
53735390 break;
53745391 _ = it.next();
53755392 _ = try appendToken(c, .Comma, ",");
53765393 }
53775394
5378 if (it.next().?.id != .RParen) {
5395 if (it.next().? != .RParen) {
53795396 return failDecl(
53805397 c,
53815398 source_loc,
......@@ -5390,15 +5407,15 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
53905407 const type_of = try c.createBuiltinCall("@TypeOf", 1);
53915408
53925409 const return_kw = try appendToken(c, .Keyword_return, "return");
5393 const expr = try parseCExpr(c, it, source, source_loc, scope);
5410 const expr = try parseCExpr(c, it, source_loc, scope);
53945411 const last = it.next().?;
5395 if (last.id != .Eof and last.id != .Nl)
5412 if (last != .Eof and last != .Nl)
53965413 return failDecl(
53975414 c,
53985415 source_loc,
53995416 name,
54005417 "unable to translate C expr: unexpected token .{}",
5401 .{@tagName(last.id)},
5418 .{@tagName(last)},
54025419 );
54035420 _ = try appendToken(c, .Semicolon, ";");
54045421 const type_of_arg = if (expr.tag != .Block) expr else blk: {
......@@ -5435,28 +5452,27 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
54355452
54365453const ParseError = Error || error{ParseError};
54375454
5438fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
5439 const node = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5440 switch (it.next().?.id) {
5455fn parseCExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
5456 const node = try parseCPrefixOpExpr(c, it, source_loc, scope);
5457 switch (it.next().?) {
54415458 .QuestionMark => {
54425459 // must come immediately after expr
54435460 _ = try appendToken(c, .RParen, ")");
54445461 const if_node = try transCreateNodeIf(c);
54455462 if_node.condition = node;
5446 if_node.body = try parseCPrimaryExpr(c, it, source, source_loc, scope);
5447 if (it.next().?.id != .Colon) {
5448 const first_tok = it.list.at(0);
5463 if_node.body = try parseCPrimaryExpr(c, it, source_loc, scope);
5464 if (it.next().? != .Colon) {
54495465 try failDecl(
54505466 c,
54515467 source_loc,
5452 source[first_tok.start..first_tok.end],
5468 it.slice(0),
54535469 "unable to translate C expr: expected ':'",
54545470 .{},
54555471 );
54565472 return error.ParseError;
54575473 }
54585474 if_node.@"else" = try transCreateNodeElse(c);
5459 if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source, source_loc, scope);
5475 if_node.@"else".?.body = try parseCPrimaryExpr(c, it, source_loc, scope);
54605476 return &if_node.base;
54615477 },
54625478 .Comma => {
......@@ -5479,10 +5495,10 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
54795495 };
54805496 try block_scope.statements.append(&op_node.base);
54815497
5482 last = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5498 last = try parseCPrefixOpExpr(c, it, source_loc, scope);
54835499 _ = try appendToken(c, .Semicolon, ";");
5484 if (it.next().?.id != .Comma) {
5485 _ = it.prev();
5500 if (it.next().? != .Comma) {
5501 it.i -= 1;
54865502 break;
54875503 }
54885504 }
......@@ -5493,70 +5509,74 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
54935509 return &block_node.base;
54945510 },
54955511 else => {
5496 _ = it.prev();
5512 it.i -= 1;
54975513 return node;
54985514 },
54995515 }
55005516}
55015517
5502fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigClangSourceLocation) ParseError!*ast.Node {
5503 var lit_bytes = source[tok.start..tok.end];
5518fn parseCNumLit(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation) ParseError!*ast.Node {
5519 var lit_bytes = it.slice(it.i);
55045520
5505 if (tok.id == .IntegerLiteral) {
5506 if (lit_bytes.len > 2 and lit_bytes[0] == '0') {
5507 switch (lit_bytes[1]) {
5508 '0'...'7' => {
5509 // Octal
5510 lit_bytes = try std.fmt.allocPrint(c.arena, "0o{}", .{lit_bytes});
5511 },
5512 'X' => {
5513 // Hexadecimal with capital X, valid in C but not in Zig
5514 lit_bytes = try std.fmt.allocPrint(c.arena, "0x{}", .{lit_bytes[2..]});
5515 },
5516 else => {},
5521 switch (it.list[it.i].id) {
5522 .IntegerLiteral => |suffix| {
5523 if (lit_bytes.len > 2 and lit_bytes[0] == '0') {
5524 switch (lit_bytes[1]) {
5525 '0'...'7' => {
5526 // Octal
5527 lit_bytes = try std.fmt.allocPrint(c.arena, "0o{}", .{lit_bytes});
5528 },
5529 'X' => {
5530 // Hexadecimal with capital X, valid in C but not in Zig
5531 lit_bytes = try std.fmt.allocPrint(c.arena, "0x{}", .{lit_bytes[2..]});
5532 },
5533 else => {},
5534 }
55175535 }
5518 }
55195536
5520 if (tok.id.IntegerLiteral == .None) {
5521 return transCreateNodeInt(c, lit_bytes);
5522 }
5537 if (suffix == .none) {
5538 return transCreateNodeInt(c, lit_bytes);
5539 }
55235540
5524 const cast_node = try c.createBuiltinCall("@as", 2);
5525 cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) {
5526 .U => "c_uint",
5527 .L => "c_long",
5528 .LU => "c_ulong",
5529 .LL => "c_longlong",
5530 .LLU => "c_ulonglong",
5531 else => unreachable,
5532 });
5533 lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) {
5534 .U, .L => @as(u8, 1),
5535 .LU, .LL => 2,
5536 .LLU => 3,
5537 else => unreachable,
5538 }];
5539 _ = try appendToken(c, .Comma, ",");
5540 cast_node.params()[1] = try transCreateNodeInt(c, lit_bytes);
5541 cast_node.rparen_token = try appendToken(c, .RParen, ")");
5542 return &cast_node.base;
5543 } else if (tok.id == .FloatLiteral) {
5544 if (lit_bytes[0] == '.')
5545 lit_bytes = try std.fmt.allocPrint(c.arena, "0{}", .{lit_bytes});
5546 if (tok.id.FloatLiteral == .None) {
5547 return transCreateNodeFloat(c, lit_bytes);
5548 }
5549 const cast_node = try c.createBuiltinCall("@as", 2);
5550 cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) {
5551 .F => "f32",
5552 .L => "c_longdouble",
5553 else => unreachable,
5554 });
5555 _ = try appendToken(c, .Comma, ",");
5556 cast_node.params()[1] = try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1]);
5557 cast_node.rparen_token = try appendToken(c, .RParen, ")");
5558 return &cast_node.base;
5559 } else unreachable;
5541 const cast_node = try c.createBuiltinCall("@as", 2);
5542 cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (suffix) {
5543 .u => "c_uint",
5544 .l => "c_long",
5545 .lu => "c_ulong",
5546 .ll => "c_longlong",
5547 .llu => "c_ulonglong",
5548 else => unreachable,
5549 });
5550 lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (suffix) {
5551 .u, .l => @as(u8, 1),
5552 .lu, .ll => 2,
5553 .llu => 3,
5554 else => unreachable,
5555 }];
5556 _ = try appendToken(c, .Comma, ",");
5557 cast_node.params()[1] = try transCreateNodeInt(c, lit_bytes);
5558 cast_node.rparen_token = try appendToken(c, .RParen, ")");
5559 return &cast_node.base;
5560 },
5561 .FloatLiteral => |suffix| {
5562 if (lit_bytes[0] == '.')
5563 lit_bytes = try std.fmt.allocPrint(c.arena, "0{}", .{lit_bytes});
5564 if (suffix == .none) {
5565 return transCreateNodeFloat(c, lit_bytes);
5566 }
5567 const cast_node = try c.createBuiltinCall("@as", 2);
5568 cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (suffix) {
5569 .f => "f32",
5570 .l => "c_longdouble",
5571 else => unreachable,
5572 });
5573 _ = try appendToken(c, .Comma, ",");
5574 cast_node.params()[1] = try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1]);
5575 cast_node.rparen_token = try appendToken(c, .RParen, ")");
5576 return &cast_node.base;
5577 },
5578 else => unreachable,
5579 }
55605580}
55615581
55625582fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ![]const u8 {
......@@ -5719,13 +5739,13 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
57195739 return bytes[0..i];
57205740}
57215741
5722fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
5742fn parseCPrimaryExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
57235743 const tok = it.next().?;
5724 switch (tok.id) {
5744 const slice = it.slice(it.i);
5745 switch (tok) {
57255746 .CharLiteral => {
5726 const first_tok = it.list.at(0);
5727 if (source[tok.start] != '\'' or source[tok.start + 1] == '\\' or tok.end - tok.start == 3) {
5728 const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, source[tok.start..tok.end], source[first_tok.start..first_tok.end], source_loc));
5747 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
5748 const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, slice, it.slice(0), source_loc));
57295749 const node = try c.arena.create(ast.Node.OneToken);
57305750 node.* = .{
57315751 .base = .{ .tag = .CharLiteral },
......@@ -5733,7 +5753,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57335753 };
57345754 return &node.base;
57355755 } else {
5736 const token = try appendTokenFmt(c, .IntegerLiteral, "0x{x}", .{source[tok.start + 1 .. tok.end - 1]});
5756 const token = try appendTokenFmt(c, .IntegerLiteral, "0x{x}", .{slice[1 .. slice.len - 1]});
57375757 const node = try c.arena.create(ast.Node.OneToken);
57385758 node.* = .{
57395759 .base = .{ .tag = .IntegerLiteral },
......@@ -5743,8 +5763,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57435763 }
57445764 },
57455765 .StringLiteral => {
5746 const first_tok = it.list.at(0);
5747 const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, source[tok.start..tok.end], source[first_tok.start..first_tok.end], source_loc));
5766 const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, slice, it.slice(0), source_loc));
57485767 const node = try c.arena.create(ast.Node.OneToken);
57495768 node.* = .{
57505769 .base = .{ .tag = .StringLiteral },
......@@ -5753,7 +5772,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57535772 return &node.base;
57545773 },
57555774 .IntegerLiteral, .FloatLiteral => {
5756 return parseCNumLit(c, tok, source, source_loc);
5775 return parseCNumLit(c, it, source_loc);
57575776 },
57585777 // eventually this will be replaced by std.c.parse which will handle these correctly
57595778 .Keyword_void => return transCreateNodeIdentifierUnchecked(c, "c_void"),
......@@ -5763,37 +5782,50 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57635782 .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_int"),
57645783 .Keyword_float => return transCreateNodeIdentifierUnchecked(c, "f32"),
57655784 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
5766 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "c_char"),
5767 .Keyword_unsigned => if (it.next()) |t| {
5768 switch (t.id) {
5769 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_ushort"),
5770 .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_uint"),
5771 .Keyword_long => if (it.peek() != null and it.peek().?.id == .Keyword_long) {
5772 _ = it.next();
5773 return transCreateNodeIdentifierUnchecked(c, "c_ulonglong");
5774 } else return transCreateNodeIdentifierUnchecked(c, "c_ulong"),
5775 else => {
5776 _ = it.prev();
5777 return transCreateNodeIdentifierUnchecked(c, "c_uint");
5778 },
5779 }
5785 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "u8"),
5786 .Keyword_unsigned => if (it.next()) |t| switch (t) {
5787 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "u8"),
5788 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_ushort"),
5789 .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_uint"),
5790 .Keyword_long => if (it.peek() != null and it.peek().? == .Keyword_long) {
5791 _ = it.next();
5792 return transCreateNodeIdentifierUnchecked(c, "c_ulonglong");
5793 } else return transCreateNodeIdentifierUnchecked(c, "c_ulong"),
5794 else => {
5795 it.i -= 1;
5796 return transCreateNodeIdentifierUnchecked(c, "c_uint");
5797 },
57805798 } else {
57815799 return transCreateNodeIdentifierUnchecked(c, "c_uint");
57825800 },
5801 .Keyword_signed => if (it.next()) |t| switch (t) {
5802 .Keyword_char => return transCreateNodeIdentifierUnchecked(c, "i8"),
5803 .Keyword_short => return transCreateNodeIdentifierUnchecked(c, "c_short"),
5804 .Keyword_int => return transCreateNodeIdentifierUnchecked(c, "c_int"),
5805 .Keyword_long => if (it.peek() != null and it.peek().? == .Keyword_long) {
5806 _ = it.next();
5807 return transCreateNodeIdentifierUnchecked(c, "c_longlong");
5808 } else return transCreateNodeIdentifierUnchecked(c, "c_long"),
5809 else => {
5810 it.i -= 1;
5811 return transCreateNodeIdentifierUnchecked(c, "c_int");
5812 },
5813 } else {
5814 return transCreateNodeIdentifierUnchecked(c, "c_int");
5815 },
57835816 .Identifier => {
5784 const mangled_name = scope.getAlias(source[tok.start..tok.end]);
5817 const mangled_name = scope.getAlias(it.slice(it.i));
57855818 return transCreateNodeIdentifier(c, mangled_name);
57865819 },
57875820 .LParen => {
5788 const inner_node = try parseCExpr(c, it, source, source_loc, scope);
5821 const inner_node = try parseCExpr(c, it, source_loc, scope);
57895822
5790 const next_id = it.next().?.id;
5823 const next_id = it.next().?;
57915824 if (next_id != .RParen) {
5792 const first_tok = it.list.at(0);
57935825 try failDecl(
57945826 c,
57955827 source_loc,
5796 source[first_tok.start..first_tok.end],
5828 it.slice(0),
57975829 "unable to translate C expr: expected ')'' instead got: {}",
57985830 .{@tagName(next_id)},
57995831 );
......@@ -5801,7 +5833,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
58015833 }
58025834 var saw_l_paren = false;
58035835 var saw_integer_literal = false;
5804 switch (it.peek().?.id) {
5836 switch (it.peek().?) {
58055837 // (type)(to_cast)
58065838 .LParen => {
58075839 saw_l_paren = true;
......@@ -5819,14 +5851,13 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
58195851 // hack to get zig fmt to render a comma in builtin calls
58205852 _ = try appendToken(c, .Comma, ",");
58215853
5822 const node_to_cast = try parseCExpr(c, it, source, source_loc, scope);
5854 const node_to_cast = try parseCExpr(c, it, source_loc, scope);
58235855
5824 if (saw_l_paren and it.next().?.id != .RParen) {
5825 const first_tok = it.list.at(0);
5856 if (saw_l_paren and it.next().? != .RParen) {
58265857 try failDecl(
58275858 c,
58285859 source_loc,
5829 source[first_tok.start..first_tok.end],
5860 it.slice(0),
58305861 "unable to translate C expr: expected ')''",
58315862 .{},
58325863 );
......@@ -5857,13 +5888,12 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
58575888 return &group_node.base;
58585889 },
58595890 else => {
5860 const first_tok = it.list.at(0);
58615891 try failDecl(
58625892 c,
58635893 source_loc,
5864 source[first_tok.start..first_tok.end],
5894 it.slice(0),
58655895 "unable to translate C expr: unexpected token .{}",
5866 .{@tagName(tok.id)},
5896 .{@tagName(tok)},
58675897 );
58685898 return error.ParseError;
58695899 },
......@@ -5971,61 +6001,52 @@ fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node {
59716001 return &group_node.base;
59726002}
59736003
5974fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
5975 var node = try parseCPrimaryExpr(c, it, source, source_loc, scope);
6004fn parseCSuffixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
6005 var node = try parseCPrimaryExpr(c, it, source_loc, scope);
59766006 while (true) {
5977 const tok = it.next().?;
59786007 var op_token: ast.TokenIndex = undefined;
59796008 var op_id: ast.Node.Tag = undefined;
59806009 var bool_op = false;
5981 switch (tok.id) {
6010 switch (it.next().?) {
59826011 .Period => {
5983 const name_tok = it.next().?;
5984 if (name_tok.id != .Identifier) {
5985 const first_tok = it.list.at(0);
6012 if (it.next().? != .Identifier) {
59866013 try failDecl(
59876014 c,
59886015 source_loc,
5989 source[first_tok.start..first_tok.end],
6016 it.slice(0),
59906017 "unable to translate C expr: expected identifier",
59916018 .{},
59926019 );
59936020 return error.ParseError;
59946021 }
59956022
5996 node = try transCreateNodeFieldAccess(c, node, source[name_tok.start..name_tok.end]);
6023 node = try transCreateNodeFieldAccess(c, node, it.slice(it.i));
59976024 continue;
59986025 },
59996026 .Arrow => {
6000 const name_tok = it.next().?;
6001 if (name_tok.id != .Identifier) {
6002 const first_tok = it.list.at(0);
6027 if (it.next().? != .Identifier) {
60036028 try failDecl(
60046029 c,
60056030 source_loc,
6006 source[first_tok.start..first_tok.end],
6031 it.slice(0),
60076032 "unable to translate C expr: expected identifier",
60086033 .{},
60096034 );
60106035 return error.ParseError;
60116036 }
60126037 const deref = try transCreateNodePtrDeref(c, node);
6013 node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]);
6038 node = try transCreateNodeFieldAccess(c, deref, it.slice(it.i));
60146039 continue;
60156040 },
60166041 .Asterisk => {
6017 if (it.peek().?.id == .RParen) {
6042 if (it.peek().? == .RParen) {
60186043 // type *)
60196044
60206045 // hack to get zig fmt to render a comma in builtin calls
60216046 _ = try appendToken(c, .Comma, ",");
60226047
6023 // * token
6024 _ = it.prev();
60256048 // last token of `node`
6026 const prev_id = it.prev().?.id;
6027 _ = it.next();
6028 _ = it.next();
6049 const prev_id = it.list[it.i - 1].id;
60296050
60306051 if (prev_id == .Keyword_void) {
60316052 const ptr = try transCreateNodePtrType(c, false, false, .Asterisk);
......@@ -6096,15 +6117,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
60966117 },
60976118 .LBracket => {
60986119 const arr_node = try transCreateNodeArrayAccess(c, node);
6099 arr_node.index_expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6120 arr_node.index_expr = try parseCPrefixOpExpr(c, it, source_loc, scope);
61006121 arr_node.rtoken = try appendToken(c, .RBracket, "]");
61016122 node = &arr_node.base;
6102 if (it.next().?.id != .RBracket) {
6103 const first_tok = it.list.at(0);
6123 if (it.next().? != .RBracket) {
61046124 try failDecl(
61056125 c,
61066126 source_loc,
6107 source[first_tok.start..first_tok.end],
6127 it.slice(0),
61086128 "unable to translate C expr: expected ']'",
61096129 .{},
61106130 );
......@@ -6117,23 +6137,21 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
61176137 var call_params = std.ArrayList(*ast.Node).init(c.gpa);
61186138 defer call_params.deinit();
61196139 while (true) {
6120 const arg = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6140 const arg = try parseCPrefixOpExpr(c, it, source_loc, scope);
61216141 try call_params.append(arg);
6122 const next = it.next().?;
6123 if (next.id == .Comma)
6124 _ = try appendToken(c, .Comma, ",")
6125 else if (next.id == .RParen)
6126 break
6127 else {
6128 const first_tok = it.list.at(0);
6129 try failDecl(
6130 c,
6131 source_loc,
6132 source[first_tok.start..first_tok.end],
6133 "unable to translate C expr: expected ',' or ')'",
6134 .{},
6135 );
6136 return error.ParseError;
6142 switch (it.next().?) {
6143 .Comma => _ = try appendToken(c, .Comma, ","),
6144 .RParen => break,
6145 else => {
6146 try failDecl(
6147 c,
6148 source_loc,
6149 it.slice(0),
6150 "unable to translate C expr: expected ',' or ')'",
6151 .{},
6152 );
6153 return error.ParseError;
6154 },
61376155 }
61386156 }
61396157 const call_node = try ast.Node.Call.alloc(c.arena, call_params.items.len);
......@@ -6158,23 +6176,21 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
61586176 defer init_vals.deinit();
61596177
61606178 while (true) {
6161 const val = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6179 const val = try parseCPrefixOpExpr(c, it, source_loc, scope);
61626180 try init_vals.append(val);
6163 const next = it.next().?;
6164 if (next.id == .Comma)
6165 _ = try appendToken(c, .Comma, ",")
6166 else if (next.id == .RBrace)
6167 break
6168 else {
6169 const first_tok = it.list.at(0);
6170 try failDecl(
6171 c,
6172 source_loc,
6173 source[first_tok.start..first_tok.end],
6174 "unable to translate C expr: expected ',' or '}}'",
6175 .{},
6176 );
6177 return error.ParseError;
6181 switch (it.next().?) {
6182 .Comma => _ = try appendToken(c, .Comma, ","),
6183 .RBrace => break,
6184 else => {
6185 try failDecl(
6186 c,
6187 source_loc,
6188 it.slice(0),
6189 "unable to translate C expr: expected ',' or '}}'",
6190 .{},
6191 );
6192 return error.ParseError;
6193 },
61786194 }
61796195 }
61806196 const tuple_node = try ast.Node.StructInitializerDot.alloc(c.arena, init_vals.items.len);
......@@ -6221,22 +6237,22 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
62216237 op_id = .ArrayCat;
62226238 op_token = try appendToken(c, .PlusPlus, "++");
62236239
6224 _ = it.prev();
6240 it.i -= 1;
62256241 },
62266242 .Identifier => {
62276243 op_id = .ArrayCat;
62286244 op_token = try appendToken(c, .PlusPlus, "++");
62296245
6230 _ = it.prev();
6246 it.i -= 1;
62316247 },
62326248 else => {
6233 _ = it.prev();
6249 it.i -= 1;
62346250 return node;
62356251 },
62366252 }
62376253 const cast_fn = if (bool_op) macroIntToBool else macroBoolToInt;
62386254 const lhs_node = try cast_fn(c, node);
6239 const rhs_node = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6255 const rhs_node = try parseCPrefixOpExpr(c, it, source_loc, scope);
62406256 const op_node = try c.arena.create(ast.Node.SimpleInfixOp);
62416257 op_node.* = .{
62426258 .base = .{ .tag = op_id },
......@@ -6248,38 +6264,36 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
62486264 }
62496265}
62506266
6251fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
6252 const op_tok = it.next().?;
6253
6254 switch (op_tok.id) {
6267fn parseCPrefixOpExpr(c: *Context, it: *CTokIterator, source_loc: ZigClangSourceLocation, scope: *Scope) ParseError!*ast.Node {
6268 switch (it.next().?) {
62556269 .Bang => {
62566270 const node = try transCreateNodeSimplePrefixOp(c, .BoolNot, .Bang, "!");
6257 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6271 node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
62586272 return &node.base;
62596273 },
62606274 .Minus => {
62616275 const node = try transCreateNodeSimplePrefixOp(c, .Negation, .Minus, "-");
6262 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6276 node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
62636277 return &node.base;
62646278 },
6265 .Plus => return try parseCPrefixOpExpr(c, it, source, source_loc, scope),
6279 .Plus => return try parseCPrefixOpExpr(c, it, source_loc, scope),
62666280 .Tilde => {
62676281 const node = try transCreateNodeSimplePrefixOp(c, .BitNot, .Tilde, "~");
6268 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6282 node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
62696283 return &node.base;
62706284 },
62716285 .Asterisk => {
6272 const node = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6286 const node = try parseCPrefixOpExpr(c, it, source_loc, scope);
62736287 return try transCreateNodePtrDeref(c, node);
62746288 },
62756289 .Ampersand => {
62766290 const node = try transCreateNodeSimplePrefixOp(c, .AddressOf, .Ampersand, "&");
6277 node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
6291 node.rhs = try parseCPrefixOpExpr(c, it, source_loc, scope);
62786292 return &node.base;
62796293 },
62806294 else => {
6281 _ = it.prev();
6282 return try parseCSuffixOpExpr(c, it, source, source_loc, scope);
6295 it.i -= 1;
6296 return try parseCSuffixOpExpr(c, it, source_loc, scope);
62836297 },
62846298 }
62856299}