authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-09-02 14:45:00+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-09-20 02:29:03+02:00
logccc7f9987debd2112d1432f7aa58a81a0814e81d
tree351b1853c4f9ede39eb6c5b5c539fc070c8b2a72
parent9fa723ee5043a9d2cb017e417f2e27041f671146

Address spaces: addrspace(A) parsing

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