authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-14 21:13:42-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-12-14 21:13:42-05:00
logcf0d300ddecf3e1bf0363002c995425dab007b74
tree1911b3595996594dffb1390699849c46eba8ad0a
parent33d9dda5584a6c21df1a4d14ab1a251772f76d4d
parente57e3602e7802789d56a076c6052092715997c24
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3908 from Vexu/translate-c-2

Translate-c-2 enums

7 files changed, 482 insertions(+), 252 deletions(-)

lib/std/zig/ast.zig+46-46
......@@ -581,7 +581,7 @@ pub const Node = struct {
581581 }
582582
583583 pub const Root = struct {
584 base: Node,
584 base: Node = Node {.id = .Root},
585585 decls: DeclList,
586586 eof_token: TokenIndex,
587587
......@@ -604,7 +604,7 @@ pub const Node = struct {
604604 };
605605
606606 pub const VarDecl = struct {
607 base: Node,
607 base: Node = Node {.id = .VarDecl},
608608 doc_comments: ?*DocComment,
609609 visib_token: ?TokenIndex,
610610 thread_local_token: ?TokenIndex,
......@@ -661,7 +661,7 @@ pub const Node = struct {
661661 };
662662
663663 pub const Use = struct {
664 base: Node,
664 base: Node = Node {.id = .Use},
665665 doc_comments: ?*DocComment,
666666 visib_token: ?TokenIndex,
667667 use_token: TokenIndex,
......@@ -688,7 +688,7 @@ pub const Node = struct {
688688 };
689689
690690 pub const ErrorSetDecl = struct {
691 base: Node,
691 base: Node = Node {.id = .ErrorSetDecl},
692692 error_token: TokenIndex,
693693 decls: DeclList,
694694 rbrace_token: TokenIndex,
......@@ -714,7 +714,7 @@ pub const Node = struct {
714714 };
715715
716716 pub const ContainerDecl = struct {
717 base: Node,
717 base: Node = Node {.id = .ContainerDecl},
718718 layout_token: ?TokenIndex,
719719 kind_token: TokenIndex,
720720 init_arg_expr: InitArg,
......@@ -801,7 +801,7 @@ pub const Node = struct {
801801 };
802802
803803 pub const ErrorTag = struct {
804 base: Node,
804 base: Node = Node {.id = .ErrorTag},
805805 doc_comments: ?*DocComment,
806806 name_token: TokenIndex,
807807
......@@ -826,7 +826,7 @@ pub const Node = struct {
826826 };
827827
828828 pub const Identifier = struct {
829 base: Node,
829 base: Node = Node {.id = .Identifier},
830830 token: TokenIndex,
831831
832832 pub fn iterate(self: *Identifier, index: usize) ?*Node {
......@@ -843,7 +843,7 @@ pub const Node = struct {
843843 };
844844
845845 pub const FnProto = struct {
846 base: Node,
846 base: Node = Node {.id = .FnProto},
847847 doc_comments: ?*DocComment,
848848 visib_token: ?TokenIndex,
849849 fn_token: TokenIndex,
......@@ -925,7 +925,7 @@ pub const Node = struct {
925925 };
926926
927927 pub const AnyFrameType = struct {
928 base: Node,
928 base: Node = Node {.id = .AnyFrameType},
929929 anyframe_token: TokenIndex,
930930 result: ?Result,
931931
......@@ -956,7 +956,7 @@ pub const Node = struct {
956956 };
957957
958958 pub const ParamDecl = struct {
959 base: Node,
959 base: Node = Node {.id = .ParamDecl},
960960 doc_comments: ?*DocComment,
961961 comptime_token: ?TokenIndex,
962962 noalias_token: ?TokenIndex,
......@@ -989,7 +989,7 @@ pub const Node = struct {
989989 };
990990
991991 pub const Block = struct {
992 base: Node,
992 base: Node = Node {.id = .Block},
993993 label: ?TokenIndex,
994994 lbrace: TokenIndex,
995995 statements: StatementList,
......@@ -1020,7 +1020,7 @@ pub const Node = struct {
10201020 };
10211021
10221022 pub const Defer = struct {
1023 base: Node,
1023 base: Node = Node {.id = .Defer},
10241024 defer_token: TokenIndex,
10251025 expr: *Node,
10261026
......@@ -1043,7 +1043,7 @@ pub const Node = struct {
10431043 };
10441044
10451045 pub const Comptime = struct {
1046 base: Node,
1046 base: Node = Node {.id = .Comptime},
10471047 doc_comments: ?*DocComment,
10481048 comptime_token: TokenIndex,
10491049 expr: *Node,
......@@ -1067,7 +1067,7 @@ pub const Node = struct {
10671067 };
10681068
10691069 pub const Payload = struct {
1070 base: Node,
1070 base: Node = Node {.id = .Payload},
10711071 lpipe: TokenIndex,
10721072 error_symbol: *Node,
10731073 rpipe: TokenIndex,
......@@ -1091,7 +1091,7 @@ pub const Node = struct {
10911091 };
10921092
10931093 pub const PointerPayload = struct {
1094 base: Node,
1094 base: Node = Node {.id = .PointerPayload},
10951095 lpipe: TokenIndex,
10961096 ptr_token: ?TokenIndex,
10971097 value_symbol: *Node,
......@@ -1116,7 +1116,7 @@ pub const Node = struct {
11161116 };
11171117
11181118 pub const PointerIndexPayload = struct {
1119 base: Node,
1119 base: Node = Node {.id = .PointerIndexPayload},
11201120 lpipe: TokenIndex,
11211121 ptr_token: ?TokenIndex,
11221122 value_symbol: *Node,
......@@ -1147,7 +1147,7 @@ pub const Node = struct {
11471147 };
11481148
11491149 pub const Else = struct {
1150 base: Node,
1150 base: Node = Node {.id = .Else},
11511151 else_token: TokenIndex,
11521152 payload: ?*Node,
11531153 body: *Node,
......@@ -1176,7 +1176,7 @@ pub const Node = struct {
11761176 };
11771177
11781178 pub const Switch = struct {
1179 base: Node,
1179 base: Node = Node {.id = .Switch},
11801180 switch_token: TokenIndex,
11811181 expr: *Node,
11821182
......@@ -1208,7 +1208,7 @@ pub const Node = struct {
12081208 };
12091209
12101210 pub const SwitchCase = struct {
1211 base: Node,
1211 base: Node = Node {.id = .SwitchCase},
12121212 items: ItemList,
12131213 arrow_token: TokenIndex,
12141214 payload: ?*Node,
......@@ -1243,7 +1243,7 @@ pub const Node = struct {
12431243 };
12441244
12451245 pub const SwitchElse = struct {
1246 base: Node,
1246 base: Node = Node {.id = .SwitchElse},
12471247 token: TokenIndex,
12481248
12491249 pub fn iterate(self: *SwitchElse, index: usize) ?*Node {
......@@ -1260,7 +1260,7 @@ pub const Node = struct {
12601260 };
12611261
12621262 pub const While = struct {
1263 base: Node,
1263 base: Node = Node {.id = .While},
12641264 label: ?TokenIndex,
12651265 inline_token: ?TokenIndex,
12661266 while_token: TokenIndex,
......@@ -1319,7 +1319,7 @@ pub const Node = struct {
13191319 };
13201320
13211321 pub const For = struct {
1322 base: Node,
1322 base: Node = Node {.id = .For},
13231323 label: ?TokenIndex,
13241324 inline_token: ?TokenIndex,
13251325 for_token: TokenIndex,
......@@ -1370,7 +1370,7 @@ pub const Node = struct {
13701370 };
13711371
13721372 pub const If = struct {
1373 base: Node,
1373 base: Node = Node {.id = .If},
13741374 if_token: TokenIndex,
13751375 condition: *Node,
13761376 payload: ?*Node,
......@@ -1413,7 +1413,7 @@ pub const Node = struct {
14131413 };
14141414
14151415 pub const InfixOp = struct {
1416 base: Node,
1416 base: Node = Node {.id = .InfixOp},
14171417 op_token: TokenIndex,
14181418 lhs: *Node,
14191419 op: Op,
......@@ -1646,7 +1646,7 @@ pub const Node = struct {
16461646 };
16471647
16481648 pub const FieldInitializer = struct {
1649 base: Node,
1649 base: Node = Node {.id = .FieldInitializer},
16501650 period_token: TokenIndex,
16511651 name_token: TokenIndex,
16521652 expr: *Node,
......@@ -1670,7 +1670,7 @@ pub const Node = struct {
16701670 };
16711671
16721672 pub const SuffixOp = struct {
1673 base: Node,
1673 base: Node = Node {.id = .SuffixOp},
16741674 lhs: Lhs,
16751675 op: Op,
16761676 rtoken: TokenIndex,
......@@ -1766,7 +1766,7 @@ pub const Node = struct {
17661766 };
17671767
17681768 pub const GroupedExpression = struct {
1769 base: Node,
1769 base: Node = Node {.id = .GroupedExpression},
17701770 lparen: TokenIndex,
17711771 expr: *Node,
17721772 rparen: TokenIndex,
......@@ -1790,7 +1790,7 @@ pub const Node = struct {
17901790 };
17911791
17921792 pub const ControlFlowExpression = struct {
1793 base: Node,
1793 base: Node = Node {.id = .ControlFlowExpression},
17941794 ltoken: TokenIndex,
17951795 kind: Kind,
17961796 rhs: ?*Node,
......@@ -1856,7 +1856,7 @@ pub const Node = struct {
18561856 };
18571857
18581858 pub const Suspend = struct {
1859 base: Node,
1859 base: Node = Node {.id = .Suspend},
18601860 suspend_token: TokenIndex,
18611861 body: ?*Node,
18621862
......@@ -1885,7 +1885,7 @@ pub const Node = struct {
18851885 };
18861886
18871887 pub const IntegerLiteral = struct {
1888 base: Node,
1888 base: Node = Node {.id = .IntegerLiteral},
18891889 token: TokenIndex,
18901890
18911891 pub fn iterate(self: *IntegerLiteral, index: usize) ?*Node {
......@@ -1902,7 +1902,7 @@ pub const Node = struct {
19021902 };
19031903
19041904 pub const EnumLiteral = struct {
1905 base: Node,
1905 base: Node = Node {.id = .EnumLiteral},
19061906 dot: TokenIndex,
19071907 name: TokenIndex,
19081908
......@@ -1920,7 +1920,7 @@ pub const Node = struct {
19201920 };
19211921
19221922 pub const FloatLiteral = struct {
1923 base: Node,
1923 base: Node = Node {.id = .FloatLiteral},
19241924 token: TokenIndex,
19251925
19261926 pub fn iterate(self: *FloatLiteral, index: usize) ?*Node {
......@@ -1937,7 +1937,7 @@ pub const Node = struct {
19371937 };
19381938
19391939 pub const BuiltinCall = struct {
1940 base: Node,
1940 base: Node = Node {.id = .BuiltinCall},
19411941 builtin_token: TokenIndex,
19421942 params: ParamList,
19431943 rparen_token: TokenIndex,
......@@ -1963,7 +1963,7 @@ pub const Node = struct {
19631963 };
19641964
19651965 pub const StringLiteral = struct {
1966 base: Node,
1966 base: Node = Node {.id = .StringLiteral},
19671967 token: TokenIndex,
19681968
19691969 pub fn iterate(self: *StringLiteral, index: usize) ?*Node {
......@@ -1980,7 +1980,7 @@ pub const Node = struct {
19801980 };
19811981
19821982 pub const MultilineStringLiteral = struct {
1983 base: Node,
1983 base: Node = Node {.id = .MultilineStringLiteral},
19841984 lines: LineList,
19851985
19861986 pub const LineList = SegmentedList(TokenIndex, 4);
......@@ -1999,7 +1999,7 @@ pub const Node = struct {
19991999 };
20002000
20012001 pub const CharLiteral = struct {
2002 base: Node,
2002 base: Node = Node {.id = .CharLiteral},
20032003 token: TokenIndex,
20042004
20052005 pub fn iterate(self: *CharLiteral, index: usize) ?*Node {
......@@ -2016,7 +2016,7 @@ pub const Node = struct {
20162016 };
20172017
20182018 pub const BoolLiteral = struct {
2019 base: Node,
2019 base: Node = Node {.id = .BoolLiteral},
20202020 token: TokenIndex,
20212021
20222022 pub fn iterate(self: *BoolLiteral, index: usize) ?*Node {
......@@ -2033,7 +2033,7 @@ pub const Node = struct {
20332033 };
20342034
20352035 pub const NullLiteral = struct {
2036 base: Node,
2036 base: Node = Node {.id = .NullLiteral},
20372037 token: TokenIndex,
20382038
20392039 pub fn iterate(self: *NullLiteral, index: usize) ?*Node {
......@@ -2050,7 +2050,7 @@ pub const Node = struct {
20502050 };
20512051
20522052 pub const UndefinedLiteral = struct {
2053 base: Node,
2053 base: Node = Node {.id = .UndefinedLiteral},
20542054 token: TokenIndex,
20552055
20562056 pub fn iterate(self: *UndefinedLiteral, index: usize) ?*Node {
......@@ -2067,7 +2067,7 @@ pub const Node = struct {
20672067 };
20682068
20692069 pub const AsmOutput = struct {
2070 base: Node,
2070 base: Node = Node {.id = .AsmOutput},
20712071 lbracket: TokenIndex,
20722072 symbolic_name: *Node,
20732073 constraint: *Node,
......@@ -2112,7 +2112,7 @@ pub const Node = struct {
21122112 };
21132113
21142114 pub const AsmInput = struct {
2115 base: Node,
2115 base: Node = Node {.id = .AsmInput},
21162116 lbracket: TokenIndex,
21172117 symbolic_name: *Node,
21182118 constraint: *Node,
......@@ -2144,7 +2144,7 @@ pub const Node = struct {
21442144 };
21452145
21462146 pub const Asm = struct {
2147 base: Node,
2147 base: Node = Node {.id = .Asm},
21482148 asm_token: TokenIndex,
21492149 volatile_token: ?TokenIndex,
21502150 template: *Node,
......@@ -2179,7 +2179,7 @@ pub const Node = struct {
21792179 };
21802180
21812181 pub const Unreachable = struct {
2182 base: Node,
2182 base: Node = Node {.id = .Unreachable},
21832183 token: TokenIndex,
21842184
21852185 pub fn iterate(self: *Unreachable, index: usize) ?*Node {
......@@ -2196,7 +2196,7 @@ pub const Node = struct {
21962196 };
21972197
21982198 pub const ErrorType = struct {
2199 base: Node,
2199 base: Node = Node {.id = .ErrorType},
22002200 token: TokenIndex,
22012201
22022202 pub fn iterate(self: *ErrorType, index: usize) ?*Node {
......@@ -2230,7 +2230,7 @@ pub const Node = struct {
22302230 };
22312231
22322232 pub const DocComment = struct {
2233 base: Node,
2233 base: Node = Node {.id = .DocComment},
22342234 lines: LineList,
22352235
22362236 pub const LineList = SegmentedList(TokenIndex, 4);
......@@ -2249,7 +2249,7 @@ pub const Node = struct {
22492249 };
22502250
22512251 pub const TestDecl = struct {
2252 base: Node,
2252 base: Node = Node {.id = .TestDecl},
22532253 doc_comments: ?*DocComment,
22542254 test_token: TokenIndex,
22552255 name: *Node,
lib/std/zig/parse.zig-72
......@@ -56,7 +56,6 @@ pub fn parse(allocator: *Allocator, source: []const u8) !*Tree {
5656fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!*Node.Root {
5757 const node = try arena.create(Node.Root);
5858 node.* = Node.Root{
59 .base = Node{ .id = .Root },
6059 .decls = undefined,
6160 .eof_token = undefined,
6261 };
......@@ -176,7 +175,6 @@ fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree)
176175
177176 const node = try arena.create(Node.DocComment);
178177 node.* = Node.DocComment{
179 .base = Node{ .id = .DocComment },
180178 .lines = lines,
181179 };
182180 return &node.base;
......@@ -194,7 +192,6 @@ fn parseTestDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
194192
195193 const test_node = try arena.create(Node.TestDecl);
196194 test_node.* = Node.TestDecl{
197 .base = Node{ .id = .TestDecl },
198195 .doc_comments = null,
199196 .test_token = test_token,
200197 .name = name_node,
......@@ -217,7 +214,6 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*
217214
218215 const comptime_node = try arena.create(Node.Comptime);
219216 comptime_node.* = Node.Comptime{
220 .base = Node{ .id = .Comptime },
221217 .doc_comments = null,
222218 .comptime_token = tok,
223219 .expr = block_node,
......@@ -338,7 +334,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
338334
339335 const fn_proto_node = try arena.create(Node.FnProto);
340336 fn_proto_node.* = Node.FnProto{
341 .base = Node{ .id = .FnProto },
342337 .doc_comments = null,
343338 .visib_token = null,
344339 .fn_token = fn_token,
......@@ -389,7 +384,6 @@ fn parseVarDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
389384
390385 const node = try arena.create(Node.VarDecl);
391386 node.* = Node.VarDecl{
392 .base = Node{ .id = .VarDecl },
393387 .doc_comments = null,
394388 .visib_token = null,
395389 .thread_local_token = null,
......@@ -477,7 +471,6 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
477471
478472 const node = try arena.create(Node.Comptime);
479473 node.* = Node.Comptime{
480 .base = Node{ .id = .Comptime },
481474 .doc_comments = null,
482475 .comptime_token = token,
483476 .expr = block_expr,
......@@ -496,7 +489,6 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
496489
497490 const node = try arena.create(Node.Suspend);
498491 node.* = Node.Suspend{
499 .base = Node{ .id = .Suspend },
500492 .suspend_token = suspend_token,
501493 .body = body_node,
502494 };
......@@ -510,7 +502,6 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
510502 });
511503 const node = try arena.create(Node.Defer);
512504 node.* = Node.Defer{
513 .base = Node{ .id = .Defer },
514505 .defer_token = token,
515506 .expr = expr_node,
516507 };
......@@ -558,7 +549,6 @@ fn parseIfStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
558549
559550 const node = try arena.create(Node.Else);
560551 node.* = Node.Else{
561 .base = Node{ .id = .Else },
562552 .else_token = else_token,
563553 .payload = payload,
564554 .body = else_body,
......@@ -652,7 +642,6 @@ fn parseForStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
652642
653643 const else_node = try arena.create(Node.Else);
654644 else_node.* = Node.Else{
655 .base = Node{ .id = .Else },
656645 .else_token = else_token,
657646 .payload = null,
658647 .body = statement_node,
......@@ -677,7 +666,6 @@ fn parseForStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
677666
678667 const else_node = try arena.create(Node.Else);
679668 else_node.* = Node.Else{
680 .base = Node{ .id = .Else },
681669 .else_token = else_token,
682670 .payload = null,
683671 .body = statement_node,
......@@ -714,7 +702,6 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
714702
715703 const else_node = try arena.create(Node.Else);
716704 else_node.* = Node.Else{
717 .base = Node{ .id = .Else },
718705 .else_token = else_token,
719706 .payload = payload,
720707 .body = statement_node,
......@@ -741,7 +728,6 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
741728
742729 const else_node = try arena.create(Node.Else);
743730 else_node.* = Node.Else{
744 .base = Node{ .id = .Else },
745731 .else_token = else_token,
746732 .payload = payload,
747733 .body = statement_node,
......@@ -870,7 +856,6 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
870856 const expr_node = try parseExpr(arena, it, tree);
871857 const node = try arena.create(Node.ControlFlowExpression);
872858 node.* = Node.ControlFlowExpression{
873 .base = Node{ .id = .ControlFlowExpression },
874859 .ltoken = token,
875860 .kind = Node.ControlFlowExpression.Kind{ .Break = label },
876861 .rhs = expr_node,
......@@ -884,7 +869,6 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
884869 });
885870 const node = try arena.create(Node.Comptime);
886871 node.* = Node.Comptime{
887 .base = Node{ .id = .Comptime },
888872 .doc_comments = null,
889873 .comptime_token = token,
890874 .expr = expr_node,
......@@ -896,7 +880,6 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
896880 const label = try parseBreakLabel(arena, it, tree);
897881 const node = try arena.create(Node.ControlFlowExpression);
898882 node.* = Node.ControlFlowExpression{
899 .base = Node{ .id = .ControlFlowExpression },
900883 .ltoken = token,
901884 .kind = Node.ControlFlowExpression.Kind{ .Continue = label },
902885 .rhs = null,
......@@ -910,7 +893,6 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
910893 });
911894 const node = try arena.create(Node.PrefixOp);
912895 node.* = Node.PrefixOp{
913 .base = Node{ .id = .PrefixOp },
914896 .op_token = token,
915897 .op = Node.PrefixOp.Op.Resume,
916898 .rhs = expr_node,
......@@ -922,7 +904,6 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
922904 const expr_node = try parseExpr(arena, it, tree);
923905 const node = try arena.create(Node.ControlFlowExpression);
924906 node.* = Node.ControlFlowExpression{
925 .base = Node{ .id = .ControlFlowExpression },
926907 .ltoken = token,
927908 .kind = Node.ControlFlowExpression.Kind.Return,
928909 .rhs = expr_node,
......@@ -970,7 +951,6 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
970951
971952 const block_node = try arena.create(Node.Block);
972953 block_node.* = Node.Block{
973 .base = Node{ .id = .Block },
974954 .label = null,
975955 .lbrace = lbrace,
976956 .statements = statements,
......@@ -1020,7 +1000,6 @@ fn parseForExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
10201000
10211001 const else_node = try arena.create(Node.Else);
10221002 else_node.* = Node.Else{
1023 .base = Node{ .id = .Else },
10241003 .else_token = else_token,
10251004 .payload = null,
10261005 .body = body,
......@@ -1050,7 +1029,6 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
10501029
10511030 const else_node = try arena.create(Node.Else);
10521031 else_node.* = Node.Else{
1053 .base = Node{ .id = .Else },
10541032 .else_token = else_token,
10551033 .payload = payload,
10561034 .body = body,
......@@ -1102,7 +1080,6 @@ fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.Suf
11021080
11031081 const node = try arena.create(Node.SuffixOp);
11041082 node.* = Node.SuffixOp{
1105 .base = Node{ .id = .SuffixOp },
11061083 .lhs = .{ .node = undefined }, // set by caller
11071084 .op = op,
11081085 .rtoken = try expectToken(it, tree, .RBrace),
......@@ -1171,7 +1148,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
11711148 };
11721149 const node = try arena.create(Node.SuffixOp);
11731150 node.* = Node.SuffixOp{
1174 .base = Node{ .id = .SuffixOp },
11751151 .lhs = .{ .node = res },
11761152 .op = Node.SuffixOp.Op{
11771153 .Call = Node.SuffixOp.Op.Call{
......@@ -1199,7 +1175,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
11991175 if (try parseFnCallArguments(arena, it, tree)) |params| {
12001176 const call = try arena.create(Node.SuffixOp);
12011177 call.* = Node.SuffixOp{
1202 .base = Node{ .id = .SuffixOp },
12031178 .lhs = .{ .node = res },
12041179 .op = Node.SuffixOp.Op{
12051180 .Call = Node.SuffixOp.Op.Call{
......@@ -1248,7 +1223,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
12481223 if (eatToken(it, .CharLiteral)) |token| {
12491224 const node = try arena.create(Node.CharLiteral);
12501225 node.* = Node.CharLiteral{
1251 .base = Node{ .id = .CharLiteral },
12521226 .token = token,
12531227 };
12541228 return &node.base;
......@@ -1267,7 +1241,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
12671241 const expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
12681242 const node = try arena.create(Node.Comptime);
12691243 node.* = Node.Comptime{
1270 .base = Node{ .id = .Comptime },
12711244 .doc_comments = null,
12721245 .comptime_token = token,
12731246 .expr = expr,
......@@ -1282,7 +1255,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
12821255 const global_error_set = try createLiteral(arena, Node.ErrorType, token);
12831256 const node = try arena.create(Node.InfixOp);
12841257 node.* = Node.InfixOp{
1285 .base = Node{ .id = .InfixOp },
12861258 .op_token = period,
12871259 .lhs = global_error_set,
12881260 .op = Node.InfixOp.Op.Period,
......@@ -1295,7 +1267,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
12951267 if (eatToken(it, .Keyword_anyframe)) |token| {
12961268 const node = try arena.create(Node.AnyFrameType);
12971269 node.* = Node.AnyFrameType{
1298 .base = Node{ .id = .AnyFrameType },
12991270 .anyframe_token = token,
13001271 .result = null,
13011272 };
......@@ -1337,7 +1308,6 @@ fn parseErrorSetDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
13371308
13381309 const node = try arena.create(Node.ErrorSetDecl);
13391310 node.* = Node.ErrorSetDecl{
1340 .base = Node{ .id = .ErrorSetDecl },
13411311 .error_token = error_token,
13421312 .decls = decls,
13431313 .rbrace_token = rbrace,
......@@ -1355,7 +1325,6 @@ fn parseGroupedExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
13551325
13561326 const node = try arena.create(Node.GroupedExpression);
13571327 node.* = Node.GroupedExpression{
1358 .base = Node{ .id = .GroupedExpression },
13591328 .lparen = lparen,
13601329 .expr = expr,
13611330 .rparen = rparen,
......@@ -1438,7 +1407,6 @@ fn parseForTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
14381407
14391408 const else_node = try arena.create(Node.Else);
14401409 else_node.* = Node.Else{
1441 .base = Node{ .id = .Else },
14421410 .else_token = else_token,
14431411 .payload = null,
14441412 .body = else_expr,
......@@ -1469,7 +1437,6 @@ fn parseWhileTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Nod
14691437
14701438 const else_node = try arena.create(Node.Else);
14711439 else_node.* = Node.Else{
1472 .base = Node{ .id = .Else },
14731440 .else_token = else_token,
14741441 .payload = null,
14751442 .body = else_expr,
......@@ -1495,7 +1462,6 @@ fn parseSwitchExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
14951462
14961463 const node = try arena.create(Node.Switch);
14971464 node.* = Node.Switch{
1498 .base = Node{ .id = .Switch },
14991465 .switch_token = switch_token,
15001466 .expr = expr_node,
15011467 .cases = cases,
......@@ -1515,7 +1481,6 @@ fn parseAsmExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
15151481
15161482 const node = try arena.create(Node.Asm);
15171483 node.* = Node.Asm{
1518 .base = Node{ .id = .Asm },
15191484 .asm_token = asm_token,
15201485 .volatile_token = volatile_token,
15211486 .template = template,
......@@ -1538,7 +1503,6 @@ fn parseAnonLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
15381503 if (eatToken(it, .Identifier)) |name| {
15391504 const node = try arena.create(Node.EnumLiteral);
15401505 node.* = Node.EnumLiteral{
1541 .base = Node{ .id = .EnumLiteral },
15421506 .dot = dot,
15431507 .name = name,
15441508 };
......@@ -1591,7 +1555,6 @@ fn parseAsmOutputItem(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Nod
15911555
15921556 const node = try arena.create(Node.AsmOutput);
15931557 node.* = Node.AsmOutput{
1594 .base = Node{ .id = .AsmOutput },
15951558 .lbracket = lbracket,
15961559 .symbolic_name = name,
15971560 .constraint = constraint,
......@@ -1628,7 +1591,6 @@ fn parseAsmInputItem(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
16281591
16291592 const node = try arena.create(Node.AsmInput);
16301593 node.* = Node.AsmInput{
1631 .base = Node{ .id = .AsmInput },
16321594 .lbracket = lbracket,
16331595 .symbolic_name = name,
16341596 .constraint = constraint,
......@@ -1687,7 +1649,6 @@ fn parseFieldInit(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
16871649
16881650 const node = try arena.create(Node.FieldInitializer);
16891651 node.* = Node.FieldInitializer{
1690 .base = Node{ .id = .FieldInitializer },
16911652 .period_token = period_token,
16921653 .name_token = name_token,
16931654 .expr = expr_node,
......@@ -1760,7 +1721,6 @@ fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
17601721
17611722 const param_decl = try arena.create(Node.ParamDecl);
17621723 param_decl.* = Node.ParamDecl{
1763 .base = Node{ .id = .ParamDecl },
17641724 .doc_comments = doc_comments,
17651725 .comptime_token = comptime_token,
17661726 .noalias_token = noalias_token,
......@@ -1807,7 +1767,6 @@ fn parseIfPrefix(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
18071767
18081768 const node = try arena.create(Node.If);
18091769 node.* = Node.If{
1810 .base = Node{ .id = .If },
18111770 .if_token = if_token,
18121771 .condition = condition,
18131772 .payload = payload,
......@@ -1832,7 +1791,6 @@ fn parseWhilePrefix(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
18321791
18331792 const node = try arena.create(Node.While);
18341793 node.* = Node.While{
1835 .base = Node{ .id = .While },
18361794 .label = null,
18371795 .inline_token = null,
18381796 .while_token = while_token,
......@@ -1861,7 +1819,6 @@ fn parseForPrefix(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
18611819
18621820 const node = try arena.create(Node.For);
18631821 node.* = Node.For{
1864 .base = Node{ .id = .For },
18651822 .label = null,
18661823 .inline_token = null,
18671824 .for_token = for_token,
......@@ -1883,7 +1840,6 @@ fn parsePayload(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
18831840
18841841 const node = try arena.create(Node.Payload);
18851842 node.* = Node.Payload{
1886 .base = Node{ .id = .Payload },
18871843 .lpipe = lpipe,
18881844 .error_symbol = identifier,
18891845 .rpipe = rpipe,
......@@ -1902,7 +1858,6 @@ fn parsePtrPayload(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
19021858
19031859 const node = try arena.create(Node.PointerPayload);
19041860 node.* = Node.PointerPayload{
1905 .base = Node{ .id = .PointerPayload },
19061861 .lpipe = lpipe,
19071862 .ptr_token = asterisk,
19081863 .value_symbol = identifier,
......@@ -1930,7 +1885,6 @@ fn parsePtrIndexPayload(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
19301885
19311886 const node = try arena.create(Node.PointerIndexPayload);
19321887 node.* = Node.PointerIndexPayload{
1933 .base = Node{ .id = .PointerIndexPayload },
19341888 .lpipe = lpipe,
19351889 .ptr_token = asterisk,
19361890 .value_symbol = identifier,
......@@ -1972,7 +1926,6 @@ fn parseSwitchCase(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
19721926 } else if (eatToken(it, .Keyword_else)) |else_token| {
19731927 const else_node = try arena.create(Node.SwitchElse);
19741928 else_node.* = Node.SwitchElse{
1975 .base = Node{ .id = .SwitchElse },
19761929 .token = else_token,
19771930 };
19781931 try list.push(&else_node.base);
......@@ -1980,7 +1933,6 @@ fn parseSwitchCase(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
19801933
19811934 const node = try arena.create(Node.SwitchCase);
19821935 node.* = Node.SwitchCase{
1983 .base = Node{ .id = .SwitchCase },
19841936 .items = list,
19851937 .arrow_token = undefined, // set by caller
19861938 .payload = null,
......@@ -1999,7 +1951,6 @@ fn parseSwitchItem(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
19991951
20001952 const node = try arena.create(Node.InfixOp);
20011953 node.* = Node.InfixOp{
2002 .base = Node{ .id = .InfixOp },
20031954 .op_token = token,
20041955 .lhs = expr,
20051956 .op = Node.InfixOp.Op{ .Range = {} },
......@@ -2052,7 +2003,6 @@ fn parseAssignOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
20522003
20532004 const node = try arena.create(Node.InfixOp);
20542005 node.* = Node.InfixOp{
2055 .base = Node{ .id = .InfixOp },
20562006 .op_token = token.index,
20572007 .lhs = undefined, // set by caller
20582008 .op = op,
......@@ -2212,7 +2162,6 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
22122162
22132163 const node = try arena.create(Node.PrefixOp);
22142164 node.* = Node.PrefixOp{
2215 .base = Node{ .id = .PrefixOp },
22162165 .op_token = token.index,
22172166 .op = op,
22182167 .rhs = undefined,
......@@ -2236,7 +2185,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
22362185 if (eatToken(it, .QuestionMark)) |token| {
22372186 const node = try arena.create(Node.PrefixOp);
22382187 node.* = Node.PrefixOp{
2239 .base = Node{ .id = .PrefixOp },
22402188 .op_token = token,
22412189 .op = Node.PrefixOp.Op.OptionalType,
22422190 .rhs = undefined, // set by caller
......@@ -2255,7 +2203,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
22552203 };
22562204 const node = try arena.create(Node.AnyFrameType);
22572205 node.* = Node.AnyFrameType{
2258 .base = Node{ .id = .AnyFrameType },
22592206 .anyframe_token = token,
22602207 .result = Node.AnyFrameType.Result{
22612208 .arrow_token = arrow,
......@@ -2430,7 +2377,6 @@ fn parseSuffixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
24302377 // this grammar rule be altered?
24312378 const node = try arena.create(Node.InfixOp);
24322379 node.* = Node.InfixOp{
2433 .base = Node{ .id = .InfixOp },
24342380 .op_token = period,
24352381 .lhs = undefined, // set by caller
24362382 .op = Node.InfixOp.Op.Period,
......@@ -2452,7 +2398,6 @@ fn parseSuffixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
24522398
24532399 const node = try arena.create(Node.SuffixOp);
24542400 node.* = Node.SuffixOp{
2455 .base = Node{ .id = .SuffixOp },
24562401 .lhs = undefined, // set by caller
24572402 .op = op_and_token.op,
24582403 .rtoken = op_and_token.token,
......@@ -2506,7 +2451,6 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
25062451
25072452 const node = try arena.create(Node.PrefixOp);
25082453 node.* = Node.PrefixOp{
2509 .base = Node{ .id = .PrefixOp },
25102454 .op_token = lbracket,
25112455 .op = op,
25122456 .rhs = undefined, // set by caller
......@@ -2656,7 +2600,6 @@ fn parseContainerDeclType(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?
26562600
26572601 const node = try arena.create(Node.ContainerDecl);
26582602 node.* = Node.ContainerDecl{
2659 .base = Node{ .id = .ContainerDecl },
26602603 .layout_token = null,
26612604 .kind_token = kind_token.index,
26622605 .init_arg_expr = init_arg_expr,
......@@ -2729,7 +2672,6 @@ fn SimpleBinOpParseFn(comptime token: Token.Id, comptime op: Node.InfixOp.Op) No
27292672 const op_token = eatToken(it, token) orelse return null;
27302673 const node = try arena.create(Node.InfixOp);
27312674 node.* = Node.InfixOp{
2732 .base = Node{ .id = .InfixOp },
27332675 .op_token = op_token,
27342676 .lhs = undefined, // set by caller
27352677 .op = op,
......@@ -2752,7 +2694,6 @@ fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
27522694 };
27532695 const node = try arena.create(Node.BuiltinCall);
27542696 node.* = Node.BuiltinCall{
2755 .base = Node{ .id = .BuiltinCall },
27562697 .builtin_token = token,
27572698 .params = params.list,
27582699 .rparen_token = params.rparen,
......@@ -2766,7 +2707,6 @@ fn parseErrorTag(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
27662707
27672708 const node = try arena.create(Node.ErrorTag);
27682709 node.* = Node.ErrorTag{
2769 .base = Node{ .id = .ErrorTag },
27702710 .doc_comments = doc_comments,
27712711 .name_token = token,
27722712 };
......@@ -2777,7 +2717,6 @@ fn parseIdentifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
27772717 const token = eatToken(it, .Identifier) orelse return null;
27782718 const node = try arena.create(Node.Identifier);
27792719 node.* = Node.Identifier{
2780 .base = Node{ .id = .Identifier },
27812720 .token = token,
27822721 };
27832722 return &node.base;
......@@ -2787,7 +2726,6 @@ fn parseVarType(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
27872726 const token = eatToken(it, .Keyword_var) orelse return null;
27882727 const node = try arena.create(Node.VarType);
27892728 node.* = Node.VarType{
2790 .base = Node{ .id = .VarType },
27912729 .token = token,
27922730 };
27932731 return &node.base;
......@@ -2807,7 +2745,6 @@ fn parseStringLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Nod
28072745 if (eatToken(it, .StringLiteral)) |token| {
28082746 const node = try arena.create(Node.StringLiteral);
28092747 node.* = Node.StringLiteral{
2810 .base = Node{ .id = .StringLiteral },
28112748 .token = token,
28122749 };
28132750 return &node.base;
......@@ -2816,7 +2753,6 @@ fn parseStringLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Nod
28162753 if (eatToken(it, .MultilineStringLiteralLine)) |first_line| {
28172754 const node = try arena.create(Node.MultilineStringLiteral);
28182755 node.* = Node.MultilineStringLiteral{
2819 .base = Node{ .id = .MultilineStringLiteral },
28202756 .lines = Node.MultilineStringLiteral.LineList.init(arena),
28212757 };
28222758 try node.lines.push(first_line);
......@@ -2833,7 +2769,6 @@ fn parseIntegerLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
28332769 const token = eatToken(it, .IntegerLiteral) orelse return null;
28342770 const node = try arena.create(Node.IntegerLiteral);
28352771 node.* = Node.IntegerLiteral{
2836 .base = Node{ .id = .IntegerLiteral },
28372772 .token = token,
28382773 };
28392774 return &node.base;
......@@ -2843,7 +2778,6 @@ fn parseFloatLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
28432778 const token = eatToken(it, .FloatLiteral) orelse return null;
28442779 const node = try arena.create(Node.FloatLiteral);
28452780 node.* = Node.FloatLiteral{
2846 .base = Node{ .id = .FloatLiteral },
28472781 .token = token,
28482782 };
28492783 return &node.base;
......@@ -2853,7 +2787,6 @@ fn parseTry(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
28532787 const token = eatToken(it, .Keyword_try) orelse return null;
28542788 const node = try arena.create(Node.PrefixOp);
28552789 node.* = Node.PrefixOp{
2856 .base = Node{ .id = .PrefixOp },
28572790 .op_token = token,
28582791 .op = Node.PrefixOp.Op.Try,
28592792 .rhs = undefined, // set by caller
......@@ -2865,7 +2798,6 @@ fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
28652798 const token = eatToken(it, .Keyword_usingnamespace) orelse return null;
28662799 const node = try arena.create(Node.Use);
28672800 node.* = Node.Use{
2868 .base = Node{ .id = .Use },
28692801 .doc_comments = null,
28702802 .visib_token = null,
28712803 .use_token = token,
......@@ -2891,7 +2823,6 @@ fn parseIf(arena: *Allocator, it: *TokenIterator, tree: *Tree, bodyParseFn: Node
28912823 });
28922824 const else_node = try arena.create(Node.Else);
28932825 else_node.* = Node.Else{
2894 .base = Node{ .id = .Else },
28952826 .else_token = else_token,
28962827 .payload = payload,
28972828 .body = else_expr,
......@@ -2912,7 +2843,6 @@ fn parseDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.D
29122843
29132844 const node = try arena.create(Node.DocComment);
29142845 node.* = Node.DocComment{
2915 .base = Node{ .id = .DocComment },
29162846 .lines = lines,
29172847 };
29182848 return node;
......@@ -2924,7 +2854,6 @@ fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, a
29242854 if (tree.tokensOnSameLine(after_token, comment_token)) {
29252855 const node = try arena.create(Node.DocComment);
29262856 node.* = Node.DocComment{
2927 .base = Node{ .id = .DocComment },
29282857 .lines = Node.DocComment.LineList.init(arena),
29292858 };
29302859 try node.lines.push(comment_token);
......@@ -3031,7 +2960,6 @@ fn parseBinOpExpr(
30312960fn createInfixOp(arena: *Allocator, index: TokenIndex, op: Node.InfixOp.Op) !*Node {
30322961 const node = try arena.create(Node.InfixOp);
30332962 node.* = Node.InfixOp{
3034 .base = Node{ .id = .InfixOp },
30352963 .op_token = index,
30362964 .lhs = undefined,
30372965 .op = op,
lib/std/zig/render.zig+1
......@@ -193,6 +193,7 @@ fn renderRoot(
193193fn renderExtraNewline(tree: *ast.Tree, stream: var, start_col: *usize, node: *ast.Node) @TypeOf(stream).Child.Error!void {
194194 const first_token = node.firstToken();
195195 var prev_token = first_token;
196 if (prev_token == 0) return;
196197 while (tree.tokens.at(prev_token - 1).id == .DocComment) {
197198 prev_token -= 1;
198199 }
lib/std/zig/tokenizer.zig+64-53
......@@ -9,66 +9,77 @@ pub const Token = struct {
99 pub const Keyword = struct {
1010 bytes: []const u8,
1111 id: Id,
12 hash: u32,
13
14 fn init(bytes: []const u8, id: Id) Keyword {
15 @setEvalBranchQuota(2000);
16 return .{
17 .bytes = bytes,
18 .id = id,
19 .hash = std.hash_map.hashString(bytes),
20 };
21 }
1222 };
1323
1424 pub const keywords = [_]Keyword{
15 Keyword{ .bytes = "align", .id = Id.Keyword_align },
16 Keyword{ .bytes = "allowzero", .id = Id.Keyword_allowzero },
17 Keyword{ .bytes = "and", .id = Id.Keyword_and },
18 Keyword{ .bytes = "anyframe", .id = Id.Keyword_anyframe },
19 Keyword{ .bytes = "asm", .id = Id.Keyword_asm },
20 Keyword{ .bytes = "async", .id = Id.Keyword_async },
21 Keyword{ .bytes = "await", .id = Id.Keyword_await },
22 Keyword{ .bytes = "break", .id = Id.Keyword_break },
23 Keyword{ .bytes = "catch", .id = Id.Keyword_catch },
24 Keyword{ .bytes = "comptime", .id = Id.Keyword_comptime },
25 Keyword{ .bytes = "const", .id = Id.Keyword_const },
26 Keyword{ .bytes = "continue", .id = Id.Keyword_continue },
27 Keyword{ .bytes = "defer", .id = Id.Keyword_defer },
28 Keyword{ .bytes = "else", .id = Id.Keyword_else },
29 Keyword{ .bytes = "enum", .id = Id.Keyword_enum },
30 Keyword{ .bytes = "errdefer", .id = Id.Keyword_errdefer },
31 Keyword{ .bytes = "error", .id = Id.Keyword_error },
32 Keyword{ .bytes = "export", .id = Id.Keyword_export },
33 Keyword{ .bytes = "extern", .id = Id.Keyword_extern },
34 Keyword{ .bytes = "false", .id = Id.Keyword_false },
35 Keyword{ .bytes = "fn", .id = Id.Keyword_fn },
36 Keyword{ .bytes = "for", .id = Id.Keyword_for },
37 Keyword{ .bytes = "if", .id = Id.Keyword_if },
38 Keyword{ .bytes = "inline", .id = Id.Keyword_inline },
39 Keyword{ .bytes = "nakedcc", .id = Id.Keyword_nakedcc },
40 Keyword{ .bytes = "noalias", .id = Id.Keyword_noalias },
41 Keyword{ .bytes = "noasync", .id = Id.Keyword_noasync },
42 Keyword{ .bytes = "noinline", .id = Id.Keyword_noinline },
43 Keyword{ .bytes = "null", .id = Id.Keyword_null },
44 Keyword{ .bytes = "or", .id = Id.Keyword_or },
45 Keyword{ .bytes = "orelse", .id = Id.Keyword_orelse },
46 Keyword{ .bytes = "packed", .id = Id.Keyword_packed },
47 Keyword{ .bytes = "pub", .id = Id.Keyword_pub },
48 Keyword{ .bytes = "resume", .id = Id.Keyword_resume },
49 Keyword{ .bytes = "return", .id = Id.Keyword_return },
50 Keyword{ .bytes = "linksection", .id = Id.Keyword_linksection },
51 Keyword{ .bytes = "stdcallcc", .id = Id.Keyword_stdcallcc },
52 Keyword{ .bytes = "struct", .id = Id.Keyword_struct },
53 Keyword{ .bytes = "suspend", .id = Id.Keyword_suspend },
54 Keyword{ .bytes = "switch", .id = Id.Keyword_switch },
55 Keyword{ .bytes = "test", .id = Id.Keyword_test },
56 Keyword{ .bytes = "threadlocal", .id = Id.Keyword_threadlocal },
57 Keyword{ .bytes = "true", .id = Id.Keyword_true },
58 Keyword{ .bytes = "try", .id = Id.Keyword_try },
59 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },
60 Keyword{ .bytes = "union", .id = Id.Keyword_union },
61 Keyword{ .bytes = "unreachable", .id = Id.Keyword_unreachable },
62 Keyword{ .bytes = "usingnamespace", .id = Id.Keyword_usingnamespace },
63 Keyword{ .bytes = "var", .id = Id.Keyword_var },
64 Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile },
65 Keyword{ .bytes = "while", .id = Id.Keyword_while },
25 Keyword.init("align", .Keyword_align),
26 Keyword.init("allowzero", .Keyword_allowzero),
27 Keyword.init("and", .Keyword_and),
28 Keyword.init("anyframe", .Keyword_anyframe),
29 Keyword.init("asm", .Keyword_asm),
30 Keyword.init("async", .Keyword_async),
31 Keyword.init("await", .Keyword_await),
32 Keyword.init("break", .Keyword_break),
33 Keyword.init("catch", .Keyword_catch),
34 Keyword.init("comptime", .Keyword_comptime),
35 Keyword.init("const", .Keyword_const),
36 Keyword.init("continue", .Keyword_continue),
37 Keyword.init("defer", .Keyword_defer),
38 Keyword.init("else", .Keyword_else),
39 Keyword.init("enum", .Keyword_enum),
40 Keyword.init("errdefer", .Keyword_errdefer),
41 Keyword.init("error", .Keyword_error),
42 Keyword.init("export", .Keyword_export),
43 Keyword.init("extern", .Keyword_extern),
44 Keyword.init("false", .Keyword_false),
45 Keyword.init("fn", .Keyword_fn),
46 Keyword.init("for", .Keyword_for),
47 Keyword.init("if", .Keyword_if),
48 Keyword.init("inline", .Keyword_inline),
49 Keyword.init("nakedcc", .Keyword_nakedcc),
50 Keyword.init("noalias", .Keyword_noalias),
51 Keyword.init("noasync", .Keyword_noasync),
52 Keyword.init("noinline", .Keyword_noinline),
53 Keyword.init("null", .Keyword_null),
54 Keyword.init("or", .Keyword_or),
55 Keyword.init("orelse", .Keyword_orelse),
56 Keyword.init("packed", .Keyword_packed),
57 Keyword.init("pub", .Keyword_pub),
58 Keyword.init("resume", .Keyword_resume),
59 Keyword.init("return", .Keyword_return),
60 Keyword.init("linksection", .Keyword_linksection),
61 Keyword.init("stdcallcc", .Keyword_stdcallcc),
62 Keyword.init("struct", .Keyword_struct),
63 Keyword.init("suspend", .Keyword_suspend),
64 Keyword.init("switch", .Keyword_switch),
65 Keyword.init("test", .Keyword_test),
66 Keyword.init("threadlocal", .Keyword_threadlocal),
67 Keyword.init("true", .Keyword_true),
68 Keyword.init("try", .Keyword_try),
69 Keyword.init("undefined", .Keyword_undefined),
70 Keyword.init("union", .Keyword_union),
71 Keyword.init("unreachable", .Keyword_unreachable),
72 Keyword.init("usingnamespace", .Keyword_usingnamespace),
73 Keyword.init("var", .Keyword_var),
74 Keyword.init("volatile", .Keyword_volatile),
75 Keyword.init("while", .Keyword_while),
6676 };
6777
6878 // TODO perfect hash at comptime
69 fn getKeyword(bytes: []const u8) ?Id {
79 pub fn getKeyword(bytes: []const u8) ?Id {
80 var hash = std.hash_map.hashString(bytes);
7081 for (keywords) |kw| {
71 if (mem.eql(u8, kw.bytes, bytes)) {
82 if (kw.hash == hash and mem.eql(u8, kw.bytes, bytes)) {
7283 return kw.id;
7384 }
7485 }
src-self-hosted/clang.zig+15-1
......@@ -713,6 +713,10 @@ pub const ZigClangRecordDecl_field_iterator = extern struct {
713713 opaque: *c_void,
714714};
715715
716pub const ZigClangEnumDecl_enumerator_iterator = extern struct {
717 opaque: *c_void,
718};
719
716720pub extern fn ZigClangSourceManager_getSpellingLoc(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation;
717721pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*:0]const u8;
718722pub extern fn ZigClangSourceManager_getSpellingLineNumber(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
......@@ -723,7 +727,7 @@ pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*st
723727pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager;
724728pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, *const struct_ZigClangDecl) bool) bool;
725729pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl;
726pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) ?*const struct_ZigClangEnumDecl;
730pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl;
727731pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;
728732pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
729733pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
......@@ -742,6 +746,11 @@ pub extern fn ZigClangRecordDecl_field_iterator_next(ZigClangRecordDecl_field_it
742746pub extern fn ZigClangRecordDecl_field_iterator_deref(ZigClangRecordDecl_field_iterator) *const struct_ZigClangFieldDecl;
743747pub extern fn ZigClangRecordDecl_field_iterator_neq(ZigClangRecordDecl_field_iterator, ZigClangRecordDecl_field_iterator) bool;
744748pub extern fn ZigClangEnumDecl_getIntegerType(self: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType;
749pub extern fn ZigClangEnumDecl_enumerator_begin(*const ZigClangEnumDecl) ZigClangEnumDecl_enumerator_iterator;
750pub extern fn ZigClangEnumDecl_enumerator_end(*const ZigClangEnumDecl) ZigClangEnumDecl_enumerator_iterator;
751pub extern fn ZigClangEnumDecl_enumerator_iterator_next(ZigClangEnumDecl_enumerator_iterator) ZigClangEnumDecl_enumerator_iterator;
752pub extern fn ZigClangEnumDecl_enumerator_iterator_deref(ZigClangEnumDecl_enumerator_iterator) *const ZigClangEnumConstantDecl;
753pub extern fn ZigClangEnumDecl_enumerator_iterator_neq(ZigClangEnumDecl_enumerator_iterator, ZigClangEnumDecl_enumerator_iterator) bool;
745754pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8;
746755pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
747756pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) *const struct_ZigClangTypedefNameDecl;
......@@ -992,6 +1001,8 @@ pub extern fn ZigClangBinaryOperator_getLHS(*const ZigClangBinaryOperator) *cons
9921001pub extern fn ZigClangBinaryOperator_getRHS(*const ZigClangBinaryOperator) *const ZigClangExpr;
9931002pub extern fn ZigClangBinaryOperator_getType(*const ZigClangBinaryOperator) ZigClangQualType;
9941003
1004pub extern fn ZigClangDecayedType_getDecayedType(*const ZigClangDecayedType) ZigClangQualType;
1005
9951006pub extern fn ZigClangStringLiteral_getKind(*const ZigClangStringLiteral) ZigClangStringLiteral_StringKind;
9961007pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangStringLiteral, *usize) [*c]const u8;
9971008
......@@ -1000,3 +1011,6 @@ pub extern fn ZigClangParenExpr_getSubExpr(*const ZigClangParenExpr) *const ZigC
10001011pub extern fn ZigClangFieldDecl_isBitField(*const struct_ZigClangFieldDecl) bool;
10011012pub extern fn ZigClangFieldDecl_getType(*const struct_ZigClangFieldDecl) struct_ZigClangQualType;
10021013pub extern fn ZigClangFieldDecl_getLocation(*const struct_ZigClangFieldDecl) struct_ZigClangSourceLocation;
1014
1015pub extern fn ZigClangEnumConstantDecl_getInitExpr(*const ZigClangEnumConstantDecl) ?*const ZigClangExpr;
1016pub extern fn ZigClangEnumConstantDecl_getInitVal(*const ZigClangEnumConstantDecl) *const ZigClangAPSInt;
src-self-hosted/translate_c.zig+287-77
......@@ -15,7 +15,7 @@ pub const Error = error{OutOfMemory};
1515const TypeError = Error || error{UnsupportedType};
1616const TransError = TypeError || error{UnsupportedTranslation};
1717
18const DeclTable = std.HashMap(usize, void, addrHash, addrEql);
18const DeclTable = std.HashMap(usize, []const u8, addrHash, addrEql);
1919
2020fn addrHash(x: usize) u32 {
2121 switch (@typeInfo(usize).Int.bits) {
......@@ -109,6 +109,12 @@ const Context = struct {
109109 global_scope: *Scope.Root,
110110 ptr_params: std.BufSet,
111111 clang_context: *ZigClangASTContext,
112 mangle_count: u64 = 0,
113
114 fn getMangle(c: *Context) u64 {
115 c.mangle_count += 1;
116 return c.mangle_count;
117 }
112118
113119 fn a(c: *Context) *std.mem.Allocator {
114120 return &c.tree.arena_allocator.allocator;
......@@ -239,7 +245,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
239245 return resolveTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl));
240246 },
241247 .Enum => {
242 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for enums", .{});
248 _ = try transEnumDecl(c, @ptrCast(*const ZigClangEnumDecl, decl));
243249 },
244250 .Record => {
245251 return resolveRecordDecl(c, @ptrCast(*const ZigClangRecordDecl, decl));
......@@ -255,9 +261,10 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
255261}
256262
257263fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
258 if (try c.decl_table.put(@ptrToInt(fn_decl), {})) |_| return; // Avoid processing this decl twice
264 if (c.decl_table.contains(@ptrToInt(fn_decl))) return; // Avoid processing this decl twice
259265 const rp = makeRestorePoint(c);
260266 const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl)));
267 _ = try c.decl_table.put(@ptrToInt(fn_decl), fn_name);
261268 const fn_decl_loc = ZigClangFunctionDecl_getLocation(fn_decl);
262269 const fn_qt = ZigClangFunctionDecl_getType(fn_decl);
263270 const fn_type = ZigClangQualType_getTypePtr(fn_qt);
......@@ -319,7 +326,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
319326}
320327
321328fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
322 if (try c.decl_table.put(@ptrToInt(var_decl), {})) |_| return; // Avoid processing this decl twice
329 if (c.decl_table.contains(@ptrToInt(var_decl))) return; // Avoid processing this decl twice
323330 const rp = makeRestorePoint(c);
324331 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
325332
......@@ -330,6 +337,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
330337
331338 var scope = &c.global_scope.base;
332339 const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl)));
340 _ = try c.decl_table.put(@ptrToInt(var_decl), var_name);
333341 const var_decl_loc = ZigClangVarDecl_getLocation(var_decl);
334342
335343 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
......@@ -348,7 +356,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
348356 else
349357 try appendToken(c, .Keyword_var, "var");
350358
351 const name_tok = try appendToken(c, .Identifier, var_name);
359 const name_tok = try appendIdentifier(c, var_name);
352360
353361 _ = try appendToken(c, .Colon, ":");
354362 const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) {
......@@ -381,7 +389,6 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
381389
382390 const node = try c.a().create(ast.Node.VarDecl);
383391 node.* = ast.Node.VarDecl{
384 .base = ast.Node{ .id = .VarDecl },
385392 .doc_comments = null,
386393 .visib_token = visib_tok,
387394 .thread_local_token = thread_local_token,
......@@ -401,13 +408,16 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
401408}
402409
403410fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!void {
404 if (try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), {})) |_| return; // Avoid processing this decl twice
411 if (c.decl_table.contains(
412 @ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)),
413 )) return; // Avoid processing this decl twice
405414 const rp = makeRestorePoint(c);
406415 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
407416 const const_tok = try appendToken(c, .Keyword_const, "const");
408417
409418 const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
410 const name_tok = try appendToken(c, .Identifier, typedef_name);
419 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), typedef_name);
420 const name_tok = try appendIdentifier(c, typedef_name);
411421 const eq_tok = try appendToken(c, .Equal, "=");
412422
413423 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
......@@ -421,7 +431,6 @@ fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Err
421431
422432 const node = try c.a().create(ast.Node.VarDecl);
423433 node.* = ast.Node.VarDecl{
424 .base = ast.Node{ .id = .VarDecl },
425434 .doc_comments = null,
426435 .visib_token = visib_tok,
427436 .thread_local_token = null,
......@@ -441,7 +450,7 @@ fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Err
441450}
442451
443452fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!void {
444 if (try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), {})) |_| return; // Avoid processing this decl twice
453 if (c.decl_table.contains(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)))) return; // Avoid processing this decl twice
445454 const rp = makeRestorePoint(c);
446455
447456 const bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, record_decl)));
......@@ -451,7 +460,7 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!
451460 else if (ZigClangRecordDecl_isStruct(record_decl))
452461 "struct"
453462 else
454 return failDecl(c, ZigClangRecordDecl_getLocation(record_decl), bare_name, "record {} is not a struct or union", .{bare_name});
463 return emitWarning(c, ZigClangRecordDecl_getLocation(record_decl), "record {} is not a struct or union", .{bare_name});
455464
456465 if (ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) or bare_name.len == 0)
457466 return;
......@@ -460,7 +469,8 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!
460469 const const_tok = try appendToken(c, .Keyword_const, "const");
461470
462471 const name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name });
463 const name_tok = try appendToken(c, .Identifier, name);
472 _ = try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), name);
473 const name_tok = try appendIdentifier(c, name);
464474
465475 const eq_tok = try appendToken(c, .Equal, "=");
466476 const init_node = transRecordDecl(c, record_decl) catch |err| switch (err) {
......@@ -473,7 +483,6 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!
473483
474484 const node = try c.a().create(ast.Node.VarDecl);
475485 node.* = ast.Node.VarDecl{
476 .base = ast.Node{ .id = .VarDecl },
477486 .doc_comments = null,
478487 .visib_token = visib_tok,
479488 .thread_local_token = null,
......@@ -497,14 +506,13 @@ fn resolveRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!
497506fn createAlias(c: *Context, alias: var) !void {
498507 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
499508 const mut_tok = try appendToken(c, .Keyword_const, "const");
500 const name_tok = try appendToken(c, .Identifier, alias.alias);
509 const name_tok = try appendIdentifier(c, alias.alias);
501510
502511 const eq_tok = try appendToken(c, .Equal, "=");
503 const init_node = try appendIdentifier(c, alias.name);
512 const init_node = try transCreateNodeIdentifier(c, alias.name);
504513
505514 const node = try c.a().create(ast.Node.VarDecl);
506515 node.* = ast.Node.VarDecl{
507 .base = ast.Node{ .id = .VarDecl },
508516 .doc_comments = null,
509517 .visib_token = visib_tok,
510518 .thread_local_token = null,
......@@ -787,7 +795,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe
787795 const c_name = try c.str(ZigClangDecl_getName_bytes_begin(
788796 @ptrCast(*const ZigClangDecl, var_decl),
789797 ));
790 const name_token = try appendToken(c, .Identifier, c_name);
798 const name_token = try appendIdentifier(c, c_name);
791799
792800 const var_scope = try c.a().create(Scope.Var);
793801 var_scope.* = Scope.Var{
......@@ -810,7 +818,6 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe
810818
811819 const node = try c.a().create(ast.Node.VarDecl);
812820 node.* = ast.Node.VarDecl{
813 .base = ast.Node{ .id = .VarDecl },
814821 .doc_comments = null,
815822 .visib_token = null,
816823 .thread_local_token = thread_local_token,
......@@ -856,7 +863,7 @@ fn transDeclRefExpr(
856863 const c_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl)));
857864 const zig_name = transLookupZigIdentifier(scope, c_name);
858865 if (lrvalue == .l_value) try rp.c.ptr_params.put(zig_name);
859 const node = try appendIdentifier(rp.c, zig_name);
866 const node = try transCreateNodeIdentifier(rp.c, zig_name);
860867 return TransResult{
861868 .node = node,
862869 .node_scope = scope,
......@@ -978,7 +985,6 @@ fn transStringLiteral(
978985 const token = try appendToken(rp.c, .StringLiteral, buf);
979986 const node = try rp.c.a().create(ast.Node.StringLiteral);
980987 node.* = ast.Node.StringLiteral{
981 .base = ast.Node{ .id = .StringLiteral },
982988 .token = token,
983989 };
984990 const res = TransResult{
......@@ -1145,7 +1151,6 @@ fn transInitListExpr(
11451151 const mul_tok = try appendToken(rp.c, .AsteriskAsterisk, "**");
11461152 const mul_node = try rp.c.a().create(ast.Node.InfixOp);
11471153 mul_node.* = .{
1148 .base = .{ .id = .InfixOp },
11491154 .op_token = mul_tok,
11501155 .lhs = &filler_init_node.base,
11511156 .op = .ArrayMult,
......@@ -1164,7 +1169,6 @@ fn transInitListExpr(
11641169
11651170 const cat_node = try rp.c.a().create(ast.Node.InfixOp);
11661171 cat_node.* = .{
1167 .base = .{ .id = .InfixOp },
11681172 .op_token = cat_tok,
11691173 .lhs = &init_node.base,
11701174 .op = .ArrayCat,
......@@ -1292,11 +1296,10 @@ fn maybeSuppressResult(
12921296 if (used == .used) return result;
12931297 // NOTE: This is backwards, but the semicolon must immediately follow the node.
12941298 _ = try appendToken(rp.c, .Semicolon, ";");
1295 const lhs = try appendIdentifier(rp.c, "_");
1299 const lhs = try transCreateNodeIdentifier(rp.c, "_");
12961300 const op_token = try appendToken(rp.c, .Equal, "=");
12971301 const op_node = try rp.c.a().create(ast.Node.InfixOp);
12981302 op_node.* = ast.Node.InfixOp{
1299 .base = ast.Node{ .id = .InfixOp },
13001303 .op_token = op_token,
13011304 .lhs = lhs,
13021305 .op = .Assign,
......@@ -1352,7 +1355,6 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro
13521355
13531356 const container_node = try c.a().create(ast.Node.ContainerDecl);
13541357 container_node.* = .{
1355 .base = ast.Node{ .id = .ContainerDecl },
13561358 .layout_token = extern_tok,
13571359 .kind_token = container_tok,
13581360 .init_arg_expr = .None,
......@@ -1374,7 +1376,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro
13741376 return node;
13751377 }
13761378
1377 const field_name = try appendToken(c, .Identifier, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))));
1379 const field_name = try appendIdentifier(c, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))));
13781380 _ = try appendToken(c, .Colon, ":");
13791381 const field_type = try transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc);
13801382
......@@ -1396,6 +1398,195 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) TypeErro
13961398 return &container_node.base;
13971399}
13981400
1401fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.Node {
1402 if (c.decl_table.get(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)))) |name|
1403 return try transCreateNodeIdentifier(c, name.value); // Avoid processing this decl twice
1404 const rp = makeRestorePoint(c);
1405 const enum_loc = ZigClangEnumDecl_getLocation(enum_decl);
1406
1407 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
1408 const const_tok = try appendToken(c, .Keyword_const, "const");
1409
1410 var bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_decl)));
1411 var is_unnamed = false;
1412 if (bare_name.len == 0) {
1413 bare_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});
1414 is_unnamed = true;
1415 }
1416
1417 const name = try std.fmt.allocPrint(c.a(), "enum_{}", .{bare_name});
1418 _ = try c.decl_table.put(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)), name);
1419 const name_tok = try appendIdentifier(c, name);
1420 const eq_tok = try appendToken(c, .Equal, "=");
1421
1422 const init_node = if (ZigClangEnumDecl_getDefinition(enum_decl)) |enum_def| blk: {
1423 var pure_enum = true;
1424 var it = ZigClangEnumDecl_enumerator_begin(enum_def);
1425 var end_it = ZigClangEnumDecl_enumerator_end(enum_def);
1426 while (ZigClangEnumDecl_enumerator_iterator_neq(it, end_it)) : (it = ZigClangEnumDecl_enumerator_iterator_next(it)) {
1427 const enum_const = ZigClangEnumDecl_enumerator_iterator_deref(it);
1428 if (ZigClangEnumConstantDecl_getInitExpr(enum_const)) |_| {
1429 pure_enum = false;
1430 break;
1431 }
1432 }
1433
1434 const extern_tok = try appendToken(c, .Keyword_extern, "extern");
1435 const container_tok = try appendToken(c, .Keyword_enum, "enum");
1436
1437 const container_node = try c.a().create(ast.Node.ContainerDecl);
1438 container_node.* = .{
1439 .layout_token = extern_tok,
1440 .kind_token = container_tok,
1441 .init_arg_expr = .None,
1442 .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(c.a()),
1443 .lbrace_token = undefined,
1444 .rbrace_token = undefined,
1445 };
1446
1447 const int_type = ZigClangEnumDecl_getIntegerType(enum_decl);
1448
1449 // TODO only emit this tag type if the enum tag type is not the default.
1450 // I don't know what the default is, need to figure out how clang is deciding.
1451 // it appears to at least be different across gcc/msvc
1452 if (!isCBuiltinType(int_type, .UInt) and
1453 !isCBuiltinType(int_type, .Int))
1454 {
1455 _ = try appendToken(c, .LParen, "(");
1456 container_node.init_arg_expr = .{
1457 .Type = transQualType(rp, int_type, enum_loc) catch |err| switch (err) {
1458 error.UnsupportedType => {
1459 if (is_unnamed) {
1460 try emitWarning(c, enum_loc, "unable to translate enum tag type", .{});
1461 } else {
1462 try failDecl(c, enum_loc, name, "unable to translate enum tag type", .{});
1463 }
1464 return null;
1465 },
1466 else => |e| return e,
1467 },
1468 };
1469 _ = try appendToken(c, .RParen, ")");
1470 }
1471
1472 container_node.lbrace_token = try appendToken(c, .LBrace, "{");
1473
1474 it = ZigClangEnumDecl_enumerator_begin(enum_def);
1475 end_it = ZigClangEnumDecl_enumerator_end(enum_def);
1476 while (ZigClangEnumDecl_enumerator_iterator_neq(it, end_it)) : (it = ZigClangEnumDecl_enumerator_iterator_next(it)) {
1477 const enum_const = ZigClangEnumDecl_enumerator_iterator_deref(it);
1478
1479 const enum_val_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_const)));
1480
1481 const field_name = if (!is_unnamed and std.mem.startsWith(u8, enum_val_name, bare_name))
1482 enum_val_name[bare_name.len..]
1483 else
1484 enum_val_name;
1485
1486 const field_name_tok = try appendIdentifier(c, field_name);
1487
1488 const int_node = if (!pure_enum) blk: {
1489 _ = try appendToken(c, .Colon, "=");
1490 break :blk try transCreateNodeAPInt(c, ZigClangEnumConstantDecl_getInitVal(enum_const));
1491 } else
1492 null;
1493
1494 const field_node = try c.a().create(ast.Node.ContainerField);
1495 field_node.* = .{
1496 .doc_comments = null,
1497 .comptime_token = null,
1498 .name_token = field_name_tok,
1499 .type_expr = null,
1500 .value_expr = int_node,
1501 .align_expr = null,
1502 };
1503
1504 try container_node.fields_and_decls.push(&field_node.base);
1505 _ = try appendToken(c, .Comma, ",");
1506 // In C each enum value is in the global namespace. So we put them there too.
1507 // At this point we can rely on the enum emitting successfully.
1508 try addEnumTopLevel(c, name, field_name, enum_val_name);
1509 }
1510 container_node.rbrace_token = try appendToken(c, .RBrace, "}");
1511
1512 break :blk &container_node.base;
1513 } else
1514 try transCreateNodeOpaqueType(c);
1515
1516 const semicolon_token = try appendToken(c, .Semicolon, ";");
1517
1518 const node = try c.a().create(ast.Node.VarDecl);
1519 node.* = ast.Node.VarDecl{
1520 .visib_token = visib_tok,
1521 .mut_token = const_tok,
1522 .name_token = name_tok,
1523 .eq_token = eq_tok,
1524 .init_node = init_node,
1525 .semicolon_token = semicolon_token,
1526 .doc_comments = null,
1527 .comptime_token = null,
1528 .extern_export_token = null,
1529 .thread_local_token = null,
1530 .lib_name = null,
1531 .type_node = null,
1532 .align_node = null,
1533 .section_node = null,
1534 };
1535
1536 try addTopLevelDecl(c, name, &node.base);
1537 if (!is_unnamed)
1538 try c.alias_list.push(.{ .alias = bare_name, .name = name });
1539 return transCreateNodeIdentifier(c, name);
1540}
1541
1542fn addEnumTopLevel(c: *Context, enum_name: []const u8, field_name: []const u8, enum_val_name: []const u8) !void {
1543 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
1544 const const_tok = try appendToken(c, .Keyword_const, "const");
1545 const name_tok = try appendIdentifier(c, enum_val_name);
1546 const eq_tok = try appendToken(c, .Equal, "=");
1547
1548 const enum_ident = try transCreateNodeIdentifier(c, enum_name);
1549 const period_tok = try appendToken(c, .Period, ".");
1550 const field_ident = try transCreateNodeIdentifier(c, field_name);
1551
1552 const field_access_node = try c.a().create(ast.Node.InfixOp);
1553 field_access_node.* = .{
1554 .op_token = period_tok,
1555 .lhs = enum_ident,
1556 .op = .Period,
1557 .rhs = field_ident,
1558 };
1559 const semicolon_token = try appendToken(c, .Semicolon, ";");
1560
1561 const node = try c.a().create(ast.Node.VarDecl);
1562 node.* = ast.Node.VarDecl{
1563 .visib_token = visib_tok,
1564 .mut_token = const_tok,
1565 .name_token = name_tok,
1566 .eq_token = eq_tok,
1567 .init_node = &field_access_node.base,
1568 .semicolon_token = semicolon_token,
1569 .thread_local_token = null,
1570 .doc_comments = null,
1571 .comptime_token = null,
1572 .extern_export_token = null,
1573 .lib_name = null,
1574 .type_node = null,
1575 .align_node = null,
1576 .section_node = null,
1577 };
1578
1579 try addTopLevelDecl(c, field_name, &node.base);
1580}
1581
1582fn isCBuiltinType(qt: ZigClangQualType, kind: ZigClangBuiltinTypeKind) bool {
1583 const c_type = qualTypeCanon(qt);
1584 if (ZigClangType_getTypeClass(c_type) != .Builtin)
1585 return false;
1586 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, c_type);
1587 return ZigClangBuiltinType_getKind(builtin_ty) == kind;
1588}
1589
13991590fn qualTypeIsPtr(qt: ZigClangQualType) bool {
14001591 return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer;
14011592}
......@@ -1523,7 +1714,6 @@ fn transCreateNodeAssign(
15231714
15241715 const node = try rp.c.a().create(ast.Node.InfixOp);
15251716 node.* = ast.Node.InfixOp{
1526 .base = ast.Node{ .id = .InfixOp },
15271717 .op_token = eq_token,
15281718 .lhs = lhs_node.node,
15291719 .op = .Assign,
......@@ -1553,7 +1743,6 @@ fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.Builti
15531743 _ = try appendToken(c, .LParen, "(");
15541744 const node = try c.a().create(ast.Node.BuiltinCall);
15551745 node.* = ast.Node.BuiltinCall{
1556 .base = ast.Node{ .id = .BuiltinCall },
15571746 .builtin_token = builtin_token,
15581747 .params = ast.Node.BuiltinCall.ParamList.init(c.a()),
15591748 .rparen_token = undefined, // set after appending args
......@@ -1565,7 +1754,6 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
15651754 _ = try appendToken(c, .LParen, "(");
15661755 const node = try c.a().create(ast.Node.SuffixOp);
15671756 node.* = ast.Node.SuffixOp{
1568 .base = ast.Node{ .id = .SuffixOp },
15691757 .lhs = fn_expr,
15701758 .op = ast.Node.SuffixOp.Op{
15711759 .Call = ast.Node.SuffixOp.Op.Call{
......@@ -1586,7 +1774,6 @@ fn transCreateNodePrefixOp(
15861774) !*ast.Node.PrefixOp {
15871775 const node = try c.a().create(ast.Node.PrefixOp);
15881776 node.* = ast.Node.PrefixOp{
1589 .base = ast.Node{ .id = .PrefixOp },
15901777 .op_token = try appendToken(c, op_tok_id, bytes),
15911778 .op = op,
15921779 .rhs = undefined, // translate and set afterward
......@@ -1609,7 +1796,6 @@ fn transCreateNodeInfixOp(
16091796 const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
16101797 const node = try rp.c.a().create(ast.Node.InfixOp);
16111798 node.* = ast.Node.InfixOp{
1612 .base = ast.Node{ .id = .InfixOp },
16131799 .op_token = op_token,
16141800 .lhs = lhs.node,
16151801 .op = op,
......@@ -1619,7 +1805,6 @@ fn transCreateNodeInfixOp(
16191805 const rparen = try appendToken(rp.c, .RParen, ")");
16201806 const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
16211807 grouped_expr.* = ast.Node.GroupedExpression{
1622 .base = ast.Node{ .id = .GroupedExpression },
16231808 .lparen = lparen,
16241809 .expr = &node.base,
16251810 .rparen = rparen,
......@@ -1644,7 +1829,7 @@ fn transCreateNodePtrType(
16441829 .Identifier => blk: {
16451830 const lbracket = try appendToken(c, .LBracket, "["); // Rendering checks if this token + 2 == .Identifier, so needs to return this token
16461831 _ = try appendToken(c, .Asterisk, "*");
1647 _ = try appendToken(c, .Identifier, "c");
1832 _ = try appendIdentifier(c, "c");
16481833 _ = try appendToken(c, .RBracket, "]");
16491834 break :blk lbracket;
16501835 },
......@@ -1652,7 +1837,6 @@ fn transCreateNodePtrType(
16521837 else => unreachable,
16531838 };
16541839 node.* = ast.Node.PrefixOp{
1655 .base = ast.Node{ .id = .PrefixOp },
16561840 .op_token = op_token,
16571841 .op = ast.Node.PrefixOp.Op{
16581842 .PtrType = .{
......@@ -1679,7 +1863,6 @@ fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node {
16791863 const token = try appendToken(c, .IntegerLiteral, str);
16801864 const node = try c.a().create(ast.Node.IntegerLiteral);
16811865 node.* = ast.Node.IntegerLiteral{
1682 .base = ast.Node{ .id = .IntegerLiteral },
16831866 .token = token,
16841867 };
16851868 return &node.base;
......@@ -1689,7 +1872,6 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node {
16891872 const ltoken = try appendToken(c, .Keyword_return, "return");
16901873 const node = try c.a().create(ast.Node.ControlFlowExpression);
16911874 node.* = ast.Node.ControlFlowExpression{
1692 .base = ast.Node{ .id = .ControlFlowExpression },
16931875 .ltoken = ltoken,
16941876 .kind = .Return,
16951877 .rhs = null,
......@@ -1701,7 +1883,6 @@ fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
17011883 const token = try appendToken(c, .Keyword_undefined, "undefined");
17021884 const node = try c.a().create(ast.Node.UndefinedLiteral);
17031885 node.* = ast.Node.UndefinedLiteral{
1704 .base = ast.Node{ .id = .UndefinedLiteral },
17051886 .token = token,
17061887 };
17071888 return &node.base;
......@@ -1711,7 +1892,6 @@ fn transCreateNodeNullLiteral(c: *Context) !*ast.Node {
17111892 const token = try appendToken(c, .Keyword_null, "null");
17121893 const node = try c.a().create(ast.Node.NullLiteral);
17131894 node.* = ast.Node.NullLiteral{
1714 .base = ast.Node{ .id = .NullLiteral },
17151895 .token = token,
17161896 };
17171897 return &node.base;
......@@ -1724,7 +1904,6 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
17241904 try appendToken(c, .Keyword_false, "false");
17251905 const node = try c.a().create(ast.Node.BoolLiteral);
17261906 node.* = ast.Node.BoolLiteral{
1727 .base = ast.Node{ .id = .BoolLiteral },
17281907 .token = token,
17291908 };
17301909 return &node.base;
......@@ -1734,7 +1913,6 @@ fn transCreateNodeArrayInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.N
17341913 _ = try appendToken(c, .LBrace, "{");
17351914 const node = try c.a().create(ast.Node.SuffixOp);
17361915 node.* = ast.Node.SuffixOp{
1737 .base = ast.Node{ .id = .SuffixOp },
17381916 .lhs = .{ .dot = dot_tok },
17391917 .op = .{
17401918 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
......@@ -1748,7 +1926,6 @@ fn transCreateNodeInt(c: *Context, int: var) !*ast.Node {
17481926 const token = try appendTokenFmt(c, .IntegerLiteral, "{}", .{int});
17491927 const node = try c.a().create(ast.Node.IntegerLiteral);
17501928 node.* = ast.Node.IntegerLiteral{
1751 .base = ast.Node{ .id = .IntegerLiteral },
17521929 .token = token,
17531930 };
17541931 return &node.base;
......@@ -1793,25 +1970,25 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
17931970 .Builtin => {
17941971 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
17951972 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
1796 .Void => return appendIdentifier(rp.c, "c_void"),
1797 .Bool => return appendIdentifier(rp.c, "bool"),
1798 .Char_U, .UChar, .Char_S, .Char8 => return appendIdentifier(rp.c, "u8"),
1799 .SChar => return appendIdentifier(rp.c, "i8"),
1800 .UShort => return appendIdentifier(rp.c, "c_ushort"),
1801 .UInt => return appendIdentifier(rp.c, "c_uint"),
1802 .ULong => return appendIdentifier(rp.c, "c_ulong"),
1803 .ULongLong => return appendIdentifier(rp.c, "c_ulonglong"),
1804 .Short => return appendIdentifier(rp.c, "c_short"),
1805 .Int => return appendIdentifier(rp.c, "c_int"),
1806 .Long => return appendIdentifier(rp.c, "c_long"),
1807 .LongLong => return appendIdentifier(rp.c, "c_longlong"),
1808 .UInt128 => return appendIdentifier(rp.c, "u128"),
1809 .Int128 => return appendIdentifier(rp.c, "i128"),
1810 .Float => return appendIdentifier(rp.c, "f32"),
1811 .Double => return appendIdentifier(rp.c, "f64"),
1812 .Float128 => return appendIdentifier(rp.c, "f128"),
1813 .Float16 => return appendIdentifier(rp.c, "f16"),
1814 .LongDouble => return appendIdentifier(rp.c, "c_longdouble"),
1973 .Void => return transCreateNodeIdentifier(rp.c, "c_void"),
1974 .Bool => return transCreateNodeIdentifier(rp.c, "bool"),
1975 .Char_U, .UChar, .Char_S, .Char8 => return transCreateNodeIdentifier(rp.c, "u8"),
1976 .SChar => return transCreateNodeIdentifier(rp.c, "i8"),
1977 .UShort => return transCreateNodeIdentifier(rp.c, "c_ushort"),
1978 .UInt => return transCreateNodeIdentifier(rp.c, "c_uint"),
1979 .ULong => return transCreateNodeIdentifier(rp.c, "c_ulong"),
1980 .ULongLong => return transCreateNodeIdentifier(rp.c, "c_ulonglong"),
1981 .Short => return transCreateNodeIdentifier(rp.c, "c_short"),
1982 .Int => return transCreateNodeIdentifier(rp.c, "c_int"),
1983 .Long => return transCreateNodeIdentifier(rp.c, "c_long"),
1984 .LongLong => return transCreateNodeIdentifier(rp.c, "c_longlong"),
1985 .UInt128 => return transCreateNodeIdentifier(rp.c, "u128"),
1986 .Int128 => return transCreateNodeIdentifier(rp.c, "i128"),
1987 .Float => return transCreateNodeIdentifier(rp.c, "f32"),
1988 .Double => return transCreateNodeIdentifier(rp.c, "f64"),
1989 .Float128 => return transCreateNodeIdentifier(rp.c, "f128"),
1990 .Float16 => return transCreateNodeIdentifier(rp.c, "f16"),
1991 .LongDouble => return transCreateNodeIdentifier(rp.c, "c_longdouble"),
18151992 else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
18161993 }
18171994 },
......@@ -1891,21 +2068,36 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
18912068
18922069 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
18932070 const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
1894 return appendIdentifier(rp.c, typedef_name);
2071 return transCreateNodeIdentifier(rp.c, typedef_name);
18952072 },
18962073 .Record => {
18972074 const record_ty = @ptrCast(*const ZigClangRecordType, ty);
18982075
18992076 const record_decl = ZigClangRecordType_getDecl(record_ty);
1900 if (try getContainerName(rp.c, record_decl)) |name|
1901 return appendIdentifier(rp.c, name)
2077 if (try getContainerName(rp, record_decl)) |name|
2078 return transCreateNodeIdentifier(rp.c, name)
19022079 else
19032080 return transRecordDecl(rp.c, record_decl);
19042081 },
2082 .Enum => {
2083 const enum_ty = @ptrCast(*const ZigClangEnumType, ty);
2084
2085 const enum_decl = ZigClangEnumType_getDecl(enum_ty);
2086 return (try transEnumDecl(rp.c, enum_decl)) orelse
2087 revertAndWarn(rp, error.UnsupportedType, source_loc, "unable to translate enum declaration", .{});
2088 },
19052089 .Elaborated => {
19062090 const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty);
19072091 return transQualType(rp, ZigClangElaboratedType_getNamedType(elaborated_ty), source_loc);
19082092 },
2093 .Decayed => {
2094 const decayed_ty = @ptrCast(*const ZigClangDecayedType, ty);
2095 return transQualType(rp, ZigClangDecayedType_getDecayedType(decayed_ty), source_loc);
2096 },
2097 .Attributed => {
2098 const attributed_ty = @ptrCast(*const ZigClangAttributedType, ty);
2099 return transQualType(rp, ZigClangAttributedType_getEquivalentType(attributed_ty), source_loc);
2100 },
19092101 else => {
19102102 const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));
19112103 return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name});
......@@ -1913,22 +2105,20 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
19132105 }
19142106}
19152107
1916fn getContainerName(c: *Context, record_decl: *const ZigClangRecordDecl) !?[]const u8 {
1917 const bare_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, record_decl)));
2108fn getContainerName(rp: RestorePoint, record_decl: *const ZigClangRecordDecl) !?[]const u8 {
2109 const bare_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, record_decl)));
19182110
19192111 const container_kind_name = if (ZigClangRecordDecl_isUnion(record_decl))
19202112 "union"
19212113 else if (ZigClangRecordDecl_isStruct(record_decl))
19222114 "struct"
1923 else {
1924 try emitWarning(c, ZigClangRecordDecl_getLocation(record_decl), "record {} is not a struct or union", .{bare_name});
1925 return null;
1926 };
2115 else
2116 return revertAndWarn(rp, error.UnsupportedType, ZigClangRecordDecl_getLocation(record_decl), "record {} is not a struct or union", .{bare_name});
19272117
19282118 if (ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) or bare_name.len == 0)
19292119 return null;
19302120
1931 return try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name });
2121 return try std.fmt.allocPrint(rp.c.a(), "{}_{}", .{ container_kind_name, bare_name });
19322122}
19332123
19342124fn isCVoid(qt: ZigClangQualType) bool {
......@@ -2020,7 +2210,7 @@ fn finishTransFnProto(
20202210 else
20212211 null;
20222212 const fn_tok = try appendToken(rp.c, .Keyword_fn, "fn");
2023 const name_tok = if (fn_decl_context) |ctx| try appendToken(rp.c, .Identifier, ctx.fn_name) else null;
2213 const name_tok = if (fn_decl_context) |ctx| try appendIdentifier(rp.c, ctx.fn_name) else null;
20242214 const lparen_tok = try appendToken(rp.c, .LParen, "(");
20252215
20262216 var fn_params = ast.Node.FnProto.ParamList.init(rp.c.a());
......@@ -2038,7 +2228,7 @@ fn finishTransFnProto(
20382228 const param_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param)));
20392229 if (param_name.len > 0) {
20402230 // TODO: If len == 0, auto-generate arg1, arg2, etc? Or leave the name blank?
2041 const result = try appendToken(rp.c, .Identifier, param_name);
2231 const result = try appendIdentifier(rp.c, param_name);
20422232 _ = try appendToken(rp.c, .Colon, ":");
20432233 break :blk result;
20442234 }
......@@ -2087,12 +2277,12 @@ fn finishTransFnProto(
20872277
20882278 const return_type_node = blk: {
20892279 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
2090 break :blk try appendIdentifier(rp.c, "noreturn");
2280 break :blk try transCreateNodeIdentifier(rp.c, "noreturn");
20912281 } else {
20922282 const return_qt = ZigClangFunctionType_getReturnType(fn_ty);
20932283 if (isCVoid(return_qt)) {
20942284 // convert primitive c_void to actual void (only for return type)
2095 break :blk try appendIdentifier(rp.c, "void");
2285 break :blk try transCreateNodeIdentifier(rp.c, "void");
20962286 } else {
20972287 break :blk transQualType(rp, return_qt, source_loc) catch |err| switch (err) {
20982288 error.UnsupportedType => {
......@@ -2145,7 +2335,7 @@ fn emitWarning(c: *Context, loc: ZigClangSourceLocation, comptime format: []cons
21452335fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime format: []const u8, args: var) !void {
21462336 // const name = @compileError(msg);
21472337 const const_tok = try appendToken(c, .Keyword_const, "const");
2148 const name_tok = try appendToken(c, .Identifier, name);
2338 const name_tok = try appendIdentifier(c, name);
21492339 const eq_tok = try appendToken(c, .Equal, "=");
21502340 const builtin_tok = try appendToken(c, .Builtin, "@compileError");
21512341 const lparen_tok = try appendToken(c, .LParen, "(");
......@@ -2190,6 +2380,7 @@ fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime
21902380}
21912381
21922382fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenIndex {
2383 std.debug.assert(token_id != .Identifier); // use appendIdentifier
21932384 return appendTokenFmt(c, token_id, "{}", .{bytes});
21942385}
21952386
......@@ -2218,8 +2409,27 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
22182409 return token_index;
22192410}
22202411
2221fn appendIdentifier(c: *Context, name: []const u8) !*ast.Node {
2222 const token_index = try appendToken(c, .Identifier, name);
2412fn isValidZigIdentifier(name: []const u8) bool {
2413 for (name) |c, i| {
2414 switch (c) {
2415 '_', 'a'...'z', 'A'...'Z' => {},
2416 '0'...'9' => if (i == 0) return false,
2417 else => return false,
2418 }
2419 }
2420 return true;
2421}
2422
2423fn appendIdentifier(c: *Context, name: []const u8) !ast.TokenIndex {
2424 if (!isValidZigIdentifier(name) or std.zig.Token.getKeyword(name) != null) {
2425 return appendTokenFmt(c, .Identifier, "@\"{}\"", .{name});
2426 } else {
2427 return appendTokenFmt(c, .Identifier, "{}", .{name});
2428 }
2429}
2430
2431fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node {
2432 const token_index = try appendIdentifier(c, name);
22232433 const identifier = try c.a().create(ast.Node.Identifier);
22242434 identifier.* = ast.Node.Identifier{
22252435 .base = ast.Node{ .id = ast.Node.Id.Identifier },
test/translate_c.zig+69-3
......@@ -217,6 +217,72 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
217217 \\pub const OpenGLProcs = union_OpenGLProcs;
218218 });
219219
220 cases.add_2("enums",
221 \\typedef enum {
222 \\ a,
223 \\ b,
224 \\ c,
225 \\} d;
226 \\enum {
227 \\ e,
228 \\ f = 4,
229 \\ g,
230 \\} h = e;
231 \\struct Baz {
232 \\ enum {
233 \\ i,
234 \\ j,
235 \\ k,
236 \\ } l;
237 \\ d m;
238 \\};
239 \\enum i {
240 \\ n,
241 \\ o,
242 \\ p,
243 \\};
244 , &[_][]const u8{
245 \\pub const a = enum_unnamed_1.a;
246 \\pub const b = enum_unnamed_1.b;
247 \\pub const c = enum_unnamed_1.c;
248 \\pub const enum_unnamed_1 = extern enum {
249 \\ a,
250 \\ b,
251 \\ c,
252 \\};
253 \\pub const d = enum_unnamed_1;
254 \\pub const e = enum_unnamed_2.e;
255 \\pub const f = enum_unnamed_2.f;
256 \\pub const g = enum_unnamed_2.g;
257 \\pub const enum_unnamed_2 = extern enum {
258 \\ e = 0,
259 \\ f = 4,
260 \\ g = 5,
261 \\};
262 \\pub export var h: enum_unnamed_2 = @as(enum_unnamed_2, e);
263 \\pub const i = enum_unnamed_3.i;
264 \\pub const j = enum_unnamed_3.j;
265 \\pub const k = enum_unnamed_3.k;
266 \\pub const enum_unnamed_3 = extern enum {
267 \\ i,
268 \\ j,
269 \\ k,
270 \\};
271 \\pub const struct_Baz = extern struct {
272 \\ l: enum_unnamed_3,
273 \\ m: d,
274 \\};
275 \\pub const n = enum_i.n;
276 \\pub const o = enum_i.o;
277 \\pub const p = enum_i.p;
278 \\pub const enum_i = extern enum {
279 \\ n,
280 \\ o,
281 \\ p,
282 \\};
283 \\pub const Baz = struct_Baz;
284 });
285
220286 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
221287
222288 cases.add_both("typedef of function in struct field",
......@@ -440,7 +506,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
440506 \\}
441507 });
442508
443 cases.add("enums",
509 cases.add_both("enums",
444510 \\enum Foo {
445511 \\ FooA,
446512 \\ FooB,
......@@ -462,7 +528,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
462528 \\pub const Foo = enum_Foo;
463529 });
464530
465 cases.add("enums",
531 cases.add_both("enums",
466532 \\enum Foo {
467533 \\ FooA = 2,
468534 \\ FooB = 5,
......@@ -686,7 +752,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
686752 \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
687753 });
688754
689 cases.add("zig keywords in C code",
755 cases.add_both("zig keywords in C code",
690756 \\struct comptime {
691757 \\ int defer;
692758 \\};