| author | |
| committer | |
| log | ccc7f9987debd2112d1432f7aa58a81a0814e81d |
| tree | 351b1853c4f9ede39eb6c5b5c539fc070c8b2a72 |
| parent | 9fa723ee5043a9d2cb017e417f2e27041f671146 |
The grammar for function prototypes, (global) variable declarations, and
pointer types now accepts an optional addrspace(A) modifier.4 files changed, 135 insertions(+), 30 deletions(-)
lib/std/zig/Ast.zig+50-4| ... | ... | @@ -262,6 +262,9 @@ pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void { |
| 262 | 262 | token_tags[parse_error.token].symbol(), |
| 263 | 263 | }); |
| 264 | 264 | }, |
| 265 | .extra_addrspace_qualifier => { | |
| 266 | return stream.writeAll("extra addrspace qualifier"); | |
| 267 | }, | |
| 265 | 268 | .extra_align_qualifier => { |
| 266 | 269 | return stream.writeAll("extra align qualifier"); |
| 267 | 270 | }, |
| ... | ... | @@ -1021,7 +1024,7 @@ pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex { |
| 1021 | 1024 | }, |
| 1022 | 1025 | .fn_proto_one => { |
| 1023 | 1026 | const extra = tree.extraData(datas[n].lhs, Node.FnProtoOne); |
| 1024 | // linksection, callconv, align can appear in any order, so we | |
| 1027 | // addrspace, linksection, callconv, align can appear in any order, so we | |
| 1025 | 1028 | // find the last one here. |
| 1026 | 1029 | var max_node: Node.Index = datas[n].rhs; |
| 1027 | 1030 | var max_start = token_starts[main_tokens[max_node]]; |
| ... | ... | @@ -1034,6 +1037,14 @@ pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex { |
| 1034 | 1037 | max_offset = 1; // for the rparen |
| 1035 | 1038 | } |
| 1036 | 1039 | } |
| 1040 | if (extra.addrspace_expr != 0) { | |
| 1041 | const start = token_starts[main_tokens[extra.addrspace_expr]]; | |
| 1042 | if (start > max_start) { | |
| 1043 | max_node = extra.addrspace_expr; | |
| 1044 | max_start = start; | |
| 1045 | max_offset = 1; // for the rparen | |
| 1046 | } | |
| 1047 | } | |
| 1037 | 1048 | if (extra.section_expr != 0) { |
| 1038 | 1049 | const start = token_starts[main_tokens[extra.section_expr]]; |
| 1039 | 1050 | if (start > max_start) { |
| ... | ... | @@ -1055,7 +1066,7 @@ pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex { |
| 1055 | 1066 | }, |
| 1056 | 1067 | .fn_proto => { |
| 1057 | 1068 | const extra = tree.extraData(datas[n].lhs, Node.FnProto); |
| 1058 | // linksection, callconv, align can appear in any order, so we | |
| 1069 | // addrspace, linksection, callconv, align can appear in any order, so we | |
| 1059 | 1070 | // find the last one here. |
| 1060 | 1071 | var max_node: Node.Index = datas[n].rhs; |
| 1061 | 1072 | var max_start = token_starts[main_tokens[max_node]]; |
| ... | ... | @@ -1068,6 +1079,14 @@ pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex { |
| 1068 | 1079 | max_offset = 1; // for the rparen |
| 1069 | 1080 | } |
| 1070 | 1081 | } |
| 1082 | if (extra.addrspace_expr != 0) { | |
| 1083 | const start = token_starts[main_tokens[extra.addrspace_expr]]; | |
| 1084 | if (start > max_start) { | |
| 1085 | max_node = extra.addrspace_expr; | |
| 1086 | max_start = start; | |
| 1087 | max_offset = 1; // for the rparen | |
| 1088 | } | |
| 1089 | } | |
| 1071 | 1090 | if (extra.section_expr != 0) { |
| 1072 | 1091 | const start = token_starts[main_tokens[extra.section_expr]]; |
| 1073 | 1092 | if (start > max_start) { |
| ... | ... | @@ -1138,6 +1157,7 @@ pub fn globalVarDecl(tree: Tree, node: Node.Index) full.VarDecl { |
| 1138 | 1157 | return tree.fullVarDecl(.{ |
| 1139 | 1158 | .type_node = extra.type_node, |
| 1140 | 1159 | .align_node = extra.align_node, |
| 1160 | .addrspace_node = extra.addrspace_node, | |
| 1141 | 1161 | .section_node = extra.section_node, |
| 1142 | 1162 | .init_node = data.rhs, |
| 1143 | 1163 | .mut_token = tree.nodes.items(.main_token)[node], |
| ... | ... | @@ -1151,6 +1171,7 @@ pub fn localVarDecl(tree: Tree, node: Node.Index) full.VarDecl { |
| 1151 | 1171 | return tree.fullVarDecl(.{ |
| 1152 | 1172 | .type_node = extra.type_node, |
| 1153 | 1173 | .align_node = extra.align_node, |
| 1174 | .addrspace_node = 0, | |
| 1154 | 1175 | .section_node = 0, |
| 1155 | 1176 | .init_node = data.rhs, |
| 1156 | 1177 | .mut_token = tree.nodes.items(.main_token)[node], |
| ... | ... | @@ -1163,6 +1184,7 @@ pub fn simpleVarDecl(tree: Tree, node: Node.Index) full.VarDecl { |
| 1163 | 1184 | return tree.fullVarDecl(.{ |
| 1164 | 1185 | .type_node = data.lhs, |
| 1165 | 1186 | .align_node = 0, |
| 1187 | .addrspace_node = 0, | |
| 1166 | 1188 | .section_node = 0, |
| 1167 | 1189 | .init_node = data.rhs, |
| 1168 | 1190 | .mut_token = tree.nodes.items(.main_token)[node], |
| ... | ... | @@ -1175,6 +1197,7 @@ pub fn alignedVarDecl(tree: Tree, node: Node.Index) full.VarDecl { |
| 1175 | 1197 | return tree.fullVarDecl(.{ |
| 1176 | 1198 | .type_node = 0, |
| 1177 | 1199 | .align_node = data.lhs, |
| 1200 | .addrspace_node = 0, | |
| 1178 | 1201 | .section_node = 0, |
| 1179 | 1202 | .init_node = data.rhs, |
| 1180 | 1203 | .mut_token = tree.nodes.items(.main_token)[node], |
| ... | ... | @@ -1249,6 +1272,7 @@ pub fn fnProtoSimple(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full. |
| 1249 | 1272 | .return_type = data.rhs, |
| 1250 | 1273 | .params = params, |
| 1251 | 1274 | .align_expr = 0, |
| 1275 | .addrspace_expr = 0, | |
| 1252 | 1276 | .section_expr = 0, |
| 1253 | 1277 | .callconv_expr = 0, |
| 1254 | 1278 | }); |
| ... | ... | @@ -1265,6 +1289,7 @@ pub fn fnProtoMulti(tree: Tree, node: Node.Index) full.FnProto { |
| 1265 | 1289 | .return_type = data.rhs, |
| 1266 | 1290 | .params = params, |
| 1267 | 1291 | .align_expr = 0, |
| 1292 | .addrspace_expr = 0, | |
| 1268 | 1293 | .section_expr = 0, |
| 1269 | 1294 | .callconv_expr = 0, |
| 1270 | 1295 | }); |
| ... | ... | @@ -1282,6 +1307,7 @@ pub fn fnProtoOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.FnP |
| 1282 | 1307 | .return_type = data.rhs, |
| 1283 | 1308 | .params = params, |
| 1284 | 1309 | .align_expr = extra.align_expr, |
| 1310 | .addrspace_expr = extra.addrspace_expr, | |
| 1285 | 1311 | .section_expr = extra.section_expr, |
| 1286 | 1312 | .callconv_expr = extra.callconv_expr, |
| 1287 | 1313 | }); |
| ... | ... | @@ -1298,6 +1324,7 @@ pub fn fnProto(tree: Tree, node: Node.Index) full.FnProto { |
| 1298 | 1324 | .return_type = data.rhs, |
| 1299 | 1325 | .params = params, |
| 1300 | 1326 | .align_expr = extra.align_expr, |
| 1327 | .addrspace_expr = extra.addrspace_expr, | |
| 1301 | 1328 | .section_expr = extra.section_expr, |
| 1302 | 1329 | .callconv_expr = extra.callconv_expr, |
| 1303 | 1330 | }); |
| ... | ... | @@ -1453,6 +1480,7 @@ pub fn ptrTypeAligned(tree: Tree, node: Node.Index) full.PtrType { |
| 1453 | 1480 | return tree.fullPtrType(.{ |
| 1454 | 1481 | .main_token = tree.nodes.items(.main_token)[node], |
| 1455 | 1482 | .align_node = data.lhs, |
| 1483 | .addrspace_node = 0, | |
| 1456 | 1484 | .sentinel = 0, |
| 1457 | 1485 | .bit_range_start = 0, |
| 1458 | 1486 | .bit_range_end = 0, |
| ... | ... | @@ -1466,6 +1494,7 @@ pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) full.PtrType { |
| 1466 | 1494 | return tree.fullPtrType(.{ |
| 1467 | 1495 | .main_token = tree.nodes.items(.main_token)[node], |
| 1468 | 1496 | .align_node = 0, |
| 1497 | .addrspace_node = 0, | |
| 1469 | 1498 | .sentinel = data.lhs, |
| 1470 | 1499 | .bit_range_start = 0, |
| 1471 | 1500 | .bit_range_end = 0, |
| ... | ... | @@ -1480,6 +1509,7 @@ pub fn ptrType(tree: Tree, node: Node.Index) full.PtrType { |
| 1480 | 1509 | return tree.fullPtrType(.{ |
| 1481 | 1510 | .main_token = tree.nodes.items(.main_token)[node], |
| 1482 | 1511 | .align_node = extra.align_node, |
| 1512 | .addrspace_node = extra.addrspace_node, | |
| 1483 | 1513 | .sentinel = extra.sentinel, |
| 1484 | 1514 | .bit_range_start = 0, |
| 1485 | 1515 | .bit_range_end = 0, |
| ... | ... | @@ -1494,6 +1524,7 @@ pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) full.PtrType { |
| 1494 | 1524 | return tree.fullPtrType(.{ |
| 1495 | 1525 | .main_token = tree.nodes.items(.main_token)[node], |
| 1496 | 1526 | .align_node = extra.align_node, |
| 1527 | .addrspace_node = extra.addrspace_node, | |
| 1497 | 1528 | .sentinel = extra.sentinel, |
| 1498 | 1529 | .bit_range_start = extra.bit_range_start, |
| 1499 | 1530 | .bit_range_end = extra.bit_range_end, |
| ... | ... | @@ -2063,6 +2094,7 @@ pub const full = struct { |
| 2063 | 2094 | mut_token: TokenIndex, |
| 2064 | 2095 | type_node: Node.Index, |
| 2065 | 2096 | align_node: Node.Index, |
| 2097 | addrspace_node: Node.Index, | |
| 2066 | 2098 | section_node: Node.Index, |
| 2067 | 2099 | init_node: Node.Index, |
| 2068 | 2100 | }; |
| ... | ... | @@ -2130,6 +2162,7 @@ pub const full = struct { |
| 2130 | 2162 | return_type: Node.Index, |
| 2131 | 2163 | params: []const Node.Index, |
| 2132 | 2164 | align_expr: Node.Index, |
| 2165 | addrspace_expr: Node.Index, | |
| 2133 | 2166 | section_expr: Node.Index, |
| 2134 | 2167 | callconv_expr: Node.Index, |
| 2135 | 2168 | }; |
| ... | ... | @@ -2288,6 +2321,7 @@ pub const full = struct { |
| 2288 | 2321 | pub const Components = struct { |
| 2289 | 2322 | main_token: TokenIndex, |
| 2290 | 2323 | align_node: Node.Index, |
| 2324 | addrspace_node: Node.Index, | |
| 2291 | 2325 | sentinel: Node.Index, |
| 2292 | 2326 | bit_range_start: Node.Index, |
| 2293 | 2327 | bit_range_end: Node.Index, |
| ... | ... | @@ -2397,6 +2431,7 @@ pub const Error = struct { |
| 2397 | 2431 | expected_var_decl_or_fn, |
| 2398 | 2432 | expected_loop_payload, |
| 2399 | 2433 | expected_container, |
| 2434 | extra_addrspace_qualifier, | |
| 2400 | 2435 | extra_align_qualifier, |
| 2401 | 2436 | extra_allowzero_qualifier, |
| 2402 | 2437 | extra_const_qualifier, |
| ... | ... | @@ -2723,13 +2758,13 @@ pub const Node = struct { |
| 2723 | 2758 | /// main_token is the `fn` keyword. |
| 2724 | 2759 | /// extern function declarations use this tag. |
| 2725 | 2760 | fn_proto_multi, |
| 2726 | /// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`. | |
| 2761 | /// `fn(a: b) rhs addrspace(e) linksection(f) callconv(g)`. `FnProtoOne[lhs]`. | |
| 2727 | 2762 | /// zero or one parameters. |
| 2728 | 2763 | /// anytype and ... parameters are omitted from the AST tree. |
| 2729 | 2764 | /// main_token is the `fn` keyword. |
| 2730 | 2765 | /// extern function declarations use this tag. |
| 2731 | 2766 | fn_proto_one, |
| 2732 | /// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`. | |
| 2767 | /// `fn(a: b, c: d) rhs addrspace(e) linksection(f) callconv(g)`. `FnProto[lhs]`. | |
| 2733 | 2768 | /// anytype and ... parameters are omitted from the AST tree. |
| 2734 | 2769 | /// main_token is the `fn` keyword. |
| 2735 | 2770 | /// extern function declarations use this tag. |
| ... | ... | @@ -2893,11 +2928,13 @@ pub const Node = struct { |
| 2893 | 2928 | pub const PtrType = struct { |
| 2894 | 2929 | sentinel: Index, |
| 2895 | 2930 | align_node: Index, |
| 2931 | addrspace_node: Index, | |
| 2896 | 2932 | }; |
| 2897 | 2933 | |
| 2898 | 2934 | pub const PtrTypeBitRange = struct { |
| 2899 | 2935 | sentinel: Index, |
| 2900 | 2936 | align_node: Index, |
| 2937 | addrspace_node: Index, | |
| 2901 | 2938 | bit_range_start: Index, |
| 2902 | 2939 | bit_range_end: Index, |
| 2903 | 2940 | }; |
| ... | ... | @@ -2920,8 +2957,13 @@ pub const Node = struct { |
| 2920 | 2957 | }; |
| 2921 | 2958 | |
| 2922 | 2959 | pub const GlobalVarDecl = struct { |
| 2960 | /// Populated if there is an explicit type ascription. | |
| 2923 | 2961 | type_node: Index, |
| 2962 | /// Populated if align(A) is present. | |
| 2924 | 2963 | align_node: Index, |
| 2964 | /// Populated if linksection(A) is present. | |
| 2965 | addrspace_node: Index, | |
| 2966 | /// Populated if addrspace(A) is present. | |
| 2925 | 2967 | section_node: Index, |
| 2926 | 2968 | }; |
| 2927 | 2969 | |
| ... | ... | @@ -2954,6 +2996,8 @@ pub const Node = struct { |
| 2954 | 2996 | /// Populated if align(A) is present. |
| 2955 | 2997 | align_expr: Index, |
| 2956 | 2998 | /// Populated if linksection(A) is present. |
| 2999 | addrspace_expr: Index, | |
| 3000 | /// Populated if addrspace(A) is present. | |
| 2957 | 3001 | section_expr: Index, |
| 2958 | 3002 | /// Populated if callconv(A) is present. |
| 2959 | 3003 | callconv_expr: Index, |
| ... | ... | @@ -2964,6 +3008,8 @@ pub const Node = struct { |
| 2964 | 3008 | params_end: Index, |
| 2965 | 3009 | /// Populated if align(A) is present. |
| 2966 | 3010 | align_expr: Index, |
| 3011 | /// Populated if addrspace(A) is present. | |
| 3012 | addrspace_expr: Index, | |
| 2967 | 3013 | /// Populated if linksection(A) is present. |
| 2968 | 3014 | section_expr: Index, |
| 2969 | 3015 | /// Populated if callconv(A) is present. |
lib/std/zig/parse.zig+81-26| ... | ... | @@ -629,7 +629,7 @@ const Parser = struct { |
| 629 | 629 | }; |
| 630 | 630 | } |
| 631 | 631 | |
| 632 | /// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr | |
| 632 | /// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr | |
| 633 | 633 | fn parseFnProto(p: *Parser) !Node.Index { |
| 634 | 634 | const fn_token = p.eatToken(.keyword_fn) orelse return null_node; |
| 635 | 635 | |
| ... | ... | @@ -639,6 +639,7 @@ const Parser = struct { |
| 639 | 639 | _ = p.eatToken(.identifier); |
| 640 | 640 | const params = try p.parseParamDeclList(); |
| 641 | 641 | const align_expr = try p.parseByteAlign(); |
| 642 | const addrspace_expr = try p.parseAddrSpace(); | |
| 642 | 643 | const section_expr = try p.parseLinkSection(); |
| 643 | 644 | const callconv_expr = try p.parseCallconv(); |
| 644 | 645 | _ = p.eatToken(.bang); |
| ... | ... | @@ -650,7 +651,7 @@ const Parser = struct { |
| 650 | 651 | try p.warn(.expected_return_type); |
| 651 | 652 | } |
| 652 | 653 | |
| 653 | if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) { | |
| 654 | if (align_expr == 0 and section_expr == 0 and callconv_expr == 0 and addrspace_expr == 0) { | |
| 654 | 655 | switch (params) { |
| 655 | 656 | .zero_or_one => |param| return p.setNode(fn_proto_index, .{ |
| 656 | 657 | .tag = .fn_proto_simple, |
| ... | ... | @@ -683,6 +684,7 @@ const Parser = struct { |
| 683 | 684 | .lhs = try p.addExtra(Node.FnProtoOne{ |
| 684 | 685 | .param = param, |
| 685 | 686 | .align_expr = align_expr, |
| 687 | .addrspace_expr = addrspace_expr, | |
| 686 | 688 | .section_expr = section_expr, |
| 687 | 689 | .callconv_expr = callconv_expr, |
| 688 | 690 | }), |
| ... | ... | @@ -698,6 +700,7 @@ const Parser = struct { |
| 698 | 700 | .params_start = span.start, |
| 699 | 701 | .params_end = span.end, |
| 700 | 702 | .align_expr = align_expr, |
| 703 | .addrspace_expr = addrspace_expr, | |
| 701 | 704 | .section_expr = section_expr, |
| 702 | 705 | .callconv_expr = callconv_expr, |
| 703 | 706 | }), |
| ... | ... | @@ -708,7 +711,7 @@ const Parser = struct { |
| 708 | 711 | } |
| 709 | 712 | } |
| 710 | 713 | |
| 711 | /// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON | |
| 714 | /// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? AddrSpace? LinkSection? (EQUAL Expr)? SEMICOLON | |
| 712 | 715 | fn parseVarDecl(p: *Parser) !Node.Index { |
| 713 | 716 | const mut_token = p.eatToken(.keyword_const) orelse |
| 714 | 717 | p.eatToken(.keyword_var) orelse |
| ... | ... | @@ -717,9 +720,10 @@ const Parser = struct { |
| 717 | 720 | _ = try p.expectToken(.identifier); |
| 718 | 721 | const type_node: Node.Index = if (p.eatToken(.colon) == null) 0 else try p.expectTypeExpr(); |
| 719 | 722 | const align_node = try p.parseByteAlign(); |
| 723 | const addrspace_node = try p.parseAddrSpace(); | |
| 720 | 724 | const section_node = try p.parseLinkSection(); |
| 721 | 725 | const init_node: Node.Index = if (p.eatToken(.equal) == null) 0 else try p.expectExpr(); |
| 722 | if (section_node == 0) { | |
| 726 | if (section_node == 0 and addrspace_node == 0) { | |
| 723 | 727 | if (align_node == 0) { |
| 724 | 728 | return p.addNode(.{ |
| 725 | 729 | .tag = .simple_var_decl, |
| ... | ... | @@ -759,6 +763,7 @@ const Parser = struct { |
| 759 | 763 | .lhs = try p.addExtra(Node.GlobalVarDecl{ |
| 760 | 764 | .type_node = type_node, |
| 761 | 765 | .align_node = align_node, |
| 766 | .addrspace_node = addrspace_node, | |
| 762 | 767 | .section_node = section_node, |
| 763 | 768 | }), |
| 764 | 769 | .rhs = init_node, |
| ... | ... | @@ -1440,8 +1445,8 @@ const Parser = struct { |
| 1440 | 1445 | /// PrefixTypeOp |
| 1441 | 1446 | /// <- QUESTIONMARK |
| 1442 | 1447 | /// / KEYWORD_anyframe MINUSRARROW |
| 1443 | /// / SliceTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* | |
| 1444 | /// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* | |
| 1448 | /// / SliceTypeStart (ByteAlign / AddrSpace / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* | |
| 1449 | /// / PtrTypeStart (AddrSpace / KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* | |
| 1445 | 1450 | /// / ArrayTypeStart |
| 1446 | 1451 | /// SliceTypeStart <- LBRACKET (COLON Expr)? RBRACKET |
| 1447 | 1452 | /// PtrTypeStart |
| ... | ... | @@ -1474,29 +1479,43 @@ const Parser = struct { |
| 1474 | 1479 | const asterisk = p.nextToken(); |
| 1475 | 1480 | const mods = try p.parsePtrModifiers(); |
| 1476 | 1481 | const elem_type = try p.expectTypeExpr(); |
| 1477 | if (mods.bit_range_start == 0) { | |
| 1482 | if (mods.bit_range_start != 0) { | |
| 1478 | 1483 | return p.addNode(.{ |
| 1479 | .tag = .ptr_type_aligned, | |
| 1484 | .tag = .ptr_type_bit_range, | |
| 1480 | 1485 | .main_token = asterisk, |
| 1481 | 1486 | .data = .{ |
| 1482 | .lhs = mods.align_node, | |
| 1487 | .lhs = try p.addExtra(Node.PtrTypeBitRange{ | |
| 1488 | .sentinel = 0, | |
| 1489 | .align_node = mods.align_node, | |
| 1490 | .addrspace_node = mods.addrspace_node, | |
| 1491 | .bit_range_start = mods.bit_range_start, | |
| 1492 | .bit_range_end = mods.bit_range_end, | |
| 1493 | }), | |
| 1483 | 1494 | .rhs = elem_type, |
| 1484 | 1495 | }, |
| 1485 | 1496 | }); |
| 1486 | } else { | |
| 1497 | } else if (mods.addrspace_node != 0) { | |
| 1487 | 1498 | return p.addNode(.{ |
| 1488 | .tag = .ptr_type_bit_range, | |
| 1499 | .tag = .ptr_type, | |
| 1489 | 1500 | .main_token = asterisk, |
| 1490 | 1501 | .data = .{ |
| 1491 | .lhs = try p.addExtra(Node.PtrTypeBitRange{ | |
| 1502 | .lhs = try p.addExtra(Node.PtrType{ | |
| 1492 | 1503 | .sentinel = 0, |
| 1493 | 1504 | .align_node = mods.align_node, |
| 1494 | .bit_range_start = mods.bit_range_start, | |
| 1495 | .bit_range_end = mods.bit_range_end, | |
| 1505 | .addrspace_node = mods.addrspace_node, | |
| 1496 | 1506 | }), |
| 1497 | 1507 | .rhs = elem_type, |
| 1498 | 1508 | }, |
| 1499 | 1509 | }); |
| 1510 | } else { | |
| 1511 | return p.addNode(.{ | |
| 1512 | .tag = .ptr_type_aligned, | |
| 1513 | .main_token = asterisk, | |
| 1514 | .data = .{ | |
| 1515 | .lhs = mods.align_node, | |
| 1516 | .rhs = elem_type, | |
| 1517 | }, | |
| 1518 | }); | |
| 1500 | 1519 | } |
| 1501 | 1520 | }, |
| 1502 | 1521 | .asterisk_asterisk => { |
| ... | ... | @@ -1504,29 +1523,43 @@ const Parser = struct { |
| 1504 | 1523 | const mods = try p.parsePtrModifiers(); |
| 1505 | 1524 | const elem_type = try p.expectTypeExpr(); |
| 1506 | 1525 | const inner: Node.Index = inner: { |
| 1507 | if (mods.bit_range_start == 0) { | |
| 1526 | if (mods.bit_range_start != 0) { | |
| 1508 | 1527 | break :inner try p.addNode(.{ |
| 1509 | .tag = .ptr_type_aligned, | |
| 1528 | .tag = .ptr_type_bit_range, | |
| 1510 | 1529 | .main_token = asterisk, |
| 1511 | 1530 | .data = .{ |
| 1512 | .lhs = mods.align_node, | |
| 1531 | .lhs = try p.addExtra(Node.PtrTypeBitRange{ | |
| 1532 | .sentinel = 0, | |
| 1533 | .align_node = mods.align_node, | |
| 1534 | .addrspace_node = mods.addrspace_node, | |
| 1535 | .bit_range_start = mods.bit_range_start, | |
| 1536 | .bit_range_end = mods.bit_range_end, | |
| 1537 | }), | |
| 1513 | 1538 | .rhs = elem_type, |
| 1514 | 1539 | }, |
| 1515 | 1540 | }); |
| 1516 | } else { | |
| 1541 | } else if (mods.addrspace_node != 0) { | |
| 1517 | 1542 | break :inner try p.addNode(.{ |
| 1518 | .tag = .ptr_type_bit_range, | |
| 1543 | .tag = .ptr_type, | |
| 1519 | 1544 | .main_token = asterisk, |
| 1520 | 1545 | .data = .{ |
| 1521 | .lhs = try p.addExtra(Node.PtrTypeBitRange{ | |
| 1546 | .lhs = try p.addExtra(Node.PtrType{ | |
| 1522 | 1547 | .sentinel = 0, |
| 1523 | 1548 | .align_node = mods.align_node, |
| 1524 | .bit_range_start = mods.bit_range_start, | |
| 1525 | .bit_range_end = mods.bit_range_end, | |
| 1549 | .addrspace_node = mods.addrspace_node, | |
| 1526 | 1550 | }), |
| 1527 | 1551 | .rhs = elem_type, |
| 1528 | 1552 | }, |
| 1529 | 1553 | }); |
| 1554 | } else { | |
| 1555 | break :inner try p.addNode(.{ | |
| 1556 | .tag = .ptr_type_aligned, | |
| 1557 | .main_token = asterisk, | |
| 1558 | .data = .{ | |
| 1559 | .lhs = mods.align_node, | |
| 1560 | .rhs = elem_type, | |
| 1561 | }, | |
| 1562 | }); | |
| 1530 | 1563 | } |
| 1531 | 1564 | }; |
| 1532 | 1565 | return p.addNode(.{ |
| ... | ... | @@ -1560,7 +1593,7 @@ const Parser = struct { |
| 1560 | 1593 | const mods = try p.parsePtrModifiers(); |
| 1561 | 1594 | const elem_type = try p.expectTypeExpr(); |
| 1562 | 1595 | if (mods.bit_range_start == 0) { |
| 1563 | if (sentinel == 0) { | |
| 1596 | if (sentinel == 0 and mods.addrspace_node == 0) { | |
| 1564 | 1597 | return p.addNode(.{ |
| 1565 | 1598 | .tag = .ptr_type_aligned, |
| 1566 | 1599 | .main_token = asterisk, |
| ... | ... | @@ -1569,7 +1602,7 @@ const Parser = struct { |
| 1569 | 1602 | .rhs = elem_type, |
| 1570 | 1603 | }, |
| 1571 | 1604 | }); |
| 1572 | } else if (mods.align_node == 0) { | |
| 1605 | } else if (mods.align_node == 0 and mods.addrspace_node == 0) { | |
| 1573 | 1606 | return p.addNode(.{ |
| 1574 | 1607 | .tag = .ptr_type_sentinel, |
| 1575 | 1608 | .main_token = asterisk, |
| ... | ... | @@ -1586,6 +1619,7 @@ const Parser = struct { |
| 1586 | 1619 | .lhs = try p.addExtra(Node.PtrType{ |
| 1587 | 1620 | .sentinel = sentinel, |
| 1588 | 1621 | .align_node = mods.align_node, |
| 1622 | .addrspace_node = mods.addrspace_node, | |
| 1589 | 1623 | }), |
| 1590 | 1624 | .rhs = elem_type, |
| 1591 | 1625 | }, |
| ... | ... | @@ -1599,6 +1633,7 @@ const Parser = struct { |
| 1599 | 1633 | .lhs = try p.addExtra(Node.PtrTypeBitRange{ |
| 1600 | 1634 | .sentinel = sentinel, |
| 1601 | 1635 | .align_node = mods.align_node, |
| 1636 | .addrspace_node = mods.addrspace_node, | |
| 1602 | 1637 | .bit_range_start = mods.bit_range_start, |
| 1603 | 1638 | .bit_range_end = mods.bit_range_end, |
| 1604 | 1639 | }), |
| ... | ... | @@ -1624,7 +1659,7 @@ const Parser = struct { |
| 1624 | 1659 | .token = p.nodes.items(.main_token)[mods.bit_range_start], |
| 1625 | 1660 | }); |
| 1626 | 1661 | } |
| 1627 | if (sentinel == 0) { | |
| 1662 | if (sentinel == 0 and mods.addrspace_node == 0) { | |
| 1628 | 1663 | return p.addNode(.{ |
| 1629 | 1664 | .tag = .ptr_type_aligned, |
| 1630 | 1665 | .main_token = lbracket, |
| ... | ... | @@ -1633,7 +1668,7 @@ const Parser = struct { |
| 1633 | 1668 | .rhs = elem_type, |
| 1634 | 1669 | }, |
| 1635 | 1670 | }); |
| 1636 | } else if (mods.align_node == 0) { | |
| 1671 | } else if (mods.align_node == 0 and mods.addrspace_node == 0) { | |
| 1637 | 1672 | return p.addNode(.{ |
| 1638 | 1673 | .tag = .ptr_type_sentinel, |
| 1639 | 1674 | .main_token = lbracket, |
| ... | ... | @@ -1650,6 +1685,7 @@ const Parser = struct { |
| 1650 | 1685 | .lhs = try p.addExtra(Node.PtrType{ |
| 1651 | 1686 | .sentinel = sentinel, |
| 1652 | 1687 | .align_node = mods.align_node, |
| 1688 | .addrspace_node = mods.addrspace_node, | |
| 1653 | 1689 | }), |
| 1654 | 1690 | .rhs = elem_type, |
| 1655 | 1691 | }, |
| ... | ... | @@ -1661,6 +1697,7 @@ const Parser = struct { |
| 1661 | 1697 | .keyword_const, |
| 1662 | 1698 | .keyword_volatile, |
| 1663 | 1699 | .keyword_allowzero, |
| 1700 | .keyword_addrspace, | |
| 1664 | 1701 | => return p.fail(.ptr_mod_on_array_child_type), |
| 1665 | 1702 | else => {}, |
| 1666 | 1703 | } |
| ... | ... | @@ -2879,6 +2916,15 @@ const Parser = struct { |
| 2879 | 2916 | return expr_node; |
| 2880 | 2917 | } |
| 2881 | 2918 | |
| 2919 | /// AddrSpace <- KEYWORD_addrspace LPAREN Expr RPAREN | |
| 2920 | fn parseAddrSpace(p: *Parser) !Node.Index { | |
| 2921 | _ = p.eatToken(.keyword_addrspace) orelse return null_node; | |
| 2922 | _ = try p.expectToken(.l_paren); | |
| 2923 | const expr_node = try p.expectExpr(); | |
| 2924 | _ = try p.expectToken(.r_paren); | |
| 2925 | return expr_node; | |
| 2926 | } | |
| 2927 | ||
| 2882 | 2928 | /// ParamDecl |
| 2883 | 2929 | /// <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType |
| 2884 | 2930 | /// / DOT3 |
| ... | ... | @@ -3011,6 +3057,7 @@ const Parser = struct { |
| 3011 | 3057 | |
| 3012 | 3058 | const PtrModifiers = struct { |
| 3013 | 3059 | align_node: Node.Index, |
| 3060 | addrspace_node: Node.Index, | |
| 3014 | 3061 | bit_range_start: Node.Index, |
| 3015 | 3062 | bit_range_end: Node.Index, |
| 3016 | 3063 | }; |
| ... | ... | @@ -3018,12 +3065,14 @@ const Parser = struct { |
| 3018 | 3065 | fn parsePtrModifiers(p: *Parser) !PtrModifiers { |
| 3019 | 3066 | var result: PtrModifiers = .{ |
| 3020 | 3067 | .align_node = 0, |
| 3068 | .addrspace_node = 0, | |
| 3021 | 3069 | .bit_range_start = 0, |
| 3022 | 3070 | .bit_range_end = 0, |
| 3023 | 3071 | }; |
| 3024 | 3072 | var saw_const = false; |
| 3025 | 3073 | var saw_volatile = false; |
| 3026 | 3074 | var saw_allowzero = false; |
| 3075 | var saw_addrspace = false; | |
| 3027 | 3076 | while (true) { |
| 3028 | 3077 | switch (p.token_tags[p.tok_i]) { |
| 3029 | 3078 | .keyword_align => { |
| ... | ... | @@ -3063,6 +3112,12 @@ const Parser = struct { |
| 3063 | 3112 | p.tok_i += 1; |
| 3064 | 3113 | saw_allowzero = true; |
| 3065 | 3114 | }, |
| 3115 | .keyword_addrspace => { | |
| 3116 | if (saw_addrspace) { | |
| 3117 | try p.warn(.extra_addrspace_qualifier); | |
| 3118 | } | |
| 3119 | result.addrspace_node = try p.parseAddrSpace(); | |
| 3120 | }, | |
| 3066 | 3121 | else => return result, |
| 3067 | 3122 | } |
| 3068 | 3123 | } |
lib/std/zig/tokenizer.zig+3| ... | ... | @@ -11,6 +11,7 @@ pub const Token = struct { |
| 11 | 11 | }; |
| 12 | 12 | |
| 13 | 13 | pub const keywords = std.ComptimeStringMap(Tag, .{ |
| 14 | .{ "addrspace", .keyword_addrspace }, | |
| 14 | 15 | .{ "align", .keyword_align }, |
| 15 | 16 | .{ "allowzero", .keyword_allowzero }, |
| 16 | 17 | .{ "and", .keyword_and }, |
| ... | ... | @@ -132,6 +133,7 @@ pub const Token = struct { |
| 132 | 133 | float_literal, |
| 133 | 134 | doc_comment, |
| 134 | 135 | container_doc_comment, |
| 136 | keyword_addrspace, | |
| 135 | 137 | keyword_align, |
| 136 | 138 | keyword_allowzero, |
| 137 | 139 | keyword_and, |
| ... | ... | @@ -251,6 +253,7 @@ pub const Token = struct { |
| 251 | 253 | .angle_bracket_angle_bracket_right => ">>", |
| 252 | 254 | .angle_bracket_angle_bracket_right_equal => ">>=", |
| 253 | 255 | .tilde => "~", |
| 256 | .keyword_addrspace => "addrspace", | |
| 254 | 257 | .keyword_align => "align", |
| 255 | 258 | .keyword_allowzero => "allowzero", |
| 256 | 259 | .keyword_and => "and", |
src/translate_c/ast.zig+1| ... | ... | @@ -2614,6 +2614,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex { |
| 2614 | 2614 | .type_node = type_node, |
| 2615 | 2615 | .align_node = align_node, |
| 2616 | 2616 | .section_node = section_node, |
| 2617 | .addrspace_node = 0, | |
| 2617 | 2618 | }), |
| 2618 | 2619 | .rhs = init_node, |
| 2619 | 2620 | }, |