authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-23 21:58:28-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-23 22:21:25-05:00
log00878a15d703a668970c7869276d33b21464714a
treed84e68f83d2b484e04494e3b36d76a6beb34e443
parentf25182f46dd672eb5b10533c67ed462a3e5df999
signaturelock-open Commit is signed but in an unrecognized format.

zig fmt: support sentinel-terminated pointer syntax


5 files changed, 202 insertions(+), 192 deletions(-)

lib/std/zig/ast.zig+16-11
......@@ -137,7 +137,6 @@ pub const Error = union(enum) {
137137 ExpectedCallOrFnProto: ExpectedCallOrFnProto,
138138 ExpectedSliceOrRBracket: ExpectedSliceOrRBracket,
139139 ExtraAlignQualifier: ExtraAlignQualifier,
140 ExtraNullQualifier: ExtraNullQualifier,
141140 ExtraConstQualifier: ExtraConstQualifier,
142141 ExtraVolatileQualifier: ExtraVolatileQualifier,
143142 ExtraAllowZeroQualifier: ExtraAllowZeroQualifier,
......@@ -185,7 +184,6 @@ pub const Error = union(enum) {
185184 .ExpectedCallOrFnProto => |*x| return x.render(tokens, stream),
186185 .ExpectedSliceOrRBracket => |*x| return x.render(tokens, stream),
187186 .ExtraAlignQualifier => |*x| return x.render(tokens, stream),
188 .ExtraNullQualifier => |*x| return x.render(tokens, stream),
189187 .ExtraConstQualifier => |*x| return x.render(tokens, stream),
190188 .ExtraVolatileQualifier => |*x| return x.render(tokens, stream),
191189 .ExtraAllowZeroQualifier => |*x| return x.render(tokens, stream),
......@@ -235,7 +233,6 @@ pub const Error = union(enum) {
235233 .ExpectedCallOrFnProto => |x| return x.node.firstToken(),
236234 .ExpectedSliceOrRBracket => |x| return x.token,
237235 .ExtraAlignQualifier => |x| return x.token,
238 .ExtraNullQualifier => |x| return x.token,
239236 .ExtraConstQualifier => |x| return x.token,
240237 .ExtraVolatileQualifier => |x| return x.token,
241238 .ExtraAllowZeroQualifier => |x| return x.token,
......@@ -296,7 +293,6 @@ pub const Error = union(enum) {
296293 pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub");
297294 pub const UnattachedDocComment = SimpleError("Unattached documentation comment");
298295 pub const ExtraAlignQualifier = SimpleError("Extra align qualifier");
299 pub const ExtraNullQualifier = SimpleError("Extra null qualifier");
300296 pub const ExtraConstQualifier = SimpleError("Extra const qualifier");
301297 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
302298 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
......@@ -1535,7 +1531,7 @@ pub const Node = struct {
15351531 };
15361532
15371533 pub const PrefixOp = struct {
1538 base: Node,
1534 base: Node = Node{ .id = .PrefixOp },
15391535 op_token: TokenIndex,
15401536 op: Op,
15411537 rhs: *Node,
......@@ -1558,15 +1554,15 @@ pub const Node = struct {
15581554
15591555 pub const ArrayInfo = struct {
15601556 len_expr: *Node,
1561 null_token: ?TokenIndex,
1557 sentinel: ?*Node,
15621558 };
15631559
15641560 pub const PtrInfo = struct {
1565 allowzero_token: ?TokenIndex,
1566 align_info: ?Align,
1567 const_token: ?TokenIndex,
1568 volatile_token: ?TokenIndex,
1569 null_token: ?TokenIndex,
1561 allowzero_token: ?TokenIndex = null,
1562 align_info: ?Align = null,
1563 const_token: ?TokenIndex = null,
1564 volatile_token: ?TokenIndex = null,
1565 sentinel: ?*Node = null,
15701566
15711567 pub const Align = struct {
15721568 node: *Node,
......@@ -1585,6 +1581,11 @@ pub const Node = struct {
15851581 switch (self.op) {
15861582 // TODO https://github.com/ziglang/zig/issues/1107
15871583 Op.SliceType => |addr_of_info| {
1584 if (addr_of_info.sentinel) |sentinel| {
1585 if (i < 1) return sentinel;
1586 i -= 1;
1587 }
1588
15881589 if (addr_of_info.align_info) |align_info| {
15891590 if (i < 1) return align_info.node;
15901591 i -= 1;
......@@ -1601,6 +1602,10 @@ pub const Node = struct {
16011602 Op.ArrayType => |array_info| {
16021603 if (i < 1) return array_info.len_expr;
16031604 i -= 1;
1605 if (array_info.sentinel) |sentinel| {
1606 if (i < 1) return sentinel;
1607 i -= 1;
1608 }
16041609 },
16051610
16061611 Op.AddressOf,
lib/std/zig/parse.zig+127-109
......@@ -2246,73 +2246,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
22462246 return &node.base;
22472247 }
22482248
2249 if (try parseArrayTypeStart(arena, it, tree)) |node| {
2250 switch (node.cast(Node.PrefixOp).?.op) {
2251 .ArrayType => {},
2252 .SliceType => |*slice_type| {
2253 // Collect pointer qualifiers in any order, but disallow duplicates
2254 while (true) {
2255 if (eatToken(it, .Keyword_null)) |null_token| {
2256 if (slice_type.null_token != null) {
2257 try tree.errors.push(AstError{
2258 .ExtraNullQualifier = AstError.ExtraNullQualifier{ .token = it.index },
2259 });
2260 return error.ParseError;
2261 }
2262 slice_type.null_token = null_token;
2263 continue;
2264 }
2265 if (try parseByteAlign(arena, it, tree)) |align_expr| {
2266 if (slice_type.align_info != null) {
2267 try tree.errors.push(AstError{
2268 .ExtraAlignQualifier = AstError.ExtraAlignQualifier{ .token = it.index },
2269 });
2270 return error.ParseError;
2271 }
2272 slice_type.align_info = Node.PrefixOp.PtrInfo.Align{
2273 .node = align_expr,
2274 .bit_range = null,
2275 };
2276 continue;
2277 }
2278 if (eatToken(it, .Keyword_const)) |const_token| {
2279 if (slice_type.const_token != null) {
2280 try tree.errors.push(AstError{
2281 .ExtraConstQualifier = AstError.ExtraConstQualifier{ .token = it.index },
2282 });
2283 return error.ParseError;
2284 }
2285 slice_type.const_token = const_token;
2286 continue;
2287 }
2288 if (eatToken(it, .Keyword_volatile)) |volatile_token| {
2289 if (slice_type.volatile_token != null) {
2290 try tree.errors.push(AstError{
2291 .ExtraVolatileQualifier = AstError.ExtraVolatileQualifier{ .token = it.index },
2292 });
2293 return error.ParseError;
2294 }
2295 slice_type.volatile_token = volatile_token;
2296 continue;
2297 }
2298 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
2299 if (slice_type.allowzero_token != null) {
2300 try tree.errors.push(AstError{
2301 .ExtraAllowZeroQualifier = AstError.ExtraAllowZeroQualifier{ .token = it.index },
2302 });
2303 return error.ParseError;
2304 }
2305 slice_type.allowzero_token = allowzero_token;
2306 continue;
2307 }
2308 break;
2309 }
2310 },
2311 else => unreachable,
2312 }
2313 return node;
2314 }
2315
23162249 if (try parsePtrTypeStart(arena, it, tree)) |node| {
23172250 // If the token encountered was **, there will be two nodes instead of one.
23182251 // The attributes should be applied to the rightmost operator.
......@@ -2323,10 +2256,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
23232256 &prefix_op.op.PtrType;
23242257
23252258 while (true) {
2326 if (eatToken(it, .Keyword_null)) |null_token| {
2327 ptr_info.null_token = null_token;
2328 continue;
2329 }
23302259 if (eatToken(it, .Keyword_align)) |align_token| {
23312260 const lparen = try expectToken(it, tree, .LParen);
23322261 const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{
......@@ -2375,6 +2304,63 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
23752304 return node;
23762305 }
23772306
2307 if (try parseArrayTypeStart(arena, it, tree)) |node| {
2308 switch (node.cast(Node.PrefixOp).?.op) {
2309 .ArrayType => {},
2310 .SliceType => |*slice_type| {
2311 // Collect pointer qualifiers in any order, but disallow duplicates
2312 while (true) {
2313 if (try parseByteAlign(arena, it, tree)) |align_expr| {
2314 if (slice_type.align_info != null) {
2315 try tree.errors.push(AstError{
2316 .ExtraAlignQualifier = AstError.ExtraAlignQualifier{ .token = it.index },
2317 });
2318 return error.ParseError;
2319 }
2320 slice_type.align_info = Node.PrefixOp.PtrInfo.Align{
2321 .node = align_expr,
2322 .bit_range = null,
2323 };
2324 continue;
2325 }
2326 if (eatToken(it, .Keyword_const)) |const_token| {
2327 if (slice_type.const_token != null) {
2328 try tree.errors.push(AstError{
2329 .ExtraConstQualifier = AstError.ExtraConstQualifier{ .token = it.index },
2330 });
2331 return error.ParseError;
2332 }
2333 slice_type.const_token = const_token;
2334 continue;
2335 }
2336 if (eatToken(it, .Keyword_volatile)) |volatile_token| {
2337 if (slice_type.volatile_token != null) {
2338 try tree.errors.push(AstError{
2339 .ExtraVolatileQualifier = AstError.ExtraVolatileQualifier{ .token = it.index },
2340 });
2341 return error.ParseError;
2342 }
2343 slice_type.volatile_token = volatile_token;
2344 continue;
2345 }
2346 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
2347 if (slice_type.allowzero_token != null) {
2348 try tree.errors.push(AstError{
2349 .ExtraAllowZeroQualifier = AstError.ExtraAllowZeroQualifier{ .token = it.index },
2350 });
2351 return error.ParseError;
2352 }
2353 slice_type.allowzero_token = allowzero_token;
2354 continue;
2355 }
2356 break;
2357 }
2358 },
2359 else => unreachable,
2360 }
2361 return node;
2362 }
2363
23782364 return null;
23792365}
23802366
......@@ -2473,14 +2459,19 @@ const AnnotatedParamList = struct {
24732459fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
24742460 const lbracket = eatToken(it, .LBracket) orelse return null;
24752461 const expr = try parseExpr(arena, it, tree);
2462 const sentinel = if (eatToken(it, .Colon)) |_|
2463 try expectNode(arena, it, tree, parseExpr, AstError{
2464 .ExpectedExpr = .{ .token = it.index },
2465 })
2466 else
2467 null;
24762468 const rbracket = try expectToken(it, tree, .RBracket);
2477 const null_token = eatToken(it, .Keyword_null);
24782469
24792470 const op = if (expr) |len_expr|
24802471 Node.PrefixOp.Op{
24812472 .ArrayType = .{
24822473 .len_expr = len_expr,
2483 .null_token = null_token,
2474 .sentinel = sentinel,
24842475 },
24852476 }
24862477 else
......@@ -2490,7 +2481,7 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
24902481 .align_info = null,
24912482 .const_token = null,
24922483 .volatile_token = null,
2493 .null_token = null,
2484 .sentinel = sentinel,
24942485 },
24952486 };
24962487
......@@ -2510,49 +2501,76 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
25102501/// / PTRUNKNOWN
25112502/// / PTRC
25122503fn parsePtrTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
2513 const token = eatAnnotatedToken(it, .Asterisk) orelse
2514 eatAnnotatedToken(it, .AsteriskAsterisk) orelse
2515 eatAnnotatedToken(it, .BracketStarBracket) orelse
2516 eatAnnotatedToken(it, .BracketStarCBracket) orelse
2517 return null;
2504 if (eatToken(it, .Asterisk)) |asterisk| {
2505 const sentinel = if (eatToken(it, .Colon)) |_|
2506 try expectNode(arena, it, tree, parseExpr, AstError{
2507 .ExpectedExpr = .{ .token = it.index },
2508 })
2509 else
2510 null;
2511 const node = try arena.create(Node.PrefixOp);
2512 node.* = .{
2513 .op_token = asterisk,
2514 .op = .{ .PtrType = .{ .sentinel = sentinel } },
2515 .rhs = undefined, // set by caller
2516 };
2517 return &node.base;
2518 }
25182519
2519 const node = try arena.create(Node.PrefixOp);
2520 node.* = Node.PrefixOp{
2521 .base = Node{ .id = .PrefixOp },
2522 .op_token = token.index,
2523 .op = Node.PrefixOp.Op{
2524 .PtrType = Node.PrefixOp.PtrInfo{
2525 .allowzero_token = null,
2526 .align_info = null,
2527 .const_token = null,
2528 .volatile_token = null,
2529 .null_token = null,
2530 },
2531 },
2532 .rhs = undefined, // set by caller
2533 };
2520 if (eatToken(it, .AsteriskAsterisk)) |double_asterisk| {
2521 const node = try arena.create(Node.PrefixOp);
2522 node.* = Node.PrefixOp{
2523 .op_token = double_asterisk,
2524 .op = Node.PrefixOp.Op{ .PtrType = .{} },
2525 .rhs = undefined, // set by caller
2526 };
25342527
2535 // Special case for **, which is its own token
2536 if (token.ptr.id == .AsteriskAsterisk) {
2528 // Special case for **, which is its own token
25372529 const child = try arena.create(Node.PrefixOp);
25382530 child.* = Node.PrefixOp{
2539 .base = Node{ .id = .PrefixOp },
2540 .op_token = token.index,
2541 .op = Node.PrefixOp.Op{
2542 .PtrType = Node.PrefixOp.PtrInfo{
2543 .allowzero_token = null,
2544 .align_info = null,
2545 .const_token = null,
2546 .volatile_token = null,
2547 .null_token = null,
2548 },
2549 },
2531 .op_token = double_asterisk,
2532 .op = Node.PrefixOp.Op{ .PtrType = .{} },
25502533 .rhs = undefined, // set by caller
25512534 };
25522535 node.rhs = &child.base;
2553 }
25542536
2555 return &node.base;
2537 return &node.base;
2538 }
2539 if (eatToken(it, .LBracket)) |lbracket| {
2540 const asterisk = eatToken(it, .Asterisk) orelse {
2541 putBackToken(it, lbracket);
2542 return null;
2543 };
2544 if (eatToken(it, .Identifier)) |ident| {
2545 if (!std.mem.eql(u8, tree.tokenSlice(ident), "c")) {
2546 putBackToken(it, ident);
2547 } else {
2548 _ = try expectToken(it, tree, .RBracket);
2549 const node = try arena.create(Node.PrefixOp);
2550 node.* = .{
2551 .op_token = ident,
2552 .op = .{ .PtrType = .{} },
2553 .rhs = undefined, // set by caller
2554 };
2555 return &node.base;
2556 }
2557 }
2558 const sentinel = if (eatToken(it, .Colon)) |_|
2559 try expectNode(arena, it, tree, parseExpr, AstError{
2560 .ExpectedExpr = .{ .token = it.index },
2561 })
2562 else
2563 null;
2564 _ = try expectToken(it, tree, .RBracket);
2565 const node = try arena.create(Node.PrefixOp);
2566 node.* = .{
2567 .op_token = lbracket,
2568 .op = .{ .PtrType = .{ .sentinel = sentinel } },
2569 .rhs = undefined, // set by caller
2570 };
2571 return &node.base;
2572 }
2573 return null;
25562574}
25572575
25582576/// ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE
lib/std/zig/render.zig+29-11
......@@ -418,13 +418,26 @@ fn renderExpression(
418418
419419 switch (prefix_op_node.op) {
420420 ast.Node.PrefixOp.Op.PtrType => |ptr_info| {
421 const star_offset = switch (tree.tokens.at(prefix_op_node.op_token).id) {
422 Token.Id.AsteriskAsterisk => @as(usize, 1),
423 else => @as(usize, 0),
424 };
425 try renderTokenOffset(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None, star_offset); // *
426 if (ptr_info.null_token) |null_token| {
427 try renderToken(tree, stream, null_token, indent, start_col, Space.Space); // null
421 const op_tok_id = tree.tokens.at(prefix_op_node.op_token).id;
422 switch (op_tok_id) {
423 .Asterisk, .AsteriskAsterisk => try stream.writeByte('*'),
424 .Identifier => try stream.write("[*c]"),
425 .LBracket => try stream.write("[*"),
426 else => unreachable,
427 }
428 if (ptr_info.sentinel) |sentinel| {
429 const colon_token = tree.prevToken(sentinel.firstToken());
430 try renderToken(tree, stream, colon_token, indent, start_col, Space.None); // :
431 const sentinel_space = switch (op_tok_id) {
432 .LBracket => Space.None,
433 else => Space.Space,
434 };
435 try renderExpression(allocator, stream, tree, indent, start_col, sentinel, sentinel_space);
436 }
437 switch (op_tok_id) {
438 .Asterisk, .AsteriskAsterisk, .Identifier => {},
439 .LBracket => try stream.writeByte(']'),
440 else => unreachable,
428441 }
429442 if (ptr_info.allowzero_token) |allowzero_token| {
430443 try renderToken(tree, stream, allowzero_token, indent, start_col, Space.Space); // allowzero
......@@ -504,7 +517,10 @@ fn renderExpression(
504517
505518 ast.Node.PrefixOp.Op.ArrayType => |array_info| {
506519 const lbracket = prefix_op_node.op_token;
507 const rbracket = tree.nextToken(array_info.len_expr.lastToken());
520 const rbracket = tree.nextToken(if (array_info.sentinel) |sentinel|
521 sentinel.lastToken()
522 else
523 array_info.len_expr.lastToken());
508524
509525 try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
510526
......@@ -519,10 +535,12 @@ fn renderExpression(
519535 if (ends_with_comment or starts_with_comment) {
520536 try stream.writeByteNTimes(' ', indent);
521537 }
522 try renderToken(tree, stream, rbracket, indent, start_col, Space.None); // ]
523 if (array_info.null_token) |null_token| {
524 try renderToken(tree, stream, null_token, indent, start_col, Space.Space); // null
538 if (array_info.sentinel) |sentinel| {
539 const colon_token = tree.prevToken(sentinel.firstToken());
540 try renderToken(tree, stream, colon_token, indent, start_col, Space.None); // :
541 try renderExpression(allocator, stream, tree, indent, start_col, sentinel, Space.None);
525542 }
543 try renderToken(tree, stream, rbracket, indent, start_col, Space.None); // ]
526544 },
527545 ast.Node.PrefixOp.Op.BitNot,
528546 ast.Node.PrefixOp.Op.BoolNot,
lib/std/zig/tokenizer.zig+10-52
......@@ -143,8 +143,6 @@ pub const Token = struct {
143143 LineComment,
144144 DocComment,
145145 ContainerDocComment,
146 BracketStarBracket,
147 BracketStarCBracket,
148146 ShebangLine,
149147 Keyword_align,
150148 Keyword_allowzero,
......@@ -269,8 +267,6 @@ pub const Token = struct {
269267 .AngleBracketAngleBracketRight => ">>",
270268 .AngleBracketAngleBracketRightEqual => ">>=",
271269 .Tilde => "~",
272 .BracketStarBracket => "[*]",
273 .BracketStarCBracket => "[*c]",
274270 .Keyword_align => "align",
275271 .Keyword_allowzero => "allowzero",
276272 .Keyword_and => "and",
......@@ -400,9 +396,6 @@ pub const Tokenizer = struct {
400396 Period,
401397 Period2,
402398 SawAtSign,
403 LBracket,
404 LBracketStar,
405 LBracketStarC,
406399 };
407400
408401 pub fn next(self: *Tokenizer) Token {
......@@ -460,7 +453,9 @@ pub const Tokenizer = struct {
460453 break;
461454 },
462455 '[' => {
463 state = State.LBracket;
456 result.id = .LBracket;
457 self.index += 1;
458 break;
464459 },
465460 ']' => {
466461 result.id = Token.Id.RBracket;
......@@ -564,43 +559,6 @@ pub const Tokenizer = struct {
564559 },
565560 },
566561
567 State.LBracket => switch (c) {
568 '*' => {
569 state = State.LBracketStar;
570 },
571 else => {
572 result.id = Token.Id.LBracket;
573 break;
574 },
575 },
576
577 State.LBracketStar => switch (c) {
578 'c' => {
579 state = State.LBracketStarC;
580 },
581 ']' => {
582 result.id = Token.Id.BracketStarBracket;
583 self.index += 1;
584 break;
585 },
586 else => {
587 result.id = Token.Id.Invalid;
588 break;
589 },
590 },
591
592 State.LBracketStarC => switch (c) {
593 ']' => {
594 result.id = Token.Id.BracketStarCBracket;
595 self.index += 1;
596 break;
597 },
598 else => {
599 result.id = Token.Id.Invalid;
600 break;
601 },
602 },
603
604562 State.Ampersand => switch (c) {
605563 '&' => {
606564 result.id = Token.Id.Invalid_ampersands;
......@@ -1227,8 +1185,6 @@ pub const Tokenizer = struct {
12271185 State.CharLiteralEnd,
12281186 State.CharLiteralUnicode,
12291187 State.StringLiteralBackslash,
1230 State.LBracketStar,
1231 State.LBracketStarC,
12321188 => {
12331189 result.id = Token.Id.Invalid;
12341190 },
......@@ -1245,9 +1201,6 @@ pub const Tokenizer = struct {
12451201 State.Slash => {
12461202 result.id = Token.Id.Slash;
12471203 },
1248 State.LBracket => {
1249 result.id = Token.Id.LBracket;
1250 },
12511204 State.Zero => {
12521205 result.id = Token.Id.IntegerLiteral;
12531206 },
......@@ -1368,9 +1321,14 @@ test "tokenizer - unknown length pointer and then c pointer" {
13681321 \\[*]u8
13691322 \\[*c]u8
13701323 , [_]Token.Id{
1371 Token.Id.BracketStarBracket,
1324 Token.Id.LBracket,
1325 Token.Id.Asterisk,
1326 Token.Id.RBracket,
1327 Token.Id.Identifier,
1328 Token.Id.LBracket,
1329 Token.Id.Asterisk,
13721330 Token.Id.Identifier,
1373 Token.Id.BracketStarCBracket,
1331 Token.Id.RBracket,
13741332 Token.Id.Identifier,
13751333 });
13761334}
src-self-hosted/translate_c.zig+20-9
......@@ -1105,19 +1105,32 @@ fn transCreateNodePtrType(
11051105 is_const: bool,
11061106 is_volatile: bool,
11071107 op_tok_id: std.zig.Token.Id,
1108 bytes: []const u8,
11091108) !*ast.Node.PrefixOp {
11101109 const node = try c.a().create(ast.Node.PrefixOp);
1110 const op_token = switch (op_tok_id) {
1111 .LBracket => blk: {
1112 const lbracket = try appendToken(c, .LBracket, "[");
1113 _ = try appendToken(c, .Asterisk, "*");
1114 _ = try appendToken(c, .RBracket, "]");
1115 break :blk lbracket;
1116 },
1117 .Identifier => blk: {
1118 _ = try appendToken(c, .LBracket, "[");
1119 _ = try appendToken(c, .Asterisk, "*");
1120 const c_ident = try appendToken(c, .Identifier, "c");
1121 _ = try appendToken(c, .RBracket, "]");
1122 break :blk c_ident;
1123 },
1124 .Asterisk => try appendToken(c, .Asterisk, "*"),
1125 else => unreachable,
1126 };
11111127 node.* = ast.Node.PrefixOp{
11121128 .base = ast.Node{ .id = .PrefixOp },
1113 .op_token = try appendToken(c, op_tok_id, bytes),
1129 .op_token = op_token,
11141130 .op = ast.Node.PrefixOp.Op{
1115 .PtrType = ast.Node.PrefixOp.PtrInfo{
1116 .allowzero_token = null,
1117 .align_info = null,
1131 .PtrType = .{
11181132 .const_token = if (is_const) try appendToken(c, .Keyword_const, "const") else null,
11191133 .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null,
1120 .null_token = null,
11211134 },
11221135 },
11231136 .rhs = undefined, // translate and set afterward
......@@ -1226,7 +1239,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
12261239 ZigClangQualType_isConstQualified(child_qt),
12271240 ZigClangQualType_isVolatileQualified(child_qt),
12281241 .Asterisk,
1229 "*",
12301242 );
12311243 optional_node.rhs = &pointer_node.base;
12321244 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);
......@@ -1236,8 +1248,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
12361248 rp.c,
12371249 ZigClangQualType_isConstQualified(child_qt),
12381250 ZigClangQualType_isVolatileQualified(child_qt),
1239 .BracketStarCBracket,
1240 "[*c]",
1251 .Identifier,
12411252 );
12421253 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);
12431254 return &pointer_node.base;