| author | |
| committer | |
| log | d2a8660d0467c024790c7dcdeb9366d993723fd7 |
| tree | 07323947e797161c2c182dca99a16de6116f22ce |
| parent | 54f4abae2f811c6de1d5c5156961e1bd75405aa6 |
ref: 9d538ea0253bb63c0b35ec907a3a734d1e22fc3217 files changed, 979 insertions(+), 675 deletions(-)
deps/aro/aro/Builtins/Builtin.def+152| ... | ... | @@ -17008,3 +17008,155 @@ wmemmove |
| 17008 | 17008 | .param_str = "w*w*wC*z" |
| 17009 | 17009 | .header = .wchar |
| 17010 | 17010 | .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true } |
| 17011 | ||
| 17012 | __c11_atomic_init | |
| 17013 | .param_str = "v." | |
| 17014 | .attributes = .{ .custom_typecheck = true } | |
| 17015 | ||
| 17016 | __c11_atomic_load | |
| 17017 | .param_str = "v." | |
| 17018 | .attributes = .{ .custom_typecheck = true } | |
| 17019 | ||
| 17020 | __c11_atomic_store | |
| 17021 | .param_str = "v." | |
| 17022 | .attributes = .{ .custom_typecheck = true } | |
| 17023 | ||
| 17024 | __c11_atomic_exchange | |
| 17025 | .param_str = "v." | |
| 17026 | .attributes = .{ .custom_typecheck = true } | |
| 17027 | ||
| 17028 | __c11_atomic_compare_exchange_strong | |
| 17029 | .param_str = "v." | |
| 17030 | .attributes = .{ .custom_typecheck = true } | |
| 17031 | ||
| 17032 | __c11_atomic_compare_exchange_weak | |
| 17033 | .param_str = "v." | |
| 17034 | .attributes = .{ .custom_typecheck = true } | |
| 17035 | ||
| 17036 | __c11_atomic_fetch_add | |
| 17037 | .param_str = "v." | |
| 17038 | .attributes = .{ .custom_typecheck = true } | |
| 17039 | ||
| 17040 | __c11_atomic_fetch_sub | |
| 17041 | .param_str = "v." | |
| 17042 | .attributes = .{ .custom_typecheck = true } | |
| 17043 | ||
| 17044 | __c11_atomic_fetch_and | |
| 17045 | .param_str = "v." | |
| 17046 | .attributes = .{ .custom_typecheck = true } | |
| 17047 | ||
| 17048 | __c11_atomic_fetch_or | |
| 17049 | .param_str = "v." | |
| 17050 | .attributes = .{ .custom_typecheck = true } | |
| 17051 | ||
| 17052 | __c11_atomic_fetch_xor | |
| 17053 | .param_str = "v." | |
| 17054 | .attributes = .{ .custom_typecheck = true } | |
| 17055 | ||
| 17056 | __c11_atomic_fetch_nand | |
| 17057 | .param_str = "v." | |
| 17058 | .attributes = .{ .custom_typecheck = true } | |
| 17059 | ||
| 17060 | __c11_atomic_fetch_max | |
| 17061 | .param_str = "v." | |
| 17062 | .attributes = .{ .custom_typecheck = true } | |
| 17063 | ||
| 17064 | __c11_atomic_fetch_min | |
| 17065 | .param_str = "v." | |
| 17066 | .attributes = .{ .custom_typecheck = true } | |
| 17067 | ||
| 17068 | __atomic_load | |
| 17069 | .param_str = "v." | |
| 17070 | .attributes = .{ .custom_typecheck = true } | |
| 17071 | ||
| 17072 | __atomic_load_n | |
| 17073 | .param_str = "v." | |
| 17074 | .attributes = .{ .custom_typecheck = true } | |
| 17075 | ||
| 17076 | __atomic_store | |
| 17077 | .param_str = "v." | |
| 17078 | .attributes = .{ .custom_typecheck = true } | |
| 17079 | ||
| 17080 | __atomic_store_n | |
| 17081 | .param_str = "v." | |
| 17082 | .attributes = .{ .custom_typecheck = true } | |
| 17083 | ||
| 17084 | __atomic_exchange | |
| 17085 | .param_str = "v." | |
| 17086 | .attributes = .{ .custom_typecheck = true } | |
| 17087 | ||
| 17088 | __atomic_exchange_n | |
| 17089 | .param_str = "v." | |
| 17090 | .attributes = .{ .custom_typecheck = true } | |
| 17091 | ||
| 17092 | __atomic_compare_exchange | |
| 17093 | .param_str = "v." | |
| 17094 | .attributes = .{ .custom_typecheck = true } | |
| 17095 | ||
| 17096 | __atomic_compare_exchange_n | |
| 17097 | .param_str = "v." | |
| 17098 | .attributes = .{ .custom_typecheck = true } | |
| 17099 | ||
| 17100 | __atomic_fetch_add | |
| 17101 | .param_str = "v." | |
| 17102 | .attributes = .{ .custom_typecheck = true } | |
| 17103 | ||
| 17104 | __atomic_fetch_sub | |
| 17105 | .param_str = "v." | |
| 17106 | .attributes = .{ .custom_typecheck = true } | |
| 17107 | ||
| 17108 | __atomic_fetch_and | |
| 17109 | .param_str = "v." | |
| 17110 | .attributes = .{ .custom_typecheck = true } | |
| 17111 | ||
| 17112 | __atomic_fetch_or | |
| 17113 | .param_str = "v." | |
| 17114 | .attributes = .{ .custom_typecheck = true } | |
| 17115 | ||
| 17116 | __atomic_fetch_xor | |
| 17117 | .param_str = "v." | |
| 17118 | .attributes = .{ .custom_typecheck = true } | |
| 17119 | ||
| 17120 | __atomic_fetch_nand | |
| 17121 | .param_str = "v." | |
| 17122 | .attributes = .{ .custom_typecheck = true } | |
| 17123 | ||
| 17124 | __atomic_add_fetch | |
| 17125 | .param_str = "v." | |
| 17126 | .attributes = .{ .custom_typecheck = true } | |
| 17127 | ||
| 17128 | __atomic_sub_fetch | |
| 17129 | .param_str = "v." | |
| 17130 | .attributes = .{ .custom_typecheck = true } | |
| 17131 | ||
| 17132 | __atomic_and_fetch | |
| 17133 | .param_str = "v." | |
| 17134 | .attributes = .{ .custom_typecheck = true } | |
| 17135 | ||
| 17136 | __atomic_or_fetch | |
| 17137 | .param_str = "v." | |
| 17138 | .attributes = .{ .custom_typecheck = true } | |
| 17139 | ||
| 17140 | __atomic_xor_fetch | |
| 17141 | .param_str = "v." | |
| 17142 | .attributes = .{ .custom_typecheck = true } | |
| 17143 | ||
| 17144 | __atomic_max_fetch | |
| 17145 | .param_str = "v." | |
| 17146 | .attributes = .{ .custom_typecheck = true } | |
| 17147 | ||
| 17148 | __atomic_min_fetch | |
| 17149 | .param_str = "v." | |
| 17150 | .attributes = .{ .custom_typecheck = true } | |
| 17151 | ||
| 17152 | __atomic_nand_fetch | |
| 17153 | .param_str = "v." | |
| 17154 | .attributes = .{ .custom_typecheck = true } | |
| 17155 | ||
| 17156 | __atomic_fetch_min | |
| 17157 | .param_str = "v." | |
| 17158 | .attributes = .{ .custom_typecheck = true } | |
| 17159 | ||
| 17160 | __atomic_fetch_max | |
| 17161 | .param_str = "v." | |
| 17162 | .attributes = .{ .custom_typecheck = true } |
deps/aro/aro/Compilation.zig+73-2| ... | ... | @@ -408,6 +408,17 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void { |
| 408 | 408 | \\ |
| 409 | 409 | ); |
| 410 | 410 | |
| 411 | // atomics | |
| 412 | try w.writeAll( | |
| 413 | \\#define __ATOMIC_RELAXED 0 | |
| 414 | \\#define __ATOMIC_CONSUME 1 | |
| 415 | \\#define __ATOMIC_ACQUIRE 2 | |
| 416 | \\#define __ATOMIC_RELEASE 3 | |
| 417 | \\#define __ATOMIC_ACQ_REL 4 | |
| 418 | \\#define __ATOMIC_SEQ_CST 5 | |
| 419 | \\ | |
| 420 | ); | |
| 421 | ||
| 411 | 422 | // types |
| 412 | 423 | if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n"); |
| 413 | 424 | try w.writeAll("#define __CHAR_BIT__ 8\n"); |
| ... | ... | @@ -445,6 +456,10 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void { |
| 445 | 456 | try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar); |
| 446 | 457 | // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer }); |
| 447 | 458 | |
| 459 | if (target_util.hasInt128(comp.target)) { | |
| 460 | try comp.generateSizeofType(w, "__SIZEOF_INT128__", .{ .specifier = .int128 }); | |
| 461 | } | |
| 462 | ||
| 448 | 463 | // various int types |
| 449 | 464 | const mapper = comp.string_interner.getSlowTypeMapper(); |
| 450 | 465 | try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts); |
| ... | ... | @@ -461,6 +476,7 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void { |
| 461 | 476 | try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts); |
| 462 | 477 | |
| 463 | 478 | try comp.generateExactWidthTypes(w, mapper); |
| 479 | try comp.generateFastAndLeastWidthTypes(w, mapper); | |
| 464 | 480 | |
| 465 | 481 | if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| { |
| 466 | 482 | try generateFloatMacros(w, "FLT16", half, "F16"); |
| ... | ... | @@ -497,10 +513,11 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi |
| 497 | 513 | ); |
| 498 | 514 | } |
| 499 | 515 | |
| 516 | try buf.appendSlice("#define __STDC__ 1\n"); | |
| 517 | try buf.writer().print("#define __STDC_HOSTED__ {d}\n", .{@intFromBool(comp.target.os.tag != .freestanding)}); | |
| 518 | ||
| 500 | 519 | // standard macros |
| 501 | 520 | try buf.appendSlice( |
| 502 | \\#define __STDC__ 1 | |
| 503 | \\#define __STDC_HOSTED__ 1 | |
| 504 | 521 | \\#define __STDC_NO_ATOMICS__ 1 |
| 505 | 522 | \\#define __STDC_NO_COMPLEX__ 1 |
| 506 | 523 | \\#define __STDC_NO_THREADS__ 1 |
| ... | ... | @@ -678,6 +695,14 @@ fn generateBuiltinTypes(comp: *Compilation) !void { |
| 678 | 695 | |
| 679 | 696 | /// Smallest integer type with at least N bits |
| 680 | 697 | fn intLeastN(comp: *const Compilation, bits: usize, signedness: std.builtin.Signedness) Type { |
| 698 | if (bits == 64 and (comp.target.isDarwin() or comp.target.isWasm())) { | |
| 699 | // WebAssembly and Darwin use `long long` for `int_least64_t` and `int_fast64_t`. | |
| 700 | return .{ .specifier = if (signedness == .signed) .long_long else .ulong_long }; | |
| 701 | } | |
| 702 | if (bits == 16 and comp.target.cpu.arch == .avr) { | |
| 703 | // AVR uses int for int_least16_t and int_fast16_t. | |
| 704 | return .{ .specifier = if (signedness == .signed) .int else .uint }; | |
| 705 | } | |
| 681 | 706 | const candidates = switch (signedness) { |
| 682 | 707 | .signed => &[_]Type.Specifier{ .schar, .short, .int, .long, .long_long }, |
| 683 | 708 | .unsigned => &[_]Type.Specifier{ .uchar, .ushort, .uint, .ulong, .ulong_long }, |
| ... | ... | @@ -693,6 +718,52 @@ fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 { |
| 693 | 718 | return ty.sizeof(comp).?; |
| 694 | 719 | } |
| 695 | 720 | |
| 721 | fn generateFastOrLeastType( | |
| 722 | comp: *Compilation, | |
| 723 | bits: usize, | |
| 724 | kind: enum { least, fast }, | |
| 725 | signedness: std.builtin.Signedness, | |
| 726 | w: anytype, | |
| 727 | mapper: StrInt.TypeMapper, | |
| 728 | ) !void { | |
| 729 | const ty = comp.intLeastN(bits, signedness); // defining the fast types as the least types is permitted | |
| 730 | ||
| 731 | var buf: [32]u8 = undefined; | |
| 732 | const suffix = "_TYPE__"; | |
| 733 | const base_name = switch (signedness) { | |
| 734 | .signed => "__INT_", | |
| 735 | .unsigned => "__UINT_", | |
| 736 | }; | |
| 737 | const kind_str = switch (kind) { | |
| 738 | .fast => "FAST", | |
| 739 | .least => "LEAST", | |
| 740 | }; | |
| 741 | ||
| 742 | const full = std.fmt.bufPrint(&buf, "{s}{s}{d}{s}", .{ | |
| 743 | base_name, kind_str, bits, suffix, | |
| 744 | }) catch return error.OutOfMemory; | |
| 745 | ||
| 746 | try generateTypeMacro(w, mapper, full, ty, comp.langopts); | |
| 747 | ||
| 748 | const prefix = full[2 .. full.len - suffix.len]; // remove "__" and "_TYPE__" | |
| 749 | ||
| 750 | switch (signedness) { | |
| 751 | .signed => try comp.generateIntMaxAndWidth(w, prefix, ty), | |
| 752 | .unsigned => try comp.generateIntMax(w, prefix, ty), | |
| 753 | } | |
| 754 | try comp.generateFmt(prefix, w, ty); | |
| 755 | } | |
| 756 | ||
| 757 | fn generateFastAndLeastWidthTypes(comp: *Compilation, w: anytype, mapper: StrInt.TypeMapper) !void { | |
| 758 | const sizes = [_]usize{ 8, 16, 32, 64 }; | |
| 759 | for (sizes) |size| { | |
| 760 | try comp.generateFastOrLeastType(size, .least, .signed, w, mapper); | |
| 761 | try comp.generateFastOrLeastType(size, .least, .unsigned, w, mapper); | |
| 762 | try comp.generateFastOrLeastType(size, .fast, .signed, w, mapper); | |
| 763 | try comp.generateFastOrLeastType(size, .fast, .unsigned, w, mapper); | |
| 764 | } | |
| 765 | } | |
| 766 | ||
| 696 | 767 | fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper) !void { |
| 697 | 768 | try comp.generateExactWidthType(w, mapper, .schar); |
| 698 | 769 |
deps/aro/aro/Diagnostics.zig+4-3| ... | ... | @@ -236,7 +236,7 @@ pub fn set(d: *Diagnostics, name: []const u8, to: Kind) !void { |
| 236 | 236 | try d.addExtra(.{}, .{ |
| 237 | 237 | .tag = .unknown_warning, |
| 238 | 238 | .extra = .{ .str = name }, |
| 239 | }, &.{}); | |
| 239 | }, &.{}, true); | |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | 242 | pub fn init(gpa: Allocator) Diagnostics { |
| ... | ... | @@ -251,7 +251,7 @@ pub fn deinit(d: *Diagnostics) void { |
| 251 | 251 | } |
| 252 | 252 | |
| 253 | 253 | pub fn add(comp: *Compilation, msg: Message, expansion_locs: []const Source.Location) Compilation.Error!void { |
| 254 | return comp.diagnostics.addExtra(comp.langopts, msg, expansion_locs); | |
| 254 | return comp.diagnostics.addExtra(comp.langopts, msg, expansion_locs, true); | |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | 257 | pub fn addExtra( |
| ... | ... | @@ -259,6 +259,7 @@ pub fn addExtra( |
| 259 | 259 | langopts: LangOpts, |
| 260 | 260 | msg: Message, |
| 261 | 261 | expansion_locs: []const Source.Location, |
| 262 | note_msg_loc: bool, | |
| 262 | 263 | ) Compilation.Error!void { |
| 263 | 264 | const kind = d.tagKind(msg.tag, langopts); |
| 264 | 265 | if (kind == .off) return; |
| ... | ... | @@ -301,7 +302,7 @@ pub fn addExtra( |
| 301 | 302 | } |
| 302 | 303 | } |
| 303 | 304 | |
| 304 | d.list.appendAssumeCapacity(.{ | |
| 305 | if (note_msg_loc) d.list.appendAssumeCapacity(.{ | |
| 305 | 306 | .tag = .expanded_from_here, |
| 306 | 307 | .kind = .note, |
| 307 | 308 | .loc = msg.loc, |
deps/aro/aro/Driver.zig+16| ... | ... | @@ -98,8 +98,10 @@ pub const usage = |
| 98 | 98 | \\ -fno-declspec Disable support for __declspec attributes |
| 99 | 99 | \\ -ffp-eval-method=[source|double|extended] |
| 100 | 100 | \\ Evaluation method to use for floating-point arithmetic |
| 101 | \\ -ffreestanding Compilation in a freestanding environment | |
| 101 | 102 | \\ -fgnu-inline-asm Enable GNU style inline asm (default: enabled) |
| 102 | 103 | \\ -fno-gnu-inline-asm Disable GNU style inline asm |
| 104 | \\ -fhosted Compilation in a hosted environment | |
| 103 | 105 | \\ -fms-extensions Enable support for Microsoft extensions |
| 104 | 106 | \\ -fno-ms-extensions Disable support for Microsoft extensions |
| 105 | 107 | \\ -fdollars-in-identifiers |
| ... | ... | @@ -177,6 +179,7 @@ pub fn parseArgs( |
| 177 | 179 | ) !bool { |
| 178 | 180 | var i: usize = 1; |
| 179 | 181 | var comment_arg: []const u8 = ""; |
| 182 | var hosted: ?bool = null; | |
| 180 | 183 | while (i < args.len) : (i += 1) { |
| 181 | 184 | const arg = args[i]; |
| 182 | 185 | if (mem.startsWith(u8, arg, "-") and arg.len > 1) { |
| ... | ... | @@ -277,6 +280,10 @@ pub fn parseArgs( |
| 277 | 280 | d.comp.langopts.declspec_attrs = true; |
| 278 | 281 | } else if (mem.eql(u8, arg, "-fno-declspec")) { |
| 279 | 282 | d.comp.langopts.declspec_attrs = false; |
| 283 | } else if (mem.eql(u8, arg, "-ffreestanding")) { | |
| 284 | hosted = false; | |
| 285 | } else if (mem.eql(u8, arg, "-fhosted")) { | |
| 286 | hosted = true; | |
| 280 | 287 | } else if (mem.eql(u8, arg, "-fms-extensions")) { |
| 281 | 288 | d.comp.langopts.enableMSExtensions(); |
| 282 | 289 | } else if (mem.eql(u8, arg, "-fno-ms-extensions")) { |
| ... | ... | @@ -440,6 +447,15 @@ pub fn parseArgs( |
| 440 | 447 | if (d.comp.langopts.preserve_comments and !d.only_preprocess) { |
| 441 | 448 | return d.fatal("invalid argument '{s}' only allowed with '-E'", .{comment_arg}); |
| 442 | 449 | } |
| 450 | if (hosted) |is_hosted| { | |
| 451 | if (is_hosted) { | |
| 452 | if (d.comp.target.os.tag == .freestanding) { | |
| 453 | return d.fatal("Cannot use freestanding target with `-fhosted`", .{}); | |
| 454 | } | |
| 455 | } else { | |
| 456 | d.comp.target.os.tag = .freestanding; | |
| 457 | } | |
| 458 | } | |
| 443 | 459 | return false; |
| 444 | 460 | } |
| 445 | 461 |
deps/aro/aro/Driver/Filesystem.zig+10-10| ... | ... | @@ -121,7 +121,7 @@ pub const Filesystem = union(enum) { |
| 121 | 121 | base: []const u8, |
| 122 | 122 | i: usize = 0, |
| 123 | 123 | |
| 124 | fn next(self: *@This()) !?std.fs.IterableDir.Entry { | |
| 124 | fn next(self: *@This()) !?std.fs.Dir.Entry { | |
| 125 | 125 | while (self.i < self.entries.len) { |
| 126 | 126 | const entry = self.entries[self.i]; |
| 127 | 127 | self.i += 1; |
| ... | ... | @@ -130,7 +130,7 @@ pub const Filesystem = union(enum) { |
| 130 | 130 | const remaining = entry.path[self.base.len + 1 ..]; |
| 131 | 131 | if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue; |
| 132 | 132 | const extension = std.fs.path.extension(remaining); |
| 133 | const kind: std.fs.IterableDir.Entry.Kind = if (extension.len == 0) .directory else .file; | |
| 133 | const kind: std.fs.Dir.Entry.Kind = if (extension.len == 0) .directory else .file; | |
| 134 | 134 | return .{ .name = remaining, .kind = kind }; |
| 135 | 135 | } |
| 136 | 136 | } |
| ... | ... | @@ -139,18 +139,18 @@ pub const Filesystem = union(enum) { |
| 139 | 139 | }; |
| 140 | 140 | }; |
| 141 | 141 | |
| 142 | const IterableDir = union(enum) { | |
| 143 | dir: std.fs.IterableDir, | |
| 142 | const Dir = union(enum) { | |
| 143 | dir: std.fs.Dir, | |
| 144 | 144 | fake: FakeDir, |
| 145 | 145 | |
| 146 | pub fn iterate(self: IterableDir) Iterator { | |
| 146 | pub fn iterate(self: Dir) Iterator { | |
| 147 | 147 | return switch (self) { |
| 148 | 148 | .dir => |dir| .{ .iterator = dir.iterate() }, |
| 149 | 149 | .fake => |fake| .{ .fake = fake.iterate() }, |
| 150 | 150 | }; |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | pub fn close(self: *IterableDir) void { | |
| 153 | pub fn close(self: *Dir) void { | |
| 154 | 154 | switch (self.*) { |
| 155 | 155 | .dir => |*d| d.close(), |
| 156 | 156 | .fake => {}, |
| ... | ... | @@ -159,10 +159,10 @@ pub const Filesystem = union(enum) { |
| 159 | 159 | }; |
| 160 | 160 | |
| 161 | 161 | const Iterator = union(enum) { |
| 162 | iterator: std.fs.IterableDir.Iterator, | |
| 162 | iterator: std.fs.Dir.Iterator, | |
| 163 | 163 | fake: FakeDir.Iterator, |
| 164 | 164 | |
| 165 | pub fn next(self: *Iterator) std.fs.IterableDir.Iterator.Error!?std.fs.IterableDir.Entry { | |
| 165 | pub fn next(self: *Iterator) std.fs.Dir.Iterator.Error!?std.fs.Dir.Entry { | |
| 166 | 166 | return switch (self.*) { |
| 167 | 167 | .iterator => |*it| it.next(), |
| 168 | 168 | .fake => |*it| it.next(), |
| ... | ... | @@ -221,9 +221,9 @@ pub const Filesystem = union(enum) { |
| 221 | 221 | }; |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | pub fn openIterableDir(fs: Filesystem, dir_name: []const u8) std.fs.Dir.OpenError!IterableDir { | |
| 224 | pub fn openDir(fs: Filesystem, dir_name: []const u8) std.fs.Dir.OpenError!Dir { | |
| 225 | 225 | return switch (fs) { |
| 226 | .real => .{ .dir = try std.fs.cwd().openIterableDir(dir_name, .{ .access_sub_paths = false }) }, | |
| 226 | .real => .{ .dir = try std.fs.cwd().openDir(dir_name, .{ .access_sub_paths = false, .iterate = true }) }, | |
| 227 | 227 | .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } }, |
| 228 | 228 | }; |
| 229 | 229 | } |
deps/aro/aro/Driver/GCCDetector.zig+1-1| ... | ... | @@ -602,7 +602,7 @@ fn scanLibDirForGCCTriple( |
| 602 | 602 | const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue; |
| 603 | 603 | |
| 604 | 604 | const dir_name = std.fs.path.join(fib.allocator(), &.{ lib_dir, lib_suffix }) catch continue; |
| 605 | var parent_dir = tc.filesystem.openIterableDir(dir_name) catch continue; | |
| 605 | var parent_dir = tc.filesystem.openDir(dir_name) catch continue; | |
| 606 | 606 | defer parent_dir.close(); |
| 607 | 607 | |
| 608 | 608 | var it = parent_dir.iterate(); |
deps/aro/aro/Parser.zig+79-32| ... | ... | @@ -9,6 +9,8 @@ const Tokenizer = @import("Tokenizer.zig"); |
| 9 | 9 | const Preprocessor = @import("Preprocessor.zig"); |
| 10 | 10 | const Tree = @import("Tree.zig"); |
| 11 | 11 | const Token = Tree.Token; |
| 12 | const NumberPrefix = Token.NumberPrefix; | |
| 13 | const NumberSuffix = Token.NumberSuffix; | |
| 12 | 14 | const TokenIndex = Tree.TokenIndex; |
| 13 | 15 | const NodeIndex = Tree.NodeIndex; |
| 14 | 16 | const Type = @import("Type.zig"); |
| ... | ... | @@ -24,9 +26,6 @@ const Symbol = SymbolStack.Symbol; |
| 24 | 26 | const record_layout = @import("record_layout.zig"); |
| 25 | 27 | const StrInt = @import("StringInterner.zig"); |
| 26 | 28 | const StringId = StrInt.StringId; |
| 27 | const number_affixes = @import("number_affixes.zig"); | |
| 28 | const NumberPrefix = number_affixes.Prefix; | |
| 29 | const NumberSuffix = number_affixes.Suffix; | |
| 30 | 29 | const Builtins = @import("Builtins.zig"); |
| 31 | 30 | const Builtin = Builtins.Builtin; |
| 32 | 31 | const target_util = @import("target.zig"); |
| ... | ... | @@ -323,7 +322,7 @@ fn expectIdentifier(p: *Parser) Error!TokenIndex { |
| 323 | 322 | return p.errExpectedToken(.identifier, actual); |
| 324 | 323 | } |
| 325 | 324 | |
| 326 | return (try p.eatIdentifier()) orelse unreachable; | |
| 325 | return (try p.eatIdentifier()) orelse error.ParsingFailed; | |
| 327 | 326 | } |
| 328 | 327 | |
| 329 | 328 | fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex { |
| ... | ... | @@ -347,7 +346,7 @@ pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 { |
| 347 | 346 | const loc = p.pp.tokens.items(.loc)[tok]; |
| 348 | 347 | var tmp_tokenizer = Tokenizer{ |
| 349 | 348 | .buf = p.comp.getSource(loc.id).buf, |
| 350 | .comp = p.comp, | |
| 349 | .langopts = p.comp.langopts, | |
| 351 | 350 | .index = loc.byte_offset, |
| 352 | 351 | .source = .generated, |
| 353 | 352 | }; |
| ... | ... | @@ -715,6 +714,9 @@ pub fn parse(pp: *Preprocessor) Compilation.Error!Tree { |
| 715 | 714 | p.field_attr_buf.deinit(); |
| 716 | 715 | } |
| 717 | 716 | |
| 717 | try p.syms.pushScope(&p); | |
| 718 | defer p.syms.popScope(); | |
| 719 | ||
| 718 | 720 | // NodeIndex 0 must be invalid |
| 719 | 721 | _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined }); |
| 720 | 722 | |
| ... | ... | @@ -1010,7 +1012,7 @@ fn decl(p: *Parser) Error!bool { |
| 1010 | 1012 | // Collect old style parameter declarations. |
| 1011 | 1013 | if (init_d.d.old_style_func != null) { |
| 1012 | 1014 | const attrs = init_d.d.ty.getAttributes(); |
| 1013 | var base_ty = if (init_d.d.ty.specifier == .attributed) init_d.d.ty.elemType() else init_d.d.ty; | |
| 1015 | var base_ty = if (init_d.d.ty.specifier == .attributed) init_d.d.ty.data.attributed.base else init_d.d.ty; | |
| 1014 | 1016 | base_ty.specifier = .func; |
| 1015 | 1017 | init_d.d.ty = try base_ty.withAttributes(p.arena, attrs); |
| 1016 | 1018 | |
| ... | ... | @@ -1066,7 +1068,7 @@ fn decl(p: *Parser) Error!bool { |
| 1066 | 1068 | d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param); |
| 1067 | 1069 | |
| 1068 | 1070 | // bypass redefinition check to avoid duplicate errors |
| 1069 | try p.syms.syms.append(p.gpa, .{ | |
| 1071 | try p.syms.define(p.gpa, .{ | |
| 1070 | 1072 | .kind = .def, |
| 1071 | 1073 | .name = interned_name, |
| 1072 | 1074 | .tok = d.name, |
| ... | ... | @@ -1088,7 +1090,7 @@ fn decl(p: *Parser) Error!bool { |
| 1088 | 1090 | } |
| 1089 | 1091 | |
| 1090 | 1092 | // bypass redefinition check to avoid duplicate errors |
| 1091 | try p.syms.syms.append(p.gpa, .{ | |
| 1093 | try p.syms.define(p.gpa, .{ | |
| 1092 | 1094 | .kind = .def, |
| 1093 | 1095 | .name = param.name, |
| 1094 | 1096 | .tok = param.name_tok, |
| ... | ... | @@ -1428,12 +1430,14 @@ fn typeof(p: *Parser) Error!?Type { |
| 1428 | 1430 | .data = typeof_expr.ty.data, |
| 1429 | 1431 | .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(), |
| 1430 | 1432 | .specifier = typeof_expr.ty.specifier, |
| 1433 | .decayed = typeof_expr.ty.decayed, | |
| 1431 | 1434 | }, |
| 1432 | 1435 | }; |
| 1433 | 1436 | |
| 1434 | 1437 | return Type{ |
| 1435 | 1438 | .data = .{ .expr = inner }, |
| 1436 | 1439 | .specifier = .typeof_expr, |
| 1440 | .decayed = typeof_expr.ty.decayed, | |
| 1437 | 1441 | }; |
| 1438 | 1442 | } |
| 1439 | 1443 | |
| ... | ... | @@ -1814,6 +1818,7 @@ fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!? |
| 1814 | 1818 | } else { |
| 1815 | 1819 | init_d.d.ty.specifier = init_d.initializer.ty.specifier; |
| 1816 | 1820 | init_d.d.ty.data = init_d.initializer.ty.data; |
| 1821 | init_d.d.ty.decayed = init_d.initializer.ty.decayed; | |
| 1817 | 1822 | } |
| 1818 | 1823 | } |
| 1819 | 1824 | if (apply_var_attributes) { |
| ... | ... | @@ -2105,7 +2110,7 @@ fn recordSpec(p: *Parser) Error!Type { |
| 2105 | 2110 | .specifier = if (is_struct) .@"struct" else .@"union", |
| 2106 | 2111 | .data = .{ .record = record_ty }, |
| 2107 | 2112 | }, attr_buf_top, null); |
| 2108 | try p.syms.syms.append(p.gpa, .{ | |
| 2113 | try p.syms.define(p.gpa, .{ | |
| 2109 | 2114 | .kind = if (is_struct) .@"struct" else .@"union", |
| 2110 | 2115 | .name = interned_name, |
| 2111 | 2116 | .tok = ident, |
| ... | ... | @@ -2151,10 +2156,8 @@ fn recordSpec(p: *Parser) Error!Type { |
| 2151 | 2156 | |
| 2152 | 2157 | // declare a symbol for the type |
| 2153 | 2158 | // We need to replace the symbol's type if it has attributes |
| 2154 | var symbol_index: ?usize = null; | |
| 2155 | 2159 | if (maybe_ident != null and !defined) { |
| 2156 | symbol_index = p.syms.syms.len; | |
| 2157 | try p.syms.syms.append(p.gpa, .{ | |
| 2160 | try p.syms.define(p.gpa, .{ | |
| 2158 | 2161 | .kind = if (is_struct) .@"struct" else .@"union", |
| 2159 | 2162 | .name = record_ty.name, |
| 2160 | 2163 | .tok = maybe_ident.?, |
| ... | ... | @@ -2216,8 +2219,11 @@ fn recordSpec(p: *Parser) Error!Type { |
| 2216 | 2219 | .specifier = if (is_struct) .@"struct" else .@"union", |
| 2217 | 2220 | .data = .{ .record = record_ty }, |
| 2218 | 2221 | }, attr_buf_top, null); |
| 2219 | if (ty.specifier == .attributed and symbol_index != null) { | |
| 2220 | p.syms.syms.items(.ty)[symbol_index.?] = ty; | |
| 2222 | if (ty.specifier == .attributed and maybe_ident != null) { | |
| 2223 | const ident_str = p.tokSlice(maybe_ident.?); | |
| 2224 | const interned_name = try StrInt.intern(p.comp, ident_str); | |
| 2225 | const ptr = p.syms.getPtr(interned_name, .tags); | |
| 2226 | ptr.ty = ty; | |
| 2221 | 2227 | } |
| 2222 | 2228 | |
| 2223 | 2229 | if (!ty.hasIncompleteSize()) { |
| ... | ... | @@ -2474,7 +2480,7 @@ fn enumSpec(p: *Parser) Error!Type { |
| 2474 | 2480 | .specifier = .@"enum", |
| 2475 | 2481 | .data = .{ .@"enum" = enum_ty }, |
| 2476 | 2482 | }, attr_buf_top, null); |
| 2477 | try p.syms.syms.append(p.gpa, .{ | |
| 2483 | try p.syms.define(p.gpa, .{ | |
| 2478 | 2484 | .kind = .@"enum", |
| 2479 | 2485 | .name = interned_name, |
| 2480 | 2486 | .tok = ident, |
| ... | ... | @@ -2525,7 +2531,6 @@ fn enumSpec(p: *Parser) Error!Type { |
| 2525 | 2531 | p.enum_buf.items.len = enum_buf_top; |
| 2526 | 2532 | } |
| 2527 | 2533 | |
| 2528 | const sym_stack_top = p.syms.syms.len; | |
| 2529 | 2534 | var e = Enumerator.init(fixed_ty); |
| 2530 | 2535 | while (try p.enumerator(&e)) |field_and_node| { |
| 2531 | 2536 | try p.enum_buf.append(field_and_node.field); |
| ... | ... | @@ -2551,13 +2556,12 @@ fn enumSpec(p: *Parser) Error!Type { |
| 2551 | 2556 | const field_nodes = p.list_buf.items[list_buf_top..]; |
| 2552 | 2557 | |
| 2553 | 2558 | if (fixed_ty == null) { |
| 2554 | const vals = p.syms.syms.items(.val)[sym_stack_top..]; | |
| 2555 | const types = p.syms.syms.items(.ty)[sym_stack_top..]; | |
| 2556 | ||
| 2557 | 2559 | for (enum_fields, 0..) |*field, i| { |
| 2558 | 2560 | if (field.ty.eql(Type.int, p.comp, false)) continue; |
| 2559 | 2561 | |
| 2560 | var res = Result{ .node = field.node, .ty = field.ty, .val = vals[i] }; | |
| 2562 | const sym = p.syms.get(field.name, .vars) orelse continue; | |
| 2563 | ||
| 2564 | var res = Result{ .node = field.node, .ty = field.ty, .val = sym.val }; | |
| 2561 | 2565 | const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some| |
| 2562 | 2566 | Type{ .specifier = some } |
| 2563 | 2567 | else if (try res.intFitsInType(p, Type.int)) |
| ... | ... | @@ -2567,8 +2571,9 @@ fn enumSpec(p: *Parser) Error!Type { |
| 2567 | 2571 | else |
| 2568 | 2572 | continue; |
| 2569 | 2573 | |
| 2570 | try vals[i].intCast(dest_ty, p.comp); | |
| 2571 | types[i] = dest_ty; | |
| 2574 | const symbol = p.syms.getPtr(field.name, .vars); | |
| 2575 | try symbol.val.intCast(dest_ty, p.comp); | |
| 2576 | symbol.ty = dest_ty; | |
| 2572 | 2577 | p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty; |
| 2573 | 2578 | field.ty = dest_ty; |
| 2574 | 2579 | res.ty = dest_ty; |
| ... | ... | @@ -2585,7 +2590,7 @@ fn enumSpec(p: *Parser) Error!Type { |
| 2585 | 2590 | |
| 2586 | 2591 | // declare a symbol for the type |
| 2587 | 2592 | if (maybe_ident != null and !defined) { |
| 2588 | try p.syms.syms.append(p.gpa, .{ | |
| 2593 | try p.syms.define(p.gpa, .{ | |
| 2589 | 2594 | .kind = .@"enum", |
| 2590 | 2595 | .name = enum_ty.name, |
| 2591 | 2596 | .ty = ty, |
| ... | ... | @@ -2885,7 +2890,7 @@ fn declarator( |
| 2885 | 2890 | try res.ty.combine(outer); |
| 2886 | 2891 | try res.ty.validateCombinedType(p, suffix_start); |
| 2887 | 2892 | res.old_style_func = d.old_style_func; |
| 2888 | res.func_declarator = d.func_declarator; | |
| 2893 | if (d.func_declarator) |some| res.func_declarator = some; | |
| 2889 | 2894 | return res; |
| 2890 | 2895 | } |
| 2891 | 2896 | |
| ... | ... | @@ -4376,7 +4381,7 @@ fn stmt(p: *Parser) Error!NodeIndex { |
| 4376 | 4381 | /// | keyword_default ':' stmt |
| 4377 | 4382 | fn labeledStmt(p: *Parser) Error!?NodeIndex { |
| 4378 | 4383 | if ((p.tok_ids[p.tok_i] == .identifier or p.tok_ids[p.tok_i] == .extended_identifier) and p.tok_ids[p.tok_i + 1] == .colon) { |
| 4379 | const name_tok = p.expectIdentifier() catch unreachable; | |
| 4384 | const name_tok = try p.expectIdentifier(); | |
| 4380 | 4385 | const str = p.tokSlice(name_tok); |
| 4381 | 4386 | if (p.findLabel(str)) |some| { |
| 4382 | 4387 | try p.errStr(.duplicate_label, name_tok, str); |
| ... | ... | @@ -4814,10 +4819,23 @@ const CallExpr = union(enum) { |
| 4814 | 4819 | /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for |
| 4815 | 4820 | /// these custom-typechecked functions. |
| 4816 | 4821 | fn paramCountOverride(self: CallExpr) ?u32 { |
| 4822 | @setEvalBranchQuota(10_000); | |
| 4817 | 4823 | return switch (self) { |
| 4818 | 4824 | .standard => null, |
| 4819 | 4825 | .builtin => |builtin| switch (builtin.tag) { |
| 4820 | 4826 | Builtin.tagFromName("__builtin_complex").? => 2, |
| 4827 | ||
| 4828 | Builtin.tagFromName("__atomic_fetch_add").?, | |
| 4829 | Builtin.tagFromName("__atomic_fetch_sub").?, | |
| 4830 | Builtin.tagFromName("__atomic_fetch_and").?, | |
| 4831 | Builtin.tagFromName("__atomic_fetch_xor").?, | |
| 4832 | Builtin.tagFromName("__atomic_fetch_or").?, | |
| 4833 | Builtin.tagFromName("__atomic_fetch_nand").?, | |
| 4834 | => 3, | |
| 4835 | ||
| 4836 | Builtin.tagFromName("__atomic_compare_exchange").?, | |
| 4837 | Builtin.tagFromName("__atomic_compare_exchange_n").?, | |
| 4838 | => 6, | |
| 4821 | 4839 | else => null, |
| 4822 | 4840 | }, |
| 4823 | 4841 | }; |
| ... | ... | @@ -4827,10 +4845,25 @@ const CallExpr = union(enum) { |
| 4827 | 4845 | return switch (self) { |
| 4828 | 4846 | .standard => callable_ty.returnType(), |
| 4829 | 4847 | .builtin => |builtin| switch (builtin.tag) { |
| 4848 | Builtin.tagFromName("__atomic_fetch_add").?, | |
| 4849 | Builtin.tagFromName("__atomic_fetch_sub").?, | |
| 4850 | Builtin.tagFromName("__atomic_fetch_and").?, | |
| 4851 | Builtin.tagFromName("__atomic_fetch_xor").?, | |
| 4852 | Builtin.tagFromName("__atomic_fetch_or").?, | |
| 4853 | Builtin.tagFromName("__atomic_fetch_nand").?, | |
| 4854 | => { | |
| 4855 | if (p.list_buf.items.len < 2) return Type.invalid; // not enough arguments; already an error | |
| 4856 | const second_param = p.list_buf.items[p.list_buf.items.len - 2]; | |
| 4857 | return p.nodes.items(.ty)[@intFromEnum(second_param)]; | |
| 4858 | }, | |
| 4830 | 4859 | Builtin.tagFromName("__builtin_complex").? => { |
| 4860 | if (p.list_buf.items.len < 1) return Type.invalid; // not enough arguments; already an error | |
| 4831 | 4861 | const last_param = p.list_buf.items[p.list_buf.items.len - 1]; |
| 4832 | 4862 | return p.nodes.items(.ty)[@intFromEnum(last_param)].makeComplex(); |
| 4833 | 4863 | }, |
| 4864 | Builtin.tagFromName("__atomic_compare_exchange").?, | |
| 4865 | Builtin.tagFromName("__atomic_compare_exchange_n").?, | |
| 4866 | => .{ .specifier = .bool }, | |
| 4834 | 4867 | else => callable_ty.returnType(), |
| 4835 | 4868 | }, |
| 4836 | 4869 | }; |
| ... | ... | @@ -7458,7 +7491,7 @@ fn primaryExpr(p: *Parser) Error!Result { |
| 7458 | 7491 | } |
| 7459 | 7492 | switch (p.tok_ids[p.tok_i]) { |
| 7460 | 7493 | .identifier, .extended_identifier => { |
| 7461 | const name_tok = p.expectIdentifier() catch unreachable; | |
| 7494 | const name_tok = try p.expectIdentifier(); | |
| 7462 | 7495 | const name = p.tokSlice(name_tok); |
| 7463 | 7496 | const interned_name = try StrInt.intern(p.comp, name); |
| 7464 | 7497 | if (p.syms.findSymbol(interned_name)) |sym| { |
| ... | ... | @@ -7938,6 +7971,8 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result { |
| 7938 | 7971 | .F, .IF => .float, |
| 7939 | 7972 | .F16 => .float16, |
| 7940 | 7973 | .L, .IL => .long_double, |
| 7974 | .W, .IW => .float80, | |
| 7975 | .Q, .IQ, .F128, .IF128 => .float128, | |
| 7941 | 7976 | else => unreachable, |
| 7942 | 7977 | } }; |
| 7943 | 7978 | const val = try Value.intern(p.comp, key: { |
| ... | ... | @@ -7946,7 +7981,7 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result { |
| 7946 | 7981 | const strings_top = p.strings.items.len; |
| 7947 | 7982 | defer p.strings.items.len = strings_top; |
| 7948 | 7983 | for (buf) |c| { |
| 7949 | if (c != '_') p.strings.appendAssumeCapacity(c); | |
| 7984 | if (c != '\'') p.strings.appendAssumeCapacity(c); | |
| 7950 | 7985 | } |
| 7951 | 7986 | |
| 7952 | 7987 | const float = std.fmt.parseFloat(f128, p.strings.items[strings_top..]) catch unreachable; |
| ... | ... | @@ -7971,6 +8006,8 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result { |
| 7971 | 8006 | .I => .complex_double, |
| 7972 | 8007 | .IF => .complex_float, |
| 7973 | 8008 | .IL => .complex_long_double, |
| 8009 | .IW => .complex_float80, | |
| 8010 | .IQ, .IF128 => .complex_float128, | |
| 7974 | 8011 | else => unreachable, |
| 7975 | 8012 | } }; |
| 7976 | 8013 | res.val = .{}; // TODO add complex values |
| ... | ... | @@ -8123,11 +8160,21 @@ fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: To |
| 8123 | 8160 | var managed = try big.int.Managed.init(p.gpa); |
| 8124 | 8161 | defer managed.deinit(); |
| 8125 | 8162 | |
| 8126 | managed.setString(base, buf) catch |e| switch (e) { | |
| 8127 | error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16 | |
| 8128 | error.InvalidCharacter => unreachable, // digits validated by Tokenizer | |
| 8129 | else => |er| return er, | |
| 8130 | }; | |
| 8163 | { | |
| 8164 | try p.strings.ensureUnusedCapacity(buf.len); | |
| 8165 | ||
| 8166 | const strings_top = p.strings.items.len; | |
| 8167 | defer p.strings.items.len = strings_top; | |
| 8168 | for (buf) |c| { | |
| 8169 | if (c != '\'') p.strings.appendAssumeCapacity(c); | |
| 8170 | } | |
| 8171 | ||
| 8172 | managed.setString(base, p.strings.items[strings_top..]) catch |e| switch (e) { | |
| 8173 | error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16 | |
| 8174 | error.InvalidCharacter => unreachable, // digits validated by Tokenizer | |
| 8175 | else => |er| return er, | |
| 8176 | }; | |
| 8177 | } | |
| 8131 | 8178 | const c = managed.toConst(); |
| 8132 | 8179 | const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: { |
| 8133 | 8180 | // Literal `0` requires at least 1 bit |
deps/aro/aro/Preprocessor.zig+60-25| ... | ... | @@ -315,7 +315,7 @@ fn invalidTokenDiagnostic(tok_id: Token.Id) Diagnostics.Tag { |
| 315 | 315 | fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 { |
| 316 | 316 | var tokenizer = Tokenizer{ |
| 317 | 317 | .buf = source.buf, |
| 318 | .comp = pp.comp, | |
| 318 | .langopts = pp.comp.langopts, | |
| 319 | 319 | .source = source.id, |
| 320 | 320 | }; |
| 321 | 321 | var hash = tokenizer.nextNoWS(); |
| ... | ... | @@ -334,7 +334,7 @@ fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!Token { |
| 334 | 334 | pp.preprocess_count += 1; |
| 335 | 335 | var tokenizer = Tokenizer{ |
| 336 | 336 | .buf = source.buf, |
| 337 | .comp = pp.comp, | |
| 337 | .langopts = pp.comp.langopts, | |
| 338 | 338 | .source = source.id, |
| 339 | 339 | }; |
| 340 | 340 | |
| ... | ... | @@ -747,6 +747,17 @@ fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anyty |
| 747 | 747 | return error.FatalError; |
| 748 | 748 | } |
| 749 | 749 | |
| 750 | fn fatalNotFound(pp: *Preprocessor, tok: Token, filename: []const u8) Compilation.Error { | |
| 751 | const old = pp.comp.diagnostics.fatal_errors; | |
| 752 | pp.comp.diagnostics.fatal_errors = true; | |
| 753 | defer pp.comp.diagnostics.fatal_errors = old; | |
| 754 | ||
| 755 | try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{ .tag = .cli_error, .loc = tok.loc, .extra = .{ | |
| 756 | .str = try std.fmt.allocPrint(pp.comp.diagnostics.arena.allocator(), "'{s}' not found", .{filename}), | |
| 757 | } }, tok.expansionSlice(), false); | |
| 758 | unreachable; // addExtra should've returned FatalError | |
| 759 | } | |
| 760 | ||
| 750 | 761 | fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void { |
| 751 | 762 | const source = pp.comp.getSource(raw.source); |
| 752 | 763 | const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start }); |
| ... | ... | @@ -1185,7 +1196,7 @@ fn pragmaOperator(pp: *Preprocessor, arg_tok: Token, operator_loc: Source.Locati |
| 1185 | 1196 | try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items); |
| 1186 | 1197 | var tmp_tokenizer = Tokenizer{ |
| 1187 | 1198 | .buf = pp.comp.generated_buf.items, |
| 1188 | .comp = pp.comp, | |
| 1199 | .langopts = pp.comp.langopts, | |
| 1189 | 1200 | .index = @intCast(start), |
| 1190 | 1201 | .source = .generated, |
| 1191 | 1202 | .line = pp.generated_line, |
| ... | ... | @@ -1864,7 +1875,7 @@ fn expandVaOpt( |
| 1864 | 1875 | .buf = source.buf, |
| 1865 | 1876 | .index = raw.start, |
| 1866 | 1877 | .source = raw.source, |
| 1867 | .comp = pp.comp, | |
| 1878 | .langopts = pp.comp.langopts, | |
| 1868 | 1879 | .line = raw.line, |
| 1869 | 1880 | }; |
| 1870 | 1881 | while (tokenizer.index < raw.end) { |
| ... | ... | @@ -2282,11 +2293,11 @@ fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroErr |
| 2282 | 2293 | |
| 2283 | 2294 | fn expandedSliceExtra(pp: *const Preprocessor, tok: Token, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 { |
| 2284 | 2295 | if (tok.id.lexeme()) |some| { |
| 2285 | if (!tok.id.allowsDigraphs(pp.comp) and !(tok.id == .macro_ws and macro_ws_handling == .preserve_macro_ws)) return some; | |
| 2296 | if (!tok.id.allowsDigraphs(pp.comp.langopts) and !(tok.id == .macro_ws and macro_ws_handling == .preserve_macro_ws)) return some; | |
| 2286 | 2297 | } |
| 2287 | 2298 | var tmp_tokenizer = Tokenizer{ |
| 2288 | 2299 | .buf = pp.comp.getSource(tok.loc.id).buf, |
| 2289 | .comp = pp.comp, | |
| 2300 | .langopts = pp.comp.langopts, | |
| 2290 | 2301 | .index = tok.loc.byte_offset, |
| 2291 | 2302 | .source = .generated, |
| 2292 | 2303 | }; |
| ... | ... | @@ -2340,7 +2351,7 @@ fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const Token) |
| 2340 | 2351 | // Try to tokenize the result. |
| 2341 | 2352 | var tmp_tokenizer = Tokenizer{ |
| 2342 | 2353 | .buf = pp.comp.generated_buf.items, |
| 2343 | .comp = pp.comp, | |
| 2354 | .langopts = pp.comp.langopts, | |
| 2344 | 2355 | .index = @intCast(start), |
| 2345 | 2356 | .source = .generated, |
| 2346 | 2357 | }; |
| ... | ... | @@ -2703,6 +2714,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void { |
| 2703 | 2714 | error.InvalidInclude => return, |
| 2704 | 2715 | else => |e| return e, |
| 2705 | 2716 | }; |
| 2717 | defer Token.free(filename_tok.expansion_locs, pp.gpa); | |
| 2706 | 2718 | |
| 2707 | 2719 | // Check for empty filename. |
| 2708 | 2720 | const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws); |
| ... | ... | @@ -2836,7 +2848,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void { |
| 2836 | 2848 | } |
| 2837 | 2849 | |
| 2838 | 2850 | const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type, limit)) orelse |
| 2839 | return pp.fatal(first, "'{s}' not found", .{filename}); | |
| 2851 | return pp.fatalNotFound(filename_tok, filename); | |
| 2840 | 2852 | defer pp.comp.gpa.free(embed_bytes); |
| 2841 | 2853 | |
| 2842 | 2854 | try Range.expand(prefix, pp, tokenizer); |
| ... | ... | @@ -2984,8 +2996,6 @@ fn findIncludeFilenameToken( |
| 2984 | 2996 | tokenizer: *Tokenizer, |
| 2985 | 2997 | trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof }, |
| 2986 | 2998 | ) !Token { |
| 2987 | const start = pp.tokens.len; | |
| 2988 | defer pp.tokens.len = start; | |
| 2989 | 2999 | var first = first_token; |
| 2990 | 3000 | |
| 2991 | 3001 | if (first.id == .angle_bracket_left) to_end: { |
| ... | ... | @@ -3008,35 +3018,60 @@ fn findIncludeFilenameToken( |
| 3008 | 3018 | }, &.{}); |
| 3009 | 3019 | try pp.err(first, .header_str_match); |
| 3010 | 3020 | } |
| 3011 | // Try to expand if the argument is a macro. | |
| 3012 | try pp.expandMacro(tokenizer, first); | |
| 3013 | 3021 | |
| 3014 | // Check that we actually got a string. | |
| 3015 | const filename_tok = pp.tokens.get(start); | |
| 3016 | switch (filename_tok.id) { | |
| 3017 | .string_literal, .macro_string => {}, | |
| 3018 | else => { | |
| 3019 | try pp.err(first, .expected_filename); | |
| 3020 | try pp.expectNl(tokenizer); | |
| 3021 | return error.InvalidInclude; | |
| 3022 | const source_tok = tokFromRaw(first); | |
| 3023 | const filename_tok, const expanded_trailing = switch (source_tok.id) { | |
| 3024 | .string_literal, .macro_string => .{ source_tok, false }, | |
| 3025 | else => expanded: { | |
| 3026 | // Try to expand if the argument is a macro. | |
| 3027 | pp.top_expansion_buf.items.len = 0; | |
| 3028 | defer for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa); | |
| 3029 | try pp.top_expansion_buf.append(source_tok); | |
| 3030 | pp.expansion_source_loc = source_tok.loc; | |
| 3031 | ||
| 3032 | try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr); | |
| 3033 | var trailing_toks: []const Token = &.{}; | |
| 3034 | const include_str = (try pp.reconstructIncludeString(pp.top_expansion_buf.items, &trailing_toks)) orelse { | |
| 3035 | try pp.err(first, .expected_filename); | |
| 3036 | try pp.expectNl(tokenizer); | |
| 3037 | return error.InvalidInclude; | |
| 3038 | }; | |
| 3039 | const start = pp.comp.generated_buf.items.len; | |
| 3040 | try pp.comp.generated_buf.appendSlice(pp.gpa, include_str); | |
| 3041 | ||
| 3042 | break :expanded .{ try pp.makeGeneratedToken(start, switch (include_str[0]) { | |
| 3043 | '"' => .string_literal, | |
| 3044 | '<' => .macro_string, | |
| 3045 | else => unreachable, | |
| 3046 | }, pp.top_expansion_buf.items[0]), trailing_toks.len != 0 }; | |
| 3022 | 3047 | }, |
| 3023 | } | |
| 3048 | }; | |
| 3049 | ||
| 3024 | 3050 | switch (trailing_token_behavior) { |
| 3025 | 3051 | .expect_nl_eof => { |
| 3026 | 3052 | // Error on extra tokens. |
| 3027 | 3053 | const nl = tokenizer.nextNoWS(); |
| 3028 | if ((nl.id != .nl and nl.id != .eof) or pp.tokens.len > start + 1) { | |
| 3054 | if ((nl.id != .nl and nl.id != .eof) or expanded_trailing) { | |
| 3029 | 3055 | skipToNl(tokenizer); |
| 3030 | try pp.err(first, .extra_tokens_directive_end); | |
| 3056 | try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{ | |
| 3057 | .tag = .extra_tokens_directive_end, | |
| 3058 | .loc = filename_tok.loc, | |
| 3059 | }, filename_tok.expansionSlice(), false); | |
| 3031 | 3060 | } |
| 3032 | 3061 | }, |
| 3033 | .ignore_trailing_tokens => {}, | |
| 3062 | .ignore_trailing_tokens => if (expanded_trailing) { | |
| 3063 | try pp.comp.diagnostics.addExtra(pp.comp.langopts, .{ | |
| 3064 | .tag = .extra_tokens_directive_end, | |
| 3065 | .loc = filename_tok.loc, | |
| 3066 | }, filename_tok.expansionSlice(), false); | |
| 3067 | }, | |
| 3034 | 3068 | } |
| 3035 | 3069 | return filename_tok; |
| 3036 | 3070 | } |
| 3037 | 3071 | |
| 3038 | 3072 | fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source { |
| 3039 | 3073 | const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof); |
| 3074 | defer Token.free(filename_tok.expansion_locs, pp.gpa); | |
| 3040 | 3075 | |
| 3041 | 3076 | // Check for empty filename. |
| 3042 | 3077 | const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws); |
| ... | ... | @@ -3054,7 +3089,7 @@ fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, |
| 3054 | 3089 | }; |
| 3055 | 3090 | |
| 3056 | 3091 | return (try pp.comp.findInclude(filename, first, include_type, which)) orelse |
| 3057 | pp.fatal(first, "'{s}' not found", .{filename}); | |
| 3092 | return pp.fatalNotFound(filename_tok, filename); | |
| 3058 | 3093 | } |
| 3059 | 3094 | |
| 3060 | 3095 | fn printLinemarker( |
deps/aro/aro/SymbolStack.zig+201-184| ... | ... | @@ -11,6 +11,8 @@ const Parser = @import("Parser.zig"); |
| 11 | 11 | const Value = @import("Value.zig"); |
| 12 | 12 | const StringId = @import("StringInterner.zig").StringId; |
| 13 | 13 | |
| 14 | const SymbolStack = @This(); | |
| 15 | ||
| 14 | 16 | pub const Symbol = struct { |
| 15 | 17 | name: StringId, |
| 16 | 18 | ty: Type, |
| ... | ... | @@ -31,72 +33,74 @@ pub const Kind = enum { |
| 31 | 33 | constexpr, |
| 32 | 34 | }; |
| 33 | 35 | |
| 34 | const SymbolStack = @This(); | |
| 36 | scopes: std.ArrayListUnmanaged(Scope) = .{}, | |
| 37 | /// allocations from nested scopes are retained after popping; `active_len` is the number | |
| 38 | /// of currently-active items in `scopes`. | |
| 39 | active_len: usize = 0, | |
| 35 | 40 | |
| 36 | syms: std.MultiArrayList(Symbol) = .{}, | |
| 37 | scopes: std.ArrayListUnmanaged(u32) = .{}, | |
| 41 | const Scope = struct { | |
| 42 | vars: std.AutoHashMapUnmanaged(StringId, Symbol) = .{}, | |
| 43 | tags: std.AutoHashMapUnmanaged(StringId, Symbol) = .{}, | |
| 44 | ||
| 45 | fn deinit(self: *Scope, allocator: Allocator) void { | |
| 46 | self.vars.deinit(allocator); | |
| 47 | self.tags.deinit(allocator); | |
| 48 | } | |
| 49 | ||
| 50 | fn clearRetainingCapacity(self: *Scope) void { | |
| 51 | self.vars.clearRetainingCapacity(); | |
| 52 | self.tags.clearRetainingCapacity(); | |
| 53 | } | |
| 54 | }; | |
| 38 | 55 | |
| 39 | 56 | pub fn deinit(s: *SymbolStack, gpa: Allocator) void { |
| 40 | s.syms.deinit(gpa); | |
| 57 | std.debug.assert(s.active_len == 0); // all scopes should have been popped | |
| 58 | for (s.scopes.items) |*scope| { | |
| 59 | scope.deinit(gpa); | |
| 60 | } | |
| 41 | 61 | s.scopes.deinit(gpa); |
| 42 | 62 | s.* = undefined; |
| 43 | 63 | } |
| 44 | 64 | |
| 45 | pub fn scopeEnd(s: SymbolStack) u32 { | |
| 46 | if (s.scopes.items.len == 0) return 0; | |
| 47 | return s.scopes.items[s.scopes.items.len - 1]; | |
| 48 | } | |
| 49 | ||
| 50 | 65 | pub fn pushScope(s: *SymbolStack, p: *Parser) !void { |
| 51 | try s.scopes.append(p.gpa, @intCast(s.syms.len)); | |
| 66 | if (s.active_len + 1 > s.scopes.items.len) { | |
| 67 | try s.scopes.append(p.gpa, .{}); | |
| 68 | s.active_len = s.scopes.items.len; | |
| 69 | } else { | |
| 70 | s.scopes.items[s.active_len].clearRetainingCapacity(); | |
| 71 | s.active_len += 1; | |
| 72 | } | |
| 52 | 73 | } |
| 53 | 74 | |
| 54 | 75 | pub fn popScope(s: *SymbolStack) void { |
| 55 | s.syms.len = s.scopes.pop(); | |
| 76 | s.active_len -= 1; | |
| 56 | 77 | } |
| 57 | 78 | |
| 58 | 79 | pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol { |
| 59 | const kinds = s.syms.items(.kind); | |
| 60 | const names = s.syms.items(.name); | |
| 61 | var i = s.syms.len; | |
| 62 | while (i > 0) { | |
| 63 | i -= 1; | |
| 64 | switch (kinds[i]) { | |
| 65 | .typedef => if (names[i] == name) return s.syms.get(i), | |
| 66 | .@"struct" => if (names[i] == name) { | |
| 67 | if (no_type_yet) return null; | |
| 68 | try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok)); | |
| 69 | return s.syms.get(i); | |
| 70 | }, | |
| 71 | .@"union" => if (names[i] == name) { | |
| 72 | if (no_type_yet) return null; | |
| 73 | try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok)); | |
| 74 | return s.syms.get(i); | |
| 75 | }, | |
| 76 | .@"enum" => if (names[i] == name) { | |
| 77 | if (no_type_yet) return null; | |
| 78 | try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok)); | |
| 79 | return s.syms.get(i); | |
| 80 | }, | |
| 81 | .def, .decl, .constexpr => if (names[i] == name) return null, | |
| 82 | else => {}, | |
| 83 | } | |
| 80 | const prev = s.lookup(name, .vars) orelse s.lookup(name, .tags) orelse return null; | |
| 81 | switch (prev.kind) { | |
| 82 | .typedef => return prev, | |
| 83 | .@"struct" => { | |
| 84 | if (no_type_yet) return null; | |
| 85 | try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok)); | |
| 86 | return prev; | |
| 87 | }, | |
| 88 | .@"union" => { | |
| 89 | if (no_type_yet) return null; | |
| 90 | try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok)); | |
| 91 | return prev; | |
| 92 | }, | |
| 93 | .@"enum" => { | |
| 94 | if (no_type_yet) return null; | |
| 95 | try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok)); | |
| 96 | return prev; | |
| 97 | }, | |
| 98 | else => return null, | |
| 84 | 99 | } |
| 85 | return null; | |
| 86 | 100 | } |
| 87 | 101 | |
| 88 | 102 | pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol { |
| 89 | const kinds = s.syms.items(.kind); | |
| 90 | const names = s.syms.items(.name); | |
| 91 | var i = s.syms.len; | |
| 92 | while (i > 0) { | |
| 93 | i -= 1; | |
| 94 | switch (kinds[i]) { | |
| 95 | .def, .decl, .enumeration, .constexpr => if (names[i] == name) return s.syms.get(i), | |
| 96 | else => {}, | |
| 97 | } | |
| 98 | } | |
| 99 | return null; | |
| 103 | return s.lookup(name, .vars); | |
| 100 | 104 | } |
| 101 | 105 | |
| 102 | 106 | pub fn findTag( |
| ... | ... | @@ -107,36 +111,62 @@ pub fn findTag( |
| 107 | 111 | name_tok: TokenIndex, |
| 108 | 112 | next_tok_id: Token.Id, |
| 109 | 113 | ) !?Symbol { |
| 110 | const kinds = s.syms.items(.kind); | |
| 111 | const names = s.syms.items(.name); | |
| 112 | 114 | // `tag Name;` should always result in a new type if in a new scope. |
| 113 | const end = if (next_tok_id == .semicolon) s.scopeEnd() else 0; | |
| 114 | var i = s.syms.len; | |
| 115 | while (i > end) { | |
| 115 | const prev = (if (next_tok_id == .semicolon) s.get(name, .tags) else s.lookup(name, .tags)) orelse return null; | |
| 116 | switch (prev.kind) { | |
| 117 | .@"enum" => if (kind == .keyword_enum) return prev, | |
| 118 | .@"struct" => if (kind == .keyword_struct) return prev, | |
| 119 | .@"union" => if (kind == .keyword_union) return prev, | |
| 120 | else => unreachable, | |
| 121 | } | |
| 122 | if (s.get(name, .tags) == null) return null; | |
| 123 | try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok)); | |
| 124 | try p.errTok(.previous_definition, prev.tok); | |
| 125 | return null; | |
| 126 | } | |
| 127 | ||
| 128 | const ScopeKind = enum { | |
| 129 | /// structs, enums, unions | |
| 130 | tags, | |
| 131 | /// everything else | |
| 132 | vars, | |
| 133 | }; | |
| 134 | ||
| 135 | /// Return the Symbol for `name` (or null if not found) in the innermost scope | |
| 136 | pub fn get(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol { | |
| 137 | return switch (kind) { | |
| 138 | .vars => s.scopes.items[s.active_len - 1].vars.get(name), | |
| 139 | .tags => s.scopes.items[s.active_len - 1].tags.get(name), | |
| 140 | }; | |
| 141 | } | |
| 142 | ||
| 143 | /// Return the Symbol for `name` (or null if not found) in the nearest active scope, | |
| 144 | /// starting at the innermost. | |
| 145 | fn lookup(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol { | |
| 146 | var i = s.active_len; | |
| 147 | while (i > 0) { | |
| 116 | 148 | i -= 1; |
| 117 | switch (kinds[i]) { | |
| 118 | .@"enum" => if (names[i] == name) { | |
| 119 | if (kind == .keyword_enum) return s.syms.get(i); | |
| 120 | break; | |
| 121 | }, | |
| 122 | .@"struct" => if (names[i] == name) { | |
| 123 | if (kind == .keyword_struct) return s.syms.get(i); | |
| 124 | break; | |
| 125 | }, | |
| 126 | .@"union" => if (names[i] == name) { | |
| 127 | if (kind == .keyword_union) return s.syms.get(i); | |
| 128 | break; | |
| 129 | }, | |
| 130 | else => {}, | |
| 149 | switch (kind) { | |
| 150 | .vars => if (s.scopes.items[i].vars.get(name)) |sym| return sym, | |
| 151 | .tags => if (s.scopes.items[i].tags.get(name)) |sym| return sym, | |
| 131 | 152 | } |
| 132 | } else return null; | |
| 133 | ||
| 134 | if (i < s.scopeEnd()) return null; | |
| 135 | try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok)); | |
| 136 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 153 | } | |
| 137 | 154 | return null; |
| 138 | 155 | } |
| 139 | 156 | |
| 157 | /// Define a symbol in the innermost scope. Does not issue diagnostics or check correctness | |
| 158 | /// with regard to the C standard. | |
| 159 | pub fn define(s: *SymbolStack, allocator: Allocator, symbol: Symbol) !void { | |
| 160 | switch (symbol.kind) { | |
| 161 | .constexpr, .def, .decl, .enumeration, .typedef => { | |
| 162 | try s.scopes.items[s.active_len - 1].vars.put(allocator, symbol.name, symbol); | |
| 163 | }, | |
| 164 | .@"struct", .@"union", .@"enum" => { | |
| 165 | try s.scopes.items[s.active_len - 1].tags.put(allocator, symbol.name, symbol); | |
| 166 | }, | |
| 167 | } | |
| 168 | } | |
| 169 | ||
| 140 | 170 | pub fn defineTypedef( |
| 141 | 171 | s: *SymbolStack, |
| 142 | 172 | p: *Parser, |
| ... | ... | @@ -145,25 +175,22 @@ pub fn defineTypedef( |
| 145 | 175 | tok: TokenIndex, |
| 146 | 176 | node: NodeIndex, |
| 147 | 177 | ) !void { |
| 148 | const kinds = s.syms.items(.kind); | |
| 149 | const names = s.syms.items(.name); | |
| 150 | const end = s.scopeEnd(); | |
| 151 | var i = s.syms.len; | |
| 152 | while (i > end) { | |
| 153 | i -= 1; | |
| 154 | switch (kinds[i]) { | |
| 155 | .typedef => if (names[i] == name) { | |
| 156 | const prev_ty = s.syms.items(.ty)[i]; | |
| 157 | if (ty.eql(prev_ty, p.comp, true)) break; | |
| 158 | try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev_ty)); | |
| 159 | const previous_tok = s.syms.items(.tok)[i]; | |
| 160 | if (previous_tok != 0) try p.errTok(.previous_definition, previous_tok); | |
| 161 | break; | |
| 178 | if (s.get(name, .vars)) |prev| { | |
| 179 | switch (prev.kind) { | |
| 180 | .typedef => { | |
| 181 | if (!ty.eql(prev.ty, p.comp, true)) { | |
| 182 | try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev.ty)); | |
| 183 | if (prev.tok != 0) try p.errTok(.previous_definition, prev.tok); | |
| 184 | } | |
| 185 | }, | |
| 186 | .enumeration, .decl, .def, .constexpr => { | |
| 187 | try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); | |
| 188 | try p.errTok(.previous_definition, prev.tok); | |
| 162 | 189 | }, |
| 163 | else => {}, | |
| 190 | else => unreachable, | |
| 164 | 191 | } |
| 165 | 192 | } |
| 166 | try s.syms.append(p.gpa, .{ | |
| 193 | try s.define(p.gpa, .{ | |
| 167 | 194 | .kind = .typedef, |
| 168 | 195 | .name = name, |
| 169 | 196 | .tok = tok, |
| ... | ... | @@ -183,35 +210,31 @@ pub fn defineSymbol( |
| 183 | 210 | val: Value, |
| 184 | 211 | constexpr: bool, |
| 185 | 212 | ) !void { |
| 186 | const kinds = s.syms.items(.kind); | |
| 187 | const names = s.syms.items(.name); | |
| 188 | const end = s.scopeEnd(); | |
| 189 | var i = s.syms.len; | |
| 190 | while (i > end) { | |
| 191 | i -= 1; | |
| 192 | switch (kinds[i]) { | |
| 193 | .enumeration => if (names[i] == name) { | |
| 213 | if (s.get(name, .vars)) |prev| { | |
| 214 | switch (prev.kind) { | |
| 215 | .enumeration => { | |
| 194 | 216 | try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); |
| 195 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 196 | break; | |
| 217 | try p.errTok(.previous_definition, prev.tok); | |
| 197 | 218 | }, |
| 198 | .decl => if (names[i] == name) { | |
| 199 | const prev_ty = s.syms.items(.ty)[i]; | |
| 200 | if (!ty.eql(prev_ty, p.comp, true)) { | |
| 219 | .decl => { | |
| 220 | if (!ty.eql(prev.ty, p.comp, true)) { | |
| 201 | 221 | try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok)); |
| 202 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 222 | try p.errTok(.previous_definition, prev.tok); | |
| 203 | 223 | } |
| 204 | break; | |
| 205 | 224 | }, |
| 206 | .def, .constexpr => if (names[i] == name) { | |
| 225 | .def, .constexpr => { | |
| 207 | 226 | try p.errStr(.redefinition, tok, p.tokSlice(tok)); |
| 208 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 209 | break; | |
| 227 | try p.errTok(.previous_definition, prev.tok); | |
| 210 | 228 | }, |
| 211 | else => {}, | |
| 229 | .typedef => { | |
| 230 | try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); | |
| 231 | try p.errTok(.previous_definition, prev.tok); | |
| 232 | }, | |
| 233 | else => unreachable, | |
| 212 | 234 | } |
| 213 | 235 | } |
| 214 | try s.syms.append(p.gpa, .{ | |
| 236 | ||
| 237 | try s.define(p.gpa, .{ | |
| 215 | 238 | .kind = if (constexpr) .constexpr else .def, |
| 216 | 239 | .name = name, |
| 217 | 240 | .tok = tok, |
| ... | ... | @@ -221,6 +244,15 @@ pub fn defineSymbol( |
| 221 | 244 | }); |
| 222 | 245 | } |
| 223 | 246 | |
| 247 | /// Get a pointer to the named symbol in the innermost scope. | |
| 248 | /// Asserts that a symbol with the name exists. | |
| 249 | pub fn getPtr(s: *SymbolStack, name: StringId, kind: ScopeKind) *Symbol { | |
| 250 | return switch (kind) { | |
| 251 | .tags => s.scopes.items[s.active_len - 1].tags.getPtr(name).?, | |
| 252 | .vars => s.scopes.items[s.active_len - 1].vars.getPtr(name).?, | |
| 253 | }; | |
| 254 | } | |
| 255 | ||
| 224 | 256 | pub fn declareSymbol( |
| 225 | 257 | s: *SymbolStack, |
| 226 | 258 | p: *Parser, |
| ... | ... | @@ -229,39 +261,34 @@ pub fn declareSymbol( |
| 229 | 261 | tok: TokenIndex, |
| 230 | 262 | node: NodeIndex, |
| 231 | 263 | ) !void { |
| 232 | const kinds = s.syms.items(.kind); | |
| 233 | const names = s.syms.items(.name); | |
| 234 | const end = s.scopeEnd(); | |
| 235 | var i = s.syms.len; | |
| 236 | while (i > end) { | |
| 237 | i -= 1; | |
| 238 | switch (kinds[i]) { | |
| 239 | .enumeration => if (names[i] == name) { | |
| 264 | if (s.get(name, .vars)) |prev| { | |
| 265 | switch (prev.kind) { | |
| 266 | .enumeration => { | |
| 240 | 267 | try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); |
| 241 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 242 | break; | |
| 268 | try p.errTok(.previous_definition, prev.tok); | |
| 243 | 269 | }, |
| 244 | .decl => if (names[i] == name) { | |
| 245 | const prev_ty = s.syms.items(.ty)[i]; | |
| 246 | if (!ty.eql(prev_ty, p.comp, true)) { | |
| 270 | .decl => { | |
| 271 | if (!ty.eql(prev.ty, p.comp, true)) { | |
| 247 | 272 | try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok)); |
| 248 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 273 | try p.errTok(.previous_definition, prev.tok); | |
| 249 | 274 | } |
| 250 | break; | |
| 251 | 275 | }, |
| 252 | .def, .constexpr => if (names[i] == name) { | |
| 253 | const prev_ty = s.syms.items(.ty)[i]; | |
| 254 | if (!ty.eql(prev_ty, p.comp, true)) { | |
| 276 | .def, .constexpr => { | |
| 277 | if (!ty.eql(prev.ty, p.comp, true)) { | |
| 255 | 278 | try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok)); |
| 256 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 257 | break; | |
| 279 | try p.errTok(.previous_definition, prev.tok); | |
| 280 | } else { | |
| 281 | return; | |
| 258 | 282 | } |
| 259 | return; | |
| 260 | 283 | }, |
| 261 | else => {}, | |
| 284 | .typedef => { | |
| 285 | try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); | |
| 286 | try p.errTok(.previous_definition, prev.tok); | |
| 287 | }, | |
| 288 | else => unreachable, | |
| 262 | 289 | } |
| 263 | 290 | } |
| 264 | try s.syms.append(p.gpa, .{ | |
| 291 | try s.define(p.gpa, .{ | |
| 265 | 292 | .kind = .decl, |
| 266 | 293 | .name = name, |
| 267 | 294 | .tok = tok, |
| ... | ... | @@ -272,25 +299,23 @@ pub fn declareSymbol( |
| 272 | 299 | } |
| 273 | 300 | |
| 274 | 301 | pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void { |
| 275 | const kinds = s.syms.items(.kind); | |
| 276 | const names = s.syms.items(.name); | |
| 277 | const end = s.scopeEnd(); | |
| 278 | var i = s.syms.len; | |
| 279 | while (i > end) { | |
| 280 | i -= 1; | |
| 281 | switch (kinds[i]) { | |
| 282 | .enumeration, .decl, .def, .constexpr => if (names[i] == name) { | |
| 302 | if (s.get(name, .vars)) |prev| { | |
| 303 | switch (prev.kind) { | |
| 304 | .enumeration, .decl, .def, .constexpr => { | |
| 283 | 305 | try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok)); |
| 284 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 285 | break; | |
| 306 | try p.errTok(.previous_definition, prev.tok); | |
| 307 | }, | |
| 308 | .typedef => { | |
| 309 | try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); | |
| 310 | try p.errTok(.previous_definition, prev.tok); | |
| 286 | 311 | }, |
| 287 | else => {}, | |
| 312 | else => unreachable, | |
| 288 | 313 | } |
| 289 | 314 | } |
| 290 | 315 | if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) { |
| 291 | 316 | try p.errStr(.suggest_pointer_for_invalid_fp16, tok, "parameters"); |
| 292 | 317 | } |
| 293 | try s.syms.append(p.gpa, .{ | |
| 318 | try s.define(p.gpa, .{ | |
| 294 | 319 | .kind = .def, |
| 295 | 320 | .name = name, |
| 296 | 321 | .tok = tok, |
| ... | ... | @@ -306,35 +331,28 @@ pub fn defineTag( |
| 306 | 331 | kind: Token.Id, |
| 307 | 332 | tok: TokenIndex, |
| 308 | 333 | ) !?Symbol { |
| 309 | const kinds = s.syms.items(.kind); | |
| 310 | const names = s.syms.items(.name); | |
| 311 | const end = s.scopeEnd(); | |
| 312 | var i = s.syms.len; | |
| 313 | while (i > end) { | |
| 314 | i -= 1; | |
| 315 | switch (kinds[i]) { | |
| 316 | .@"enum" => if (names[i] == name) { | |
| 317 | if (kind == .keyword_enum) return s.syms.get(i); | |
| 318 | try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); | |
| 319 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 320 | return null; | |
| 321 | }, | |
| 322 | .@"struct" => if (names[i] == name) { | |
| 323 | if (kind == .keyword_struct) return s.syms.get(i); | |
| 324 | try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); | |
| 325 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 326 | return null; | |
| 327 | }, | |
| 328 | .@"union" => if (names[i] == name) { | |
| 329 | if (kind == .keyword_union) return s.syms.get(i); | |
| 330 | try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); | |
| 331 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 332 | return null; | |
| 333 | }, | |
| 334 | else => {}, | |
| 335 | } | |
| 334 | const prev = s.get(name, .tags) orelse return null; | |
| 335 | switch (prev.kind) { | |
| 336 | .@"enum" => { | |
| 337 | if (kind == .keyword_enum) return prev; | |
| 338 | try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); | |
| 339 | try p.errTok(.previous_definition, prev.tok); | |
| 340 | return null; | |
| 341 | }, | |
| 342 | .@"struct" => { | |
| 343 | if (kind == .keyword_struct) return prev; | |
| 344 | try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); | |
| 345 | try p.errTok(.previous_definition, prev.tok); | |
| 346 | return null; | |
| 347 | }, | |
| 348 | .@"union" => { | |
| 349 | if (kind == .keyword_union) return prev; | |
| 350 | try p.errStr(.wrong_tag, tok, p.tokSlice(tok)); | |
| 351 | try p.errTok(.previous_definition, prev.tok); | |
| 352 | return null; | |
| 353 | }, | |
| 354 | else => unreachable, | |
| 336 | 355 | } |
| 337 | return null; | |
| 338 | 356 | } |
| 339 | 357 | |
| 340 | 358 | pub fn defineEnumeration( |
| ... | ... | @@ -345,27 +363,26 @@ pub fn defineEnumeration( |
| 345 | 363 | tok: TokenIndex, |
| 346 | 364 | val: Value, |
| 347 | 365 | ) !void { |
| 348 | const kinds = s.syms.items(.kind); | |
| 349 | const names = s.syms.items(.name); | |
| 350 | const end = s.scopeEnd(); | |
| 351 | var i = s.syms.len; | |
| 352 | while (i > end) { | |
| 353 | i -= 1; | |
| 354 | switch (kinds[i]) { | |
| 355 | .enumeration => if (names[i] == name) { | |
| 366 | if (s.get(name, .vars)) |prev| { | |
| 367 | switch (prev.kind) { | |
| 368 | .enumeration => { | |
| 356 | 369 | try p.errStr(.redefinition, tok, p.tokSlice(tok)); |
| 357 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 370 | try p.errTok(.previous_definition, prev.tok); | |
| 358 | 371 | return; |
| 359 | 372 | }, |
| 360 | .decl, .def, .constexpr => if (names[i] == name) { | |
| 373 | .decl, .def, .constexpr => { | |
| 361 | 374 | try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); |
| 362 | try p.errTok(.previous_definition, s.syms.items(.tok)[i]); | |
| 375 | try p.errTok(.previous_definition, prev.tok); | |
| 363 | 376 | return; |
| 364 | 377 | }, |
| 365 | else => {}, | |
| 378 | .typedef => { | |
| 379 | try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok)); | |
| 380 | try p.errTok(.previous_definition, prev.tok); | |
| 381 | }, | |
| 382 | else => unreachable, | |
| 366 | 383 | } |
| 367 | 384 | } |
| 368 | try s.syms.append(p.gpa, .{ | |
| 385 | try s.define(p.gpa, .{ | |
| 369 | 386 | .kind = .enumeration, |
| 370 | 387 | .name = name, |
| 371 | 388 | .tok = tok, |
deps/aro/aro/Tokenizer.zig+26-23| ... | ... | @@ -749,12 +749,15 @@ pub const Token = struct { |
| 749 | 749 | .string_literal_utf_8, |
| 750 | 750 | .string_literal_utf_32, |
| 751 | 751 | .string_literal_wide, |
| 752 | .unterminated_string_literal, | |
| 752 | 753 | => "a string literal", |
| 753 | 754 | .char_literal, |
| 754 | 755 | .char_literal_utf_8, |
| 755 | 756 | .char_literal_utf_16, |
| 756 | 757 | .char_literal_utf_32, |
| 757 | 758 | .char_literal_wide, |
| 759 | .unterminated_char_literal, | |
| 760 | .empty_char_literal, | |
| 758 | 761 | => "a character literal", |
| 759 | 762 | .pp_num, .embed_byte => "A number", |
| 760 | 763 | else => id.lexeme().?, |
| ... | ... | @@ -798,7 +801,7 @@ pub const Token = struct { |
| 798 | 801 | }; |
| 799 | 802 | } |
| 800 | 803 | |
| 801 | pub fn allowsDigraphs(id: Id, comp: *const Compilation) bool { | |
| 804 | pub fn allowsDigraphs(id: Id, langopts: LangOpts) bool { | |
| 802 | 805 | return switch (id) { |
| 803 | 806 | .l_bracket, |
| 804 | 807 | .r_bracket, |
| ... | ... | @@ -806,7 +809,7 @@ pub const Token = struct { |
| 806 | 809 | .r_brace, |
| 807 | 810 | .hash, |
| 808 | 811 | .hash_hash, |
| 809 | => comp.langopts.hasDigraphs(), | |
| 812 | => langopts.hasDigraphs(), | |
| 810 | 813 | else => false, |
| 811 | 814 | }; |
| 812 | 815 | } |
| ... | ... | @@ -829,15 +832,15 @@ pub const Token = struct { |
| 829 | 832 | /// double underscore and underscore + capital letter identifiers |
| 830 | 833 | /// belong to the implementation namespace, so we always convert them |
| 831 | 834 | /// to keywords. |
| 832 | pub fn getTokenId(comp: *const Compilation, str: []const u8) Token.Id { | |
| 835 | pub fn getTokenId(langopts: LangOpts, str: []const u8) Token.Id { | |
| 833 | 836 | const kw = all_kws.get(str) orelse return .identifier; |
| 834 | const standard = comp.langopts.standard; | |
| 837 | const standard = langopts.standard; | |
| 835 | 838 | return switch (kw) { |
| 836 | 839 | .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier, |
| 837 | 840 | .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier, |
| 838 | 841 | .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c23)) kw else .identifier, |
| 839 | 842 | .keyword_asm => if (standard.isGNU()) kw else .identifier, |
| 840 | .keyword_declspec => if (comp.langopts.declspec_attrs) kw else .identifier, | |
| 843 | .keyword_declspec => if (langopts.declspec_attrs) kw else .identifier, | |
| 841 | 844 | |
| 842 | 845 | .keyword_c23_alignas, |
| 843 | 846 | .keyword_c23_alignof, |
| ... | ... | @@ -864,7 +867,7 @@ pub const Token = struct { |
| 864 | 867 | .keyword_stdcall2, |
| 865 | 868 | .keyword_thiscall2, |
| 866 | 869 | .keyword_vectorcall2, |
| 867 | => if (comp.langopts.ms_extensions) kw else .identifier, | |
| 870 | => if (langopts.ms_extensions) kw else .identifier, | |
| 868 | 871 | else => kw, |
| 869 | 872 | }; |
| 870 | 873 | } |
| ... | ... | @@ -1023,7 +1026,7 @@ const Tokenizer = @This(); |
| 1023 | 1026 | buf: []const u8, |
| 1024 | 1027 | index: u32 = 0, |
| 1025 | 1028 | source: Source.Id, |
| 1026 | comp: *const Compilation, | |
| 1029 | langopts: LangOpts, | |
| 1027 | 1030 | line: u32 = 1, |
| 1028 | 1031 | |
| 1029 | 1032 | pub fn next(self: *Tokenizer) Token { |
| ... | ... | @@ -1162,14 +1165,14 @@ pub fn next(self: *Tokenizer) Token { |
| 1162 | 1165 | '#' => state = .hash, |
| 1163 | 1166 | '0'...'9' => state = .pp_num, |
| 1164 | 1167 | '\t', '\x0B', '\x0C', ' ' => state = .whitespace, |
| 1165 | '$' => if (self.comp.langopts.dollars_in_identifiers) { | |
| 1168 | '$' => if (self.langopts.dollars_in_identifiers) { | |
| 1166 | 1169 | state = .extended_identifier; |
| 1167 | 1170 | } else { |
| 1168 | 1171 | id = .invalid; |
| 1169 | 1172 | self.index += 1; |
| 1170 | 1173 | break; |
| 1171 | 1174 | }, |
| 1172 | 0x1A => if (self.comp.langopts.ms_extensions) { | |
| 1175 | 0x1A => if (self.langopts.ms_extensions) { | |
| 1173 | 1176 | id = .eof; |
| 1174 | 1177 | break; |
| 1175 | 1178 | } else { |
| ... | ... | @@ -1306,15 +1309,15 @@ pub fn next(self: *Tokenizer) Token { |
| 1306 | 1309 | }, |
| 1307 | 1310 | .identifier, .extended_identifier => switch (c) { |
| 1308 | 1311 | 'a'...'z', 'A'...'Z', '_', '0'...'9' => {}, |
| 1309 | '$' => if (self.comp.langopts.dollars_in_identifiers) { | |
| 1312 | '$' => if (self.langopts.dollars_in_identifiers) { | |
| 1310 | 1313 | state = .extended_identifier; |
| 1311 | 1314 | } else { |
| 1312 | id = if (state == .identifier) Token.getTokenId(self.comp, self.buf[start..self.index]) else .extended_identifier; | |
| 1315 | id = if (state == .identifier) Token.getTokenId(self.langopts, self.buf[start..self.index]) else .extended_identifier; | |
| 1313 | 1316 | break; |
| 1314 | 1317 | }, |
| 1315 | 1318 | 0x80...0xFF => state = .extended_identifier, |
| 1316 | 1319 | else => { |
| 1317 | id = if (state == .identifier) Token.getTokenId(self.comp, self.buf[start..self.index]) else .extended_identifier; | |
| 1320 | id = if (state == .identifier) Token.getTokenId(self.langopts, self.buf[start..self.index]) else .extended_identifier; | |
| 1318 | 1321 | break; |
| 1319 | 1322 | }, |
| 1320 | 1323 | }, |
| ... | ... | @@ -1358,7 +1361,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1358 | 1361 | }, |
| 1359 | 1362 | .colon => switch (c) { |
| 1360 | 1363 | '>' => { |
| 1361 | if (self.comp.langopts.hasDigraphs()) { | |
| 1364 | if (self.langopts.hasDigraphs()) { | |
| 1362 | 1365 | id = .r_bracket; |
| 1363 | 1366 | self.index += 1; |
| 1364 | 1367 | } else { |
| ... | ... | @@ -1367,7 +1370,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1367 | 1370 | break; |
| 1368 | 1371 | }, |
| 1369 | 1372 | ':' => { |
| 1370 | if (self.comp.langopts.standard.atLeast(.c23)) { | |
| 1373 | if (self.langopts.standard.atLeast(.c23)) { | |
| 1371 | 1374 | id = .colon_colon; |
| 1372 | 1375 | self.index += 1; |
| 1373 | 1376 | break; |
| ... | ... | @@ -1388,7 +1391,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1388 | 1391 | break; |
| 1389 | 1392 | }, |
| 1390 | 1393 | '>' => { |
| 1391 | if (self.comp.langopts.hasDigraphs()) { | |
| 1394 | if (self.langopts.hasDigraphs()) { | |
| 1392 | 1395 | id = .r_brace; |
| 1393 | 1396 | self.index += 1; |
| 1394 | 1397 | } else { |
| ... | ... | @@ -1397,7 +1400,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1397 | 1400 | break; |
| 1398 | 1401 | }, |
| 1399 | 1402 | ':' => { |
| 1400 | if (self.comp.langopts.hasDigraphs()) { | |
| 1403 | if (self.langopts.hasDigraphs()) { | |
| 1401 | 1404 | state = .hash_digraph; |
| 1402 | 1405 | } else { |
| 1403 | 1406 | id = .percent; |
| ... | ... | @@ -1444,7 +1447,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1444 | 1447 | break; |
| 1445 | 1448 | }, |
| 1446 | 1449 | ':' => { |
| 1447 | if (self.comp.langopts.hasDigraphs()) { | |
| 1450 | if (self.langopts.hasDigraphs()) { | |
| 1448 | 1451 | id = .l_bracket; |
| 1449 | 1452 | self.index += 1; |
| 1450 | 1453 | } else { |
| ... | ... | @@ -1453,7 +1456,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1453 | 1456 | break; |
| 1454 | 1457 | }, |
| 1455 | 1458 | '%' => { |
| 1456 | if (self.comp.langopts.hasDigraphs()) { | |
| 1459 | if (self.langopts.hasDigraphs()) { | |
| 1457 | 1460 | id = .l_brace; |
| 1458 | 1461 | self.index += 1; |
| 1459 | 1462 | } else { |
| ... | ... | @@ -1613,7 +1616,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1613 | 1616 | }, |
| 1614 | 1617 | .line_comment => switch (c) { |
| 1615 | 1618 | '\n' => { |
| 1616 | if (self.comp.langopts.preserve_comments) { | |
| 1619 | if (self.langopts.preserve_comments) { | |
| 1617 | 1620 | id = .comment; |
| 1618 | 1621 | break; |
| 1619 | 1622 | } |
| ... | ... | @@ -1629,7 +1632,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1629 | 1632 | }, |
| 1630 | 1633 | .multi_line_comment_asterisk => switch (c) { |
| 1631 | 1634 | '/' => { |
| 1632 | if (self.comp.langopts.preserve_comments) { | |
| 1635 | if (self.langopts.preserve_comments) { | |
| 1633 | 1636 | self.index += 1; |
| 1634 | 1637 | id = .comment; |
| 1635 | 1638 | break; |
| ... | ... | @@ -1673,7 +1676,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1673 | 1676 | '.', |
| 1674 | 1677 | => {}, |
| 1675 | 1678 | 'e', 'E', 'p', 'P' => state = .pp_num_exponent, |
| 1676 | '\'' => if (self.comp.langopts.standard.atLeast(.c23)) { | |
| 1679 | '\'' => if (self.langopts.standard.atLeast(.c23)) { | |
| 1677 | 1680 | state = .pp_num_digit_separator; |
| 1678 | 1681 | } else { |
| 1679 | 1682 | id = .pp_num; |
| ... | ... | @@ -1721,7 +1724,7 @@ pub fn next(self: *Tokenizer) Token { |
| 1721 | 1724 | } else if (self.index == self.buf.len) { |
| 1722 | 1725 | switch (state) { |
| 1723 | 1726 | .start, .line_comment => {}, |
| 1724 | .u, .u8, .U, .L, .identifier => id = Token.getTokenId(self.comp, self.buf[start..self.index]), | |
| 1727 | .u, .u8, .U, .L, .identifier => id = Token.getTokenId(self.langopts, self.buf[start..self.index]), | |
| 1725 | 1728 | .extended_identifier => id = .extended_identifier, |
| 1726 | 1729 | |
| 1727 | 1730 | .period2 => { |
| ... | ... | @@ -2149,7 +2152,7 @@ fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, st |
| 2149 | 2152 | var tokenizer = Tokenizer{ |
| 2150 | 2153 | .buf = source.buf, |
| 2151 | 2154 | .source = source.id, |
| 2152 | .comp = &comp, | |
| 2155 | .langopts = comp.langopts, | |
| 2153 | 2156 | }; |
| 2154 | 2157 | var i: usize = 0; |
| 2155 | 2158 | while (i < expected_tokens.len) { |
deps/aro/aro/Toolchain.zig+5-8| ... | ... | @@ -183,18 +183,15 @@ pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 { |
| 183 | 183 | return tc.getProgramPath(default_linker, buf); |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | const TargetSpecificToolName = std.BoundedArray(u8, 64); | |
| 187 | ||
| 188 | 186 | /// If an explicit target is provided, also check the prefixed tool-specific name |
| 189 | 187 | /// TODO: this isn't exactly right since our target names don't necessarily match up |
| 190 | 188 | /// with GCC's. |
| 191 | 189 | /// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools |
| 192 | fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, target_specific: *TargetSpecificToolName) std.BoundedArray([]const u8, 2) { | |
| 190 | fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, buf: *[64]u8) std.BoundedArray([]const u8, 2) { | |
| 193 | 191 | var possible_names: std.BoundedArray([]const u8, 2) = .{}; |
| 194 | 192 | if (raw_triple) |triple| { |
| 195 | const w = target_specific.writer(); | |
| 196 | if (w.print("{s}-{s}", .{ triple, name })) { | |
| 197 | possible_names.appendAssumeCapacity(target_specific.constSlice()); | |
| 193 | if (std.fmt.bufPrint(buf, "{s}-{s}", .{ triple, name })) |res| { | |
| 194 | possible_names.appendAssumeCapacity(res); | |
| 198 | 195 | } else |_| {} |
| 199 | 196 | } |
| 200 | 197 | possible_names.appendAssumeCapacity(name); |
| ... | ... | @@ -227,8 +224,8 @@ fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8 |
| 227 | 224 | var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; |
| 228 | 225 | var fib = std.heap.FixedBufferAllocator.init(&path_buf); |
| 229 | 226 | |
| 230 | var tool_specific_name: TargetSpecificToolName = .{}; | |
| 231 | const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_name); | |
| 227 | var tool_specific_buf: [64]u8 = undefined; | |
| 228 | const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_buf); | |
| 232 | 229 | |
| 233 | 230 | for (possible_names.constSlice()) |tool_name| { |
| 234 | 231 | for (tc.program_paths.items) |program_path| { |
deps/aro/aro/Tree.zig+7-4| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const Interner = @import("backend").Interner; |
| 3 | const Type = @import("Type.zig"); | |
| 4 | const Tokenizer = @import("Tokenizer.zig"); | |
| 3 | const Attribute = @import("Attribute.zig"); | |
| 5 | 4 | const CodeGen = @import("CodeGen.zig"); |
| 6 | 5 | const Compilation = @import("Compilation.zig"); |
| 6 | const number_affixes = @import("Tree/number_affixes.zig"); | |
| 7 | 7 | const Source = @import("Source.zig"); |
| 8 | const Attribute = @import("Attribute.zig"); | |
| 8 | const Tokenizer = @import("Tokenizer.zig"); | |
| 9 | const Type = @import("Type.zig"); | |
| 9 | 10 | const Value = @import("Value.zig"); |
| 10 | 11 | const StringInterner = @import("StringInterner.zig"); |
| 11 | 12 | |
| ... | ... | @@ -92,6 +93,8 @@ pub const Token = struct { |
| 92 | 93 | |
| 93 | 94 | pub const List = std.MultiArrayList(Token); |
| 94 | 95 | pub const Id = Tokenizer.Token.Id; |
| 96 | pub const NumberPrefix = number_affixes.Prefix; | |
| 97 | pub const NumberSuffix = number_affixes.Suffix; | |
| 95 | 98 | }; |
| 96 | 99 | |
| 97 | 100 | pub const TokenIndex = u32; |
| ... | ... | @@ -669,7 +672,7 @@ pub fn tokSlice(tree: *const Tree, tok_i: TokenIndex) []const u8 { |
| 669 | 672 | const loc = tree.tokens.items(.loc)[tok_i]; |
| 670 | 673 | var tmp_tokenizer = Tokenizer{ |
| 671 | 674 | .buf = tree.comp.getSource(loc.id).buf, |
| 672 | .comp = tree.comp, | |
| 675 | .langopts = tree.comp.langopts, | |
| 673 | 676 | .index = loc.byte_offset, |
| 674 | 677 | .source = .generated, |
| 675 | 678 | }; |
deps/aro/aro/Tree/number_affixes.zig created+187| ... | ... | @@ -0,0 +1,187 @@ |
| 1 | const std = @import("std"); | |
| 2 | const mem = std.mem; | |
| 3 | ||
| 4 | pub const Prefix = enum(u8) { | |
| 5 | binary = 2, | |
| 6 | octal = 8, | |
| 7 | decimal = 10, | |
| 8 | hex = 16, | |
| 9 | ||
| 10 | pub fn digitAllowed(prefix: Prefix, c: u8) bool { | |
| 11 | return switch (c) { | |
| 12 | '0', '1' => true, | |
| 13 | '2'...'7' => prefix != .binary, | |
| 14 | '8'...'9' => prefix == .decimal or prefix == .hex, | |
| 15 | 'a'...'f', 'A'...'F' => prefix == .hex, | |
| 16 | else => false, | |
| 17 | }; | |
| 18 | } | |
| 19 | ||
| 20 | pub fn fromString(buf: []const u8) Prefix { | |
| 21 | if (buf.len == 1) return .decimal; | |
| 22 | // tokenizer enforces that first byte is a decimal digit or period | |
| 23 | switch (buf[0]) { | |
| 24 | '.', '1'...'9' => return .decimal, | |
| 25 | '0' => {}, | |
| 26 | else => unreachable, | |
| 27 | } | |
| 28 | switch (buf[1]) { | |
| 29 | 'x', 'X' => return if (buf.len == 2) .decimal else .hex, | |
| 30 | 'b', 'B' => return if (buf.len == 2) .decimal else .binary, | |
| 31 | else => { | |
| 32 | if (mem.indexOfAny(u8, buf, "eE.")) |_| { | |
| 33 | // This is a decimal floating point number that happens to start with zero | |
| 34 | return .decimal; | |
| 35 | } else if (Suffix.fromString(buf[1..], .int)) |_| { | |
| 36 | // This is `0` with a valid suffix | |
| 37 | return .decimal; | |
| 38 | } else { | |
| 39 | return .octal; | |
| 40 | } | |
| 41 | }, | |
| 42 | } | |
| 43 | } | |
| 44 | ||
| 45 | /// Length of this prefix as a string | |
| 46 | pub fn stringLen(prefix: Prefix) usize { | |
| 47 | return switch (prefix) { | |
| 48 | .binary => 2, | |
| 49 | .octal => 1, | |
| 50 | .decimal => 0, | |
| 51 | .hex => 2, | |
| 52 | }; | |
| 53 | } | |
| 54 | }; | |
| 55 | ||
| 56 | pub const Suffix = enum { | |
| 57 | // zig fmt: off | |
| 58 | ||
| 59 | // int and imaginary int | |
| 60 | None, I, | |
| 61 | ||
| 62 | // unsigned real integers | |
| 63 | U, UL, ULL, | |
| 64 | ||
| 65 | // unsigned imaginary integers | |
| 66 | IU, IUL, IULL, | |
| 67 | ||
| 68 | // long or long double, real and imaginary | |
| 69 | L, IL, | |
| 70 | ||
| 71 | // long long and imaginary long long | |
| 72 | LL, ILL, | |
| 73 | ||
| 74 | // float and imaginary float | |
| 75 | F, IF, | |
| 76 | ||
| 77 | // _Float16 | |
| 78 | F16, | |
| 79 | ||
| 80 | // __float80 | |
| 81 | W, | |
| 82 | ||
| 83 | // Imaginary __float80 | |
| 84 | IW, | |
| 85 | ||
| 86 | // _Float128 | |
| 87 | Q, F128, | |
| 88 | ||
| 89 | // Imaginary _Float128 | |
| 90 | IQ, IF128, | |
| 91 | ||
| 92 | // Imaginary _Bitint | |
| 93 | IWB, IUWB, | |
| 94 | ||
| 95 | // _Bitint | |
| 96 | WB, UWB, | |
| 97 | ||
| 98 | // zig fmt: on | |
| 99 | ||
| 100 | const Tuple = struct { Suffix, []const []const u8 }; | |
| 101 | ||
| 102 | const IntSuffixes = &[_]Tuple{ | |
| 103 | .{ .U, &.{"U"} }, | |
| 104 | .{ .L, &.{"L"} }, | |
| 105 | .{ .WB, &.{"WB"} }, | |
| 106 | .{ .UL, &.{ "U", "L" } }, | |
| 107 | .{ .UWB, &.{ "U", "WB" } }, | |
| 108 | .{ .LL, &.{"LL"} }, | |
| 109 | .{ .ULL, &.{ "U", "LL" } }, | |
| 110 | ||
| 111 | .{ .I, &.{"I"} }, | |
| 112 | ||
| 113 | .{ .IWB, &.{ "I", "WB" } }, | |
| 114 | .{ .IU, &.{ "I", "U" } }, | |
| 115 | .{ .IL, &.{ "I", "L" } }, | |
| 116 | .{ .IUL, &.{ "I", "U", "L" } }, | |
| 117 | .{ .IUWB, &.{ "I", "U", "WB" } }, | |
| 118 | .{ .ILL, &.{ "I", "LL" } }, | |
| 119 | .{ .IULL, &.{ "I", "U", "LL" } }, | |
| 120 | }; | |
| 121 | ||
| 122 | const FloatSuffixes = &[_]Tuple{ | |
| 123 | .{ .F16, &.{"F16"} }, | |
| 124 | .{ .F, &.{"F"} }, | |
| 125 | .{ .L, &.{"L"} }, | |
| 126 | .{ .W, &.{"W"} }, | |
| 127 | .{ .F128, &.{"F128"} }, | |
| 128 | .{ .Q, &.{"Q"} }, | |
| 129 | ||
| 130 | .{ .I, &.{"I"} }, | |
| 131 | .{ .IL, &.{ "I", "L" } }, | |
| 132 | .{ .IF, &.{ "I", "F" } }, | |
| 133 | .{ .IW, &.{ "I", "W" } }, | |
| 134 | .{ .IF128, &.{ "I", "F128" } }, | |
| 135 | .{ .IQ, &.{ "I", "Q" } }, | |
| 136 | }; | |
| 137 | ||
| 138 | pub fn fromString(buf: []const u8, suffix_kind: enum { int, float }) ?Suffix { | |
| 139 | if (buf.len == 0) return .None; | |
| 140 | ||
| 141 | const suffixes = switch (suffix_kind) { | |
| 142 | .float => FloatSuffixes, | |
| 143 | .int => IntSuffixes, | |
| 144 | }; | |
| 145 | var scratch: [4]u8 = undefined; | |
| 146 | top: for (suffixes) |candidate| { | |
| 147 | const tag = candidate[0]; | |
| 148 | const parts = candidate[1]; | |
| 149 | var len: usize = 0; | |
| 150 | for (parts) |part| len += part.len; | |
| 151 | if (len != buf.len) continue; | |
| 152 | ||
| 153 | for (parts) |part| { | |
| 154 | const lower = std.ascii.lowerString(&scratch, part); | |
| 155 | if (mem.indexOf(u8, buf, part) == null and mem.indexOf(u8, buf, lower) == null) continue :top; | |
| 156 | } | |
| 157 | return tag; | |
| 158 | } | |
| 159 | return null; | |
| 160 | } | |
| 161 | ||
| 162 | pub fn isImaginary(suffix: Suffix) bool { | |
| 163 | return switch (suffix) { | |
| 164 | .I, .IL, .IF, .IU, .IUL, .ILL, .IULL, .IWB, .IUWB, .IF128, .IQ, .IW => true, | |
| 165 | .None, .L, .F16, .F, .U, .UL, .LL, .ULL, .WB, .UWB, .F128, .Q, .W => false, | |
| 166 | }; | |
| 167 | } | |
| 168 | ||
| 169 | pub fn isSignedInteger(suffix: Suffix) bool { | |
| 170 | return switch (suffix) { | |
| 171 | .None, .L, .LL, .I, .IL, .ILL, .WB, .IWB => true, | |
| 172 | .U, .UL, .ULL, .IU, .IUL, .IULL, .UWB, .IUWB => false, | |
| 173 | .F, .IF, .F16, .F128, .IF128, .Q, .IQ, .W, .IW => unreachable, | |
| 174 | }; | |
| 175 | } | |
| 176 | ||
| 177 | pub fn signedness(suffix: Suffix) std.builtin.Signedness { | |
| 178 | return if (suffix.isSignedInteger()) .signed else .unsigned; | |
| 179 | } | |
| 180 | ||
| 181 | pub fn isBitInt(suffix: Suffix) bool { | |
| 182 | return switch (suffix) { | |
| 183 | .WB, .UWB, .IWB, .IUWB => true, | |
| 184 | else => false, | |
| 185 | }; | |
| 186 | } | |
| 187 | }; |
deps/aro/aro/Type.zig+157-212| ... | ... | @@ -363,7 +363,6 @@ pub const Specifier = enum { |
| 363 | 363 | // data.sub_type |
| 364 | 364 | pointer, |
| 365 | 365 | unspecified_variable_len_array, |
| 366 | decayed_unspecified_variable_len_array, | |
| 367 | 366 | // data.func |
| 368 | 367 | /// int foo(int bar, char baz) and int (void) |
| 369 | 368 | func, |
| ... | ... | @@ -375,15 +374,11 @@ pub const Specifier = enum { |
| 375 | 374 | |
| 376 | 375 | // data.array |
| 377 | 376 | array, |
| 378 | decayed_array, | |
| 379 | 377 | static_array, |
| 380 | decayed_static_array, | |
| 381 | 378 | incomplete_array, |
| 382 | decayed_incomplete_array, | |
| 383 | 379 | vector, |
| 384 | 380 | // data.expr |
| 385 | 381 | variable_len_array, |
| 386 | decayed_variable_len_array, | |
| 387 | 382 | |
| 388 | 383 | // data.record |
| 389 | 384 | @"struct", |
| ... | ... | @@ -394,13 +389,9 @@ pub const Specifier = enum { |
| 394 | 389 | |
| 395 | 390 | /// typeof(type-name) |
| 396 | 391 | typeof_type, |
| 397 | /// decayed array created with typeof(type-name) | |
| 398 | decayed_typeof_type, | |
| 399 | 392 | |
| 400 | 393 | /// typeof(expression) |
| 401 | 394 | typeof_expr, |
| 402 | /// decayed array created with typeof(expression) | |
| 403 | decayed_typeof_expr, | |
| 404 | 395 | |
| 405 | 396 | /// data.attributed |
| 406 | 397 | attributed, |
| ... | ... | @@ -428,6 +419,7 @@ data: union { |
| 428 | 419 | } = .{ .none = {} }, |
| 429 | 420 | specifier: Specifier, |
| 430 | 421 | qual: Qualifiers = .{}, |
| 422 | decayed: bool = false, | |
| 431 | 423 | |
| 432 | 424 | pub const int = Type{ .specifier = .int }; |
| 433 | 425 | pub const invalid = Type{ .specifier = .invalid }; |
| ... | ... | @@ -442,7 +434,7 @@ pub fn is(ty: Type, specifier: Specifier) bool { |
| 442 | 434 | pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type { |
| 443 | 435 | if (attributes.len == 0) return self; |
| 444 | 436 | const attributed_type = try Type.Attributed.create(allocator, self, self.getAttributes(), attributes); |
| 445 | return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type } }; | |
| 437 | return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type }, .decayed = self.decayed }; | |
| 446 | 438 | } |
| 447 | 439 | |
| 448 | 440 | pub fn isCallable(ty: Type) ?Type { |
| ... | ... | @@ -468,10 +460,10 @@ pub fn isFunc(ty: Type) bool { |
| 468 | 460 | |
| 469 | 461 | pub fn isArray(ty: Type) bool { |
| 470 | 462 | return switch (ty.specifier) { |
| 471 | .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => true, | |
| 472 | .typeof_type => ty.data.sub_type.isArray(), | |
| 473 | .typeof_expr => ty.data.expr.ty.isArray(), | |
| 474 | .attributed => ty.data.attributed.base.isArray(), | |
| 463 | .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => !ty.isDecayed(), | |
| 464 | .typeof_type => !ty.isDecayed() and ty.data.sub_type.isArray(), | |
| 465 | .typeof_expr => !ty.isDecayed() and ty.data.expr.ty.isArray(), | |
| 466 | .attributed => !ty.isDecayed() and ty.data.attributed.base.isArray(), | |
| 475 | 467 | else => false, |
| 476 | 468 | }; |
| 477 | 469 | } |
| ... | ... | @@ -502,35 +494,22 @@ pub fn isScalarNonInt(ty: Type) bool { |
| 502 | 494 | } |
| 503 | 495 | |
| 504 | 496 | pub fn isDecayed(ty: Type) bool { |
| 505 | const decayed = switch (ty.specifier) { | |
| 506 | .decayed_array, | |
| 507 | .decayed_static_array, | |
| 508 | .decayed_incomplete_array, | |
| 509 | .decayed_variable_len_array, | |
| 510 | .decayed_unspecified_variable_len_array, | |
| 511 | .decayed_typeof_type, | |
| 512 | .decayed_typeof_expr, | |
| 513 | => true, | |
| 514 | else => false, | |
| 515 | }; | |
| 516 | std.debug.assert(decayed or !std.mem.startsWith(u8, @tagName(ty.specifier), "decayed")); | |
| 517 | return decayed; | |
| 497 | return ty.decayed; | |
| 518 | 498 | } |
| 519 | 499 | |
| 520 | 500 | pub fn isPtr(ty: Type) bool { |
| 521 | 501 | return switch (ty.specifier) { |
| 522 | .pointer, | |
| 523 | .decayed_array, | |
| 524 | .decayed_static_array, | |
| 525 | .decayed_incomplete_array, | |
| 526 | .decayed_variable_len_array, | |
| 527 | .decayed_unspecified_variable_len_array, | |
| 528 | .decayed_typeof_type, | |
| 529 | .decayed_typeof_expr, | |
| 530 | => true, | |
| 531 | .typeof_type => ty.data.sub_type.isPtr(), | |
| 532 | .typeof_expr => ty.data.expr.ty.isPtr(), | |
| 533 | .attributed => ty.data.attributed.base.isPtr(), | |
| 502 | .pointer => true, | |
| 503 | ||
| 504 | .array, | |
| 505 | .static_array, | |
| 506 | .incomplete_array, | |
| 507 | .variable_len_array, | |
| 508 | .unspecified_variable_len_array, | |
| 509 | => ty.isDecayed(), | |
| 510 | .typeof_type => ty.isDecayed() or ty.data.sub_type.isPtr(), | |
| 511 | .typeof_expr => ty.isDecayed() or ty.data.expr.ty.isPtr(), | |
| 512 | .attributed => ty.isDecayed() or ty.data.attributed.base.isPtr(), | |
| 534 | 513 | else => false, |
| 535 | 514 | }; |
| 536 | 515 | } |
| ... | ... | @@ -608,15 +587,15 @@ pub fn isVoidStar(ty: Type) bool { |
| 608 | 587 | |
| 609 | 588 | pub fn isTypeof(ty: Type) bool { |
| 610 | 589 | return switch (ty.specifier) { |
| 611 | .typeof_type, .typeof_expr, .decayed_typeof_type, .decayed_typeof_expr => true, | |
| 590 | .typeof_type, .typeof_expr => true, | |
| 612 | 591 | else => false, |
| 613 | 592 | }; |
| 614 | 593 | } |
| 615 | 594 | |
| 616 | 595 | pub fn isConst(ty: Type) bool { |
| 617 | 596 | return switch (ty.specifier) { |
| 618 | .typeof_type, .decayed_typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(), | |
| 619 | .typeof_expr, .decayed_typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(), | |
| 597 | .typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(), | |
| 598 | .typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(), | |
| 620 | 599 | .attributed => ty.data.attributed.base.isConst(), |
| 621 | 600 | else => ty.qual.@"const", |
| 622 | 601 | }; |
| ... | ... | @@ -630,7 +609,7 @@ pub fn signedness(ty: Type, comp: *const Compilation) std.builtin.Signedness { |
| 630 | 609 | return switch (ty.specifier) { |
| 631 | 610 | // zig fmt: off |
| 632 | 611 | .char, .complex_char => return comp.getCharSignedness(), |
| 633 | .uchar, .ushort, .uint, .ulong, .ulong_long, .bool, .complex_uchar, .complex_ushort, | |
| 612 | .uchar, .ushort, .uint, .ulong, .ulong_long, .uint128, .bool, .complex_uchar, .complex_ushort, | |
| 634 | 613 | .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => .unsigned, |
| 635 | 614 | // zig fmt: on |
| 636 | 615 | .bit_int, .complex_bit_int => ty.data.int.signedness, |
| ... | ... | @@ -678,16 +657,16 @@ pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool { |
| 678 | 657 | |
| 679 | 658 | pub fn elemType(ty: Type) Type { |
| 680 | 659 | return switch (ty.specifier) { |
| 681 | .pointer, .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => ty.data.sub_type.*, | |
| 682 | .array, .static_array, .incomplete_array, .decayed_array, .decayed_static_array, .decayed_incomplete_array, .vector => ty.data.array.elem, | |
| 683 | .variable_len_array, .decayed_variable_len_array => ty.data.expr.ty, | |
| 684 | .typeof_type, .decayed_typeof_type, .typeof_expr, .decayed_typeof_expr => { | |
| 660 | .pointer, .unspecified_variable_len_array => ty.data.sub_type.*, | |
| 661 | .array, .static_array, .incomplete_array, .vector => ty.data.array.elem, | |
| 662 | .variable_len_array => ty.data.expr.ty, | |
| 663 | .typeof_type, .typeof_expr => { | |
| 685 | 664 | const unwrapped = ty.canonicalize(.preserve_quals); |
| 686 | 665 | var elem = unwrapped.elemType(); |
| 687 | 666 | elem.qual = elem.qual.mergeAll(unwrapped.qual); |
| 688 | 667 | return elem; |
| 689 | 668 | }, |
| 690 | .attributed => ty.data.attributed.base, | |
| 669 | .attributed => ty.data.attributed.base.elemType(), | |
| 691 | 670 | .invalid => Type.invalid, |
| 692 | 671 | // zig fmt: off |
| 693 | 672 | .complex_float, .complex_double, .complex_long_double, .complex_float80, |
| ... | ... | @@ -703,8 +682,8 @@ pub fn elemType(ty: Type) Type { |
| 703 | 682 | pub fn returnType(ty: Type) Type { |
| 704 | 683 | return switch (ty.specifier) { |
| 705 | 684 | .func, .var_args_func, .old_style_func => ty.data.func.return_type, |
| 706 | .typeof_type, .decayed_typeof_type => ty.data.sub_type.returnType(), | |
| 707 | .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.returnType(), | |
| 685 | .typeof_type => ty.data.sub_type.returnType(), | |
| 686 | .typeof_expr => ty.data.expr.ty.returnType(), | |
| 708 | 687 | .attributed => ty.data.attributed.base.returnType(), |
| 709 | 688 | .invalid => Type.invalid, |
| 710 | 689 | else => unreachable, |
| ... | ... | @@ -714,8 +693,8 @@ pub fn returnType(ty: Type) Type { |
| 714 | 693 | pub fn params(ty: Type) []Func.Param { |
| 715 | 694 | return switch (ty.specifier) { |
| 716 | 695 | .func, .var_args_func, .old_style_func => ty.data.func.params, |
| 717 | .typeof_type, .decayed_typeof_type => ty.data.sub_type.params(), | |
| 718 | .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.params(), | |
| 696 | .typeof_type => ty.data.sub_type.params(), | |
| 697 | .typeof_expr => ty.data.expr.ty.params(), | |
| 719 | 698 | .attributed => ty.data.attributed.base.params(), |
| 720 | 699 | .invalid => &.{}, |
| 721 | 700 | else => unreachable, |
| ... | ... | @@ -724,9 +703,9 @@ pub fn params(ty: Type) []Func.Param { |
| 724 | 703 | |
| 725 | 704 | pub fn arrayLen(ty: Type) ?u64 { |
| 726 | 705 | return switch (ty.specifier) { |
| 727 | .array, .static_array, .decayed_array, .decayed_static_array => ty.data.array.len, | |
| 728 | .typeof_type, .decayed_typeof_type => ty.data.sub_type.arrayLen(), | |
| 729 | .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.arrayLen(), | |
| 706 | .array, .static_array => ty.data.array.len, | |
| 707 | .typeof_type => ty.data.sub_type.arrayLen(), | |
| 708 | .typeof_expr => ty.data.expr.ty.arrayLen(), | |
| 730 | 709 | .attributed => ty.data.attributed.base.arrayLen(), |
| 731 | 710 | else => null, |
| 732 | 711 | }; |
| ... | ... | @@ -748,8 +727,8 @@ pub fn anyQual(ty: Type) bool { |
| 748 | 727 | pub fn getAttributes(ty: Type) []const Attribute { |
| 749 | 728 | return switch (ty.specifier) { |
| 750 | 729 | .attributed => ty.data.attributed.attributes, |
| 751 | .typeof_type, .decayed_typeof_type => ty.data.sub_type.getAttributes(), | |
| 752 | .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getAttributes(), | |
| 730 | .typeof_type => ty.data.sub_type.getAttributes(), | |
| 731 | .typeof_expr => ty.data.expr.ty.getAttributes(), | |
| 753 | 732 | else => &.{}, |
| 754 | 733 | }; |
| 755 | 734 | } |
| ... | ... | @@ -757,8 +736,8 @@ pub fn getAttributes(ty: Type) []const Attribute { |
| 757 | 736 | pub fn getRecord(ty: Type) ?*const Type.Record { |
| 758 | 737 | return switch (ty.specifier) { |
| 759 | 738 | .attributed => ty.data.attributed.base.getRecord(), |
| 760 | .typeof_type, .decayed_typeof_type => ty.data.sub_type.getRecord(), | |
| 761 | .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getRecord(), | |
| 739 | .typeof_type => ty.data.sub_type.getRecord(), | |
| 740 | .typeof_expr => ty.data.expr.ty.getRecord(), | |
| 762 | 741 | .@"struct", .@"union" => ty.data.record, |
| 763 | 742 | else => null, |
| 764 | 743 | }; |
| ... | ... | @@ -901,6 +880,7 @@ pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type { |
| 901 | 880 | } |
| 902 | 881 | |
| 903 | 882 | pub fn hasIncompleteSize(ty: Type) bool { |
| 883 | if (ty.isDecayed()) return false; | |
| 904 | 884 | return switch (ty.specifier) { |
| 905 | 885 | .void, .incomplete_array => true, |
| 906 | 886 | .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed, |
| ... | ... | @@ -917,20 +897,14 @@ pub fn hasUnboundVLA(ty: Type) bool { |
| 917 | 897 | var cur = ty; |
| 918 | 898 | while (true) { |
| 919 | 899 | switch (cur.specifier) { |
| 920 | .unspecified_variable_len_array, | |
| 921 | .decayed_unspecified_variable_len_array, | |
| 922 | => return true, | |
| 900 | .unspecified_variable_len_array => return true, | |
| 923 | 901 | .array, |
| 924 | 902 | .static_array, |
| 925 | 903 | .incomplete_array, |
| 926 | 904 | .variable_len_array, |
| 927 | .decayed_array, | |
| 928 | .decayed_static_array, | |
| 929 | .decayed_incomplete_array, | |
| 930 | .decayed_variable_len_array, | |
| 931 | 905 | => cur = cur.elemType(), |
| 932 | .typeof_type, .decayed_typeof_type => cur = cur.data.sub_type.*, | |
| 933 | .typeof_expr, .decayed_typeof_expr => cur = cur.data.expr.ty, | |
| 906 | .typeof_type => cur = cur.data.sub_type.*, | |
| 907 | .typeof_expr => cur = cur.data.expr.ty, | |
| 934 | 908 | .attributed => cur = cur.data.attributed.base, |
| 935 | 909 | else => return false, |
| 936 | 910 | } |
| ... | ... | @@ -1006,9 +980,11 @@ pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder { |
| 1006 | 980 | |
| 1007 | 981 | /// Size of type as reported by sizeof |
| 1008 | 982 | pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 { |
| 983 | if (ty.isPtr()) return comp.target.ptrBitWidth() / 8; | |
| 984 | ||
| 1009 | 985 | return switch (ty.specifier) { |
| 1010 | 986 | .auto_type, .c23_auto => unreachable, |
| 1011 | .variable_len_array, .unspecified_variable_len_array => return null, | |
| 987 | .variable_len_array, .unspecified_variable_len_array => null, | |
| 1012 | 988 | .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null, |
| 1013 | 989 | .func, .var_args_func, .old_style_func, .void, .bool => 1, |
| 1014 | 990 | .char, .schar, .uchar => 1, |
| ... | ... | @@ -1037,14 +1013,7 @@ pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 { |
| 1037 | 1013 | .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int, |
| 1038 | 1014 | => return 2 * ty.makeReal().sizeof(comp).?, |
| 1039 | 1015 | // zig fmt: on |
| 1040 | .pointer, | |
| 1041 | .decayed_array, | |
| 1042 | .decayed_static_array, | |
| 1043 | .decayed_incomplete_array, | |
| 1044 | .decayed_variable_len_array, | |
| 1045 | .decayed_unspecified_variable_len_array, | |
| 1046 | .decayed_typeof_type, | |
| 1047 | .decayed_typeof_expr, | |
| 1016 | .pointer => unreachable, | |
| 1048 | 1017 | .static_array, |
| 1049 | 1018 | .nullptr_t, |
| 1050 | 1019 | => comp.target.ptrBitWidth() / 8, |
| ... | ... | @@ -1073,8 +1042,8 @@ pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 { |
| 1073 | 1042 | pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 { |
| 1074 | 1043 | return switch (ty.specifier) { |
| 1075 | 1044 | .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1, |
| 1076 | .typeof_type, .decayed_typeof_type => ty.data.sub_type.bitSizeof(comp), | |
| 1077 | .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.bitSizeof(comp), | |
| 1045 | .typeof_type => ty.data.sub_type.bitSizeof(comp), | |
| 1046 | .typeof_expr => ty.data.expr.ty.bitSizeof(comp), | |
| 1078 | 1047 | .attributed => ty.data.attributed.base.bitSizeof(comp), |
| 1079 | 1048 | .bit_int => return ty.data.int.bits, |
| 1080 | 1049 | .long_double => comp.target.c_type_bit_size(.longdouble), |
| ... | ... | @@ -1117,7 +1086,10 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 { |
| 1117 | 1086 | .unspecified_variable_len_array, |
| 1118 | 1087 | .array, |
| 1119 | 1088 | .vector, |
| 1120 | => ty.elemType().alignof(comp), | |
| 1089 | => if (ty.isPtr()) switch (comp.target.cpu.arch) { | |
| 1090 | .avr => 1, | |
| 1091 | else => comp.target.ptrBitWidth() / 8, | |
| 1092 | } else ty.elemType().alignof(comp), | |
| 1121 | 1093 | .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target), |
| 1122 | 1094 | .char, .schar, .uchar, .void, .bool => 1, |
| 1123 | 1095 | |
| ... | ... | @@ -1153,11 +1125,6 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 { |
| 1153 | 1125 | |
| 1154 | 1126 | .float80, .float128 => 16, |
| 1155 | 1127 | .pointer, |
| 1156 | .decayed_array, | |
| 1157 | .decayed_static_array, | |
| 1158 | .decayed_incomplete_array, | |
| 1159 | .decayed_variable_len_array, | |
| 1160 | .decayed_unspecified_variable_len_array, | |
| 1161 | 1128 | .static_array, |
| 1162 | 1129 | .nullptr_t, |
| 1163 | 1130 | => switch (comp.target.cpu.arch) { |
| ... | ... | @@ -1166,8 +1133,8 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 { |
| 1166 | 1133 | }, |
| 1167 | 1134 | .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8), |
| 1168 | 1135 | .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp), |
| 1169 | .typeof_type, .decayed_typeof_type => ty.data.sub_type.alignof(comp), | |
| 1170 | .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.alignof(comp), | |
| 1136 | .typeof_type => ty.data.sub_type.alignof(comp), | |
| 1137 | .typeof_expr => ty.data.expr.ty.alignof(comp), | |
| 1171 | 1138 | .attributed => ty.data.attributed.base.alignof(comp), |
| 1172 | 1139 | }; |
| 1173 | 1140 | } |
| ... | ... | @@ -1179,7 +1146,10 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 { |
| 1179 | 1146 | /// arrays and pointers. |
| 1180 | 1147 | pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type { |
| 1181 | 1148 | var cur = ty; |
| 1182 | if (cur.specifier == .attributed) cur = cur.data.attributed.base; | |
| 1149 | if (cur.specifier == .attributed) { | |
| 1150 | cur = cur.data.attributed.base; | |
| 1151 | cur.decayed = ty.decayed; | |
| 1152 | } | |
| 1183 | 1153 | if (!cur.isTypeof()) return cur; |
| 1184 | 1154 | |
| 1185 | 1155 | var qual = cur.qual; |
| ... | ... | @@ -1187,14 +1157,6 @@ pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) |
| 1187 | 1157 | switch (cur.specifier) { |
| 1188 | 1158 | .typeof_type => cur = cur.data.sub_type.*, |
| 1189 | 1159 | .typeof_expr => cur = cur.data.expr.ty, |
| 1190 | .decayed_typeof_type => { | |
| 1191 | cur = cur.data.sub_type.*; | |
| 1192 | cur.decayArray(); | |
| 1193 | }, | |
| 1194 | .decayed_typeof_expr => { | |
| 1195 | cur = cur.data.expr.ty; | |
| 1196 | cur.decayArray(); | |
| 1197 | }, | |
| 1198 | 1160 | else => break, |
| 1199 | 1161 | } |
| 1200 | 1162 | qual = qual.mergeAll(cur.qual); |
| ... | ... | @@ -1204,6 +1166,7 @@ pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) |
| 1204 | 1166 | } else { |
| 1205 | 1167 | cur.qual = qual; |
| 1206 | 1168 | } |
| 1169 | cur.decayed = ty.decayed; | |
| 1207 | 1170 | return cur; |
| 1208 | 1171 | } |
| 1209 | 1172 | |
| ... | ... | @@ -1219,8 +1182,8 @@ pub fn get(ty: *const Type, specifier: Specifier) ?*const Type { |
| 1219 | 1182 | |
| 1220 | 1183 | pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 { |
| 1221 | 1184 | return switch (ty.specifier) { |
| 1222 | .typeof_type, .decayed_typeof_type => ty.data.sub_type.requestedAlignment(comp), | |
| 1223 | .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.requestedAlignment(comp), | |
| 1185 | .typeof_type => ty.data.sub_type.requestedAlignment(comp), | |
| 1186 | .typeof_expr => ty.data.expr.ty.requestedAlignment(comp), | |
| 1224 | 1187 | .attributed => annotationAlignment(comp, ty.data.attributed.attributes), |
| 1225 | 1188 | else => null, |
| 1226 | 1189 | }; |
| ... | ... | @@ -1265,14 +1228,11 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi |
| 1265 | 1228 | if (a.qual.@"volatile" != b.qual.@"volatile") return false; |
| 1266 | 1229 | } |
| 1267 | 1230 | |
| 1231 | if (a.isPtr()) { | |
| 1232 | return a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers); | |
| 1233 | } | |
| 1268 | 1234 | switch (a.specifier) { |
| 1269 | .pointer, | |
| 1270 | .decayed_array, | |
| 1271 | .decayed_static_array, | |
| 1272 | .decayed_incomplete_array, | |
| 1273 | .decayed_variable_len_array, | |
| 1274 | .decayed_unspecified_variable_len_array, | |
| 1275 | => if (!a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers)) return false, | |
| 1235 | .pointer => unreachable, | |
| 1276 | 1236 | |
| 1277 | 1237 | .func, |
| 1278 | 1238 | .var_args_func, |
| ... | ... | @@ -1293,8 +1253,9 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi |
| 1293 | 1253 | } |
| 1294 | 1254 | if (!a.elemType().eql(b.elemType(), comp, false)) return false; |
| 1295 | 1255 | }, |
| 1296 | .variable_len_array => if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false, | |
| 1297 | ||
| 1256 | .variable_len_array => { | |
| 1257 | if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false; | |
| 1258 | }, | |
| 1298 | 1259 | .@"struct", .@"union" => if (a.data.record != b.data.record) return false, |
| 1299 | 1260 | .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false, |
| 1300 | 1261 | .bit_int, .complex_bit_int => return a.data.int.bits == b.data.int.bits and a.data.int.signedness == b.data.int.signedness, |
| ... | ... | @@ -1306,14 +1267,14 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi |
| 1306 | 1267 | |
| 1307 | 1268 | /// Decays an array to a pointer |
| 1308 | 1269 | pub fn decayArray(ty: *Type) void { |
| 1309 | // the decayed array type is the current specifier +1 | |
| 1310 | ty.specifier = @enumFromInt(@intFromEnum(ty.specifier) + 1); | |
| 1270 | std.debug.assert(ty.isArray()); | |
| 1271 | ty.decayed = true; | |
| 1311 | 1272 | } |
| 1312 | 1273 | |
| 1313 | 1274 | pub fn originalTypeOfDecayedArray(ty: Type) Type { |
| 1314 | 1275 | std.debug.assert(ty.isDecayed()); |
| 1315 | 1276 | var copy = ty; |
| 1316 | copy.specifier = @enumFromInt(@intFromEnum(ty.specifier) - 1); | |
| 1277 | copy.decayed = false; | |
| 1317 | 1278 | return copy; |
| 1318 | 1279 | } |
| 1319 | 1280 | |
| ... | ... | @@ -1405,25 +1366,23 @@ pub fn combine(inner: *Type, outer: Type) Parser.Error!void { |
| 1405 | 1366 | switch (inner.specifier) { |
| 1406 | 1367 | .pointer => return inner.data.sub_type.combine(outer), |
| 1407 | 1368 | .unspecified_variable_len_array => { |
| 1369 | std.debug.assert(!inner.isDecayed()); | |
| 1408 | 1370 | try inner.data.sub_type.combine(outer); |
| 1409 | 1371 | }, |
| 1410 | 1372 | .variable_len_array => { |
| 1373 | std.debug.assert(!inner.isDecayed()); | |
| 1411 | 1374 | try inner.data.expr.ty.combine(outer); |
| 1412 | 1375 | }, |
| 1413 | 1376 | .array, .static_array, .incomplete_array => { |
| 1377 | std.debug.assert(!inner.isDecayed()); | |
| 1414 | 1378 | try inner.data.array.elem.combine(outer); |
| 1415 | 1379 | }, |
| 1416 | 1380 | .func, .var_args_func, .old_style_func => { |
| 1417 | 1381 | try inner.data.func.return_type.combine(outer); |
| 1418 | 1382 | }, |
| 1419 | .decayed_array, | |
| 1420 | .decayed_static_array, | |
| 1421 | .decayed_incomplete_array, | |
| 1422 | .decayed_variable_len_array, | |
| 1423 | .decayed_unspecified_variable_len_array, | |
| 1424 | .decayed_typeof_type, | |
| 1425 | .decayed_typeof_expr, | |
| 1426 | => unreachable, // type should not be able to decay before being combined | |
| 1383 | .typeof_type, | |
| 1384 | .typeof_expr, | |
| 1385 | => std.debug.assert(!inner.isDecayed()), | |
| 1427 | 1386 | .void, .invalid => inner.* = outer, |
| 1428 | 1387 | else => unreachable, |
| 1429 | 1388 | } |
| ... | ... | @@ -1474,8 +1433,8 @@ pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser |
| 1474 | 1433 | try p.errStr(.suggest_pointer_for_invalid_fp16, source_tok, "function return value"); |
| 1475 | 1434 | } |
| 1476 | 1435 | }, |
| 1477 | .typeof_type, .decayed_typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok), | |
| 1478 | .typeof_expr, .decayed_typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok), | |
| 1436 | .typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok), | |
| 1437 | .typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok), | |
| 1479 | 1438 | .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok), |
| 1480 | 1439 | else => {}, |
| 1481 | 1440 | } |
| ... | ... | @@ -1610,6 +1569,7 @@ pub const Builder = struct { |
| 1610 | 1569 | decayed_typeof_expr: *Expr, |
| 1611 | 1570 | |
| 1612 | 1571 | attributed: *Attributed, |
| 1572 | decayed_attributed: *Attributed, | |
| 1613 | 1573 | |
| 1614 | 1574 | pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 { |
| 1615 | 1575 | return switch (spec) { |
| ... | ... | @@ -1835,13 +1795,10 @@ pub const Builder = struct { |
| 1835 | 1795 | ty.specifier = .pointer; |
| 1836 | 1796 | ty.data = .{ .sub_type = data }; |
| 1837 | 1797 | }, |
| 1838 | .unspecified_variable_len_array => |data| { | |
| 1798 | .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => |data| { | |
| 1839 | 1799 | ty.specifier = .unspecified_variable_len_array; |
| 1840 | 1800 | ty.data = .{ .sub_type = data }; |
| 1841 | }, | |
| 1842 | .decayed_unspecified_variable_len_array => |data| { | |
| 1843 | ty.specifier = .decayed_unspecified_variable_len_array; | |
| 1844 | ty.data = .{ .sub_type = data }; | |
| 1801 | ty.decayed = b.specifier == .decayed_unspecified_variable_len_array; | |
| 1845 | 1802 | }, |
| 1846 | 1803 | .func => |data| { |
| 1847 | 1804 | ty.specifier = .func; |
| ... | ... | @@ -1855,41 +1812,29 @@ pub const Builder = struct { |
| 1855 | 1812 | ty.specifier = .old_style_func; |
| 1856 | 1813 | ty.data = .{ .func = data }; |
| 1857 | 1814 | }, |
| 1858 | .array => |data| { | |
| 1815 | .array, .decayed_array => |data| { | |
| 1859 | 1816 | ty.specifier = .array; |
| 1860 | 1817 | ty.data = .{ .array = data }; |
| 1818 | ty.decayed = b.specifier == .decayed_array; | |
| 1861 | 1819 | }, |
| 1862 | .decayed_array => |data| { | |
| 1863 | ty.specifier = .decayed_array; | |
| 1864 | ty.data = .{ .array = data }; | |
| 1865 | }, | |
| 1866 | .static_array => |data| { | |
| 1820 | .static_array, .decayed_static_array => |data| { | |
| 1867 | 1821 | ty.specifier = .static_array; |
| 1868 | 1822 | ty.data = .{ .array = data }; |
| 1823 | ty.decayed = b.specifier == .decayed_static_array; | |
| 1869 | 1824 | }, |
| 1870 | .decayed_static_array => |data| { | |
| 1871 | ty.specifier = .decayed_static_array; | |
| 1872 | ty.data = .{ .array = data }; | |
| 1873 | }, | |
| 1874 | .incomplete_array => |data| { | |
| 1825 | .incomplete_array, .decayed_incomplete_array => |data| { | |
| 1875 | 1826 | ty.specifier = .incomplete_array; |
| 1876 | 1827 | ty.data = .{ .array = data }; |
| 1877 | }, | |
| 1878 | .decayed_incomplete_array => |data| { | |
| 1879 | ty.specifier = .decayed_incomplete_array; | |
| 1880 | ty.data = .{ .array = data }; | |
| 1828 | ty.decayed = b.specifier == .decayed_incomplete_array; | |
| 1881 | 1829 | }, |
| 1882 | 1830 | .vector => |data| { |
| 1883 | 1831 | ty.specifier = .vector; |
| 1884 | 1832 | ty.data = .{ .array = data }; |
| 1885 | 1833 | }, |
| 1886 | .variable_len_array => |data| { | |
| 1834 | .variable_len_array, .decayed_variable_len_array => |data| { | |
| 1887 | 1835 | ty.specifier = .variable_len_array; |
| 1888 | 1836 | ty.data = .{ .expr = data }; |
| 1889 | }, | |
| 1890 | .decayed_variable_len_array => |data| { | |
| 1891 | ty.specifier = .decayed_variable_len_array; | |
| 1892 | ty.data = .{ .expr = data }; | |
| 1837 | ty.decayed = b.specifier == .decayed_variable_len_array; | |
| 1893 | 1838 | }, |
| 1894 | 1839 | .@"struct" => |data| { |
| 1895 | 1840 | ty.specifier = .@"struct"; |
| ... | ... | @@ -1903,25 +1848,20 @@ pub const Builder = struct { |
| 1903 | 1848 | ty.specifier = .@"enum"; |
| 1904 | 1849 | ty.data = .{ .@"enum" = data }; |
| 1905 | 1850 | }, |
| 1906 | .typeof_type => |data| { | |
| 1851 | .typeof_type, .decayed_typeof_type => |data| { | |
| 1907 | 1852 | ty.specifier = .typeof_type; |
| 1908 | 1853 | ty.data = .{ .sub_type = data }; |
| 1854 | ty.decayed = b.specifier == .decayed_typeof_type; | |
| 1909 | 1855 | }, |
| 1910 | .decayed_typeof_type => |data| { | |
| 1911 | ty.specifier = .decayed_typeof_type; | |
| 1912 | ty.data = .{ .sub_type = data }; | |
| 1913 | }, | |
| 1914 | .typeof_expr => |data| { | |
| 1856 | .typeof_expr, .decayed_typeof_expr => |data| { | |
| 1915 | 1857 | ty.specifier = .typeof_expr; |
| 1916 | 1858 | ty.data = .{ .expr = data }; |
| 1859 | ty.decayed = b.specifier == .decayed_typeof_expr; | |
| 1917 | 1860 | }, |
| 1918 | .decayed_typeof_expr => |data| { | |
| 1919 | ty.specifier = .decayed_typeof_expr; | |
| 1920 | ty.data = .{ .expr = data }; | |
| 1921 | }, | |
| 1922 | .attributed => |data| { | |
| 1861 | .attributed, .decayed_attributed => |data| { | |
| 1923 | 1862 | ty.specifier = .attributed; |
| 1924 | 1863 | ty.data = .{ .attributed = data }; |
| 1864 | ty.decayed = b.specifier == .decayed_attributed; | |
| 1925 | 1865 | }, |
| 1926 | 1866 | } |
| 1927 | 1867 | if (!ty.isReal() and ty.isInt()) { |
| ... | ... | @@ -2359,30 +2299,47 @@ pub const Builder = struct { |
| 2359 | 2299 | .complex_float128 => .complex_float128, |
| 2360 | 2300 | |
| 2361 | 2301 | .pointer => .{ .pointer = ty.data.sub_type }, |
| 2362 | .unspecified_variable_len_array => .{ .unspecified_variable_len_array = ty.data.sub_type }, | |
| 2363 | .decayed_unspecified_variable_len_array => .{ .decayed_unspecified_variable_len_array = ty.data.sub_type }, | |
| 2302 | .unspecified_variable_len_array => if (ty.isDecayed()) | |
| 2303 | .{ .decayed_unspecified_variable_len_array = ty.data.sub_type } | |
| 2304 | else | |
| 2305 | .{ .unspecified_variable_len_array = ty.data.sub_type }, | |
| 2364 | 2306 | .func => .{ .func = ty.data.func }, |
| 2365 | 2307 | .var_args_func => .{ .var_args_func = ty.data.func }, |
| 2366 | 2308 | .old_style_func => .{ .old_style_func = ty.data.func }, |
| 2367 | .array => .{ .array = ty.data.array }, | |
| 2368 | .decayed_array => .{ .decayed_array = ty.data.array }, | |
| 2369 | .static_array => .{ .static_array = ty.data.array }, | |
| 2370 | .decayed_static_array => .{ .decayed_static_array = ty.data.array }, | |
| 2371 | .incomplete_array => .{ .incomplete_array = ty.data.array }, | |
| 2372 | .decayed_incomplete_array => .{ .decayed_incomplete_array = ty.data.array }, | |
| 2309 | .array => if (ty.isDecayed()) | |
| 2310 | .{ .decayed_array = ty.data.array } | |
| 2311 | else | |
| 2312 | .{ .array = ty.data.array }, | |
| 2313 | .static_array => if (ty.isDecayed()) | |
| 2314 | .{ .decayed_static_array = ty.data.array } | |
| 2315 | else | |
| 2316 | .{ .static_array = ty.data.array }, | |
| 2317 | .incomplete_array => if (ty.isDecayed()) | |
| 2318 | .{ .decayed_incomplete_array = ty.data.array } | |
| 2319 | else | |
| 2320 | .{ .incomplete_array = ty.data.array }, | |
| 2373 | 2321 | .vector => .{ .vector = ty.data.array }, |
| 2374 | .variable_len_array => .{ .variable_len_array = ty.data.expr }, | |
| 2375 | .decayed_variable_len_array => .{ .decayed_variable_len_array = ty.data.expr }, | |
| 2322 | .variable_len_array => if (ty.isDecayed()) | |
| 2323 | .{ .decayed_variable_len_array = ty.data.expr } | |
| 2324 | else | |
| 2325 | .{ .variable_len_array = ty.data.expr }, | |
| 2376 | 2326 | .@"struct" => .{ .@"struct" = ty.data.record }, |
| 2377 | 2327 | .@"union" => .{ .@"union" = ty.data.record }, |
| 2378 | 2328 | .@"enum" => .{ .@"enum" = ty.data.@"enum" }, |
| 2379 | 2329 | |
| 2380 | .typeof_type => .{ .typeof_type = ty.data.sub_type }, | |
| 2381 | .decayed_typeof_type => .{ .decayed_typeof_type = ty.data.sub_type }, | |
| 2382 | .typeof_expr => .{ .typeof_expr = ty.data.expr }, | |
| 2383 | .decayed_typeof_expr => .{ .decayed_typeof_expr = ty.data.expr }, | |
| 2330 | .typeof_type => if (ty.isDecayed()) | |
| 2331 | .{ .decayed_typeof_type = ty.data.sub_type } | |
| 2332 | else | |
| 2333 | .{ .typeof_type = ty.data.sub_type }, | |
| 2334 | .typeof_expr => if (ty.isDecayed()) | |
| 2335 | .{ .decayed_typeof_expr = ty.data.expr } | |
| 2336 | else | |
| 2337 | .{ .typeof_expr = ty.data.expr }, | |
| 2384 | 2338 | |
| 2385 | .attributed => .{ .attributed = ty.data.attributed }, | |
| 2339 | .attributed => if (ty.isDecayed()) | |
| 2340 | .{ .decayed_attributed = ty.data.attributed } | |
| 2341 | else | |
| 2342 | .{ .attributed = ty.data.attributed }, | |
| 2386 | 2343 | else => unreachable, |
| 2387 | 2344 | }; |
| 2388 | 2345 | } |
| ... | ... | @@ -2472,24 +2429,17 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts |
| 2472 | 2429 | try w.writeAll(")"); |
| 2473 | 2430 | return true; |
| 2474 | 2431 | } |
| 2432 | if (ty.isPtr()) { | |
| 2433 | const elem_ty = ty.elemType(); | |
| 2434 | const simple = try elem_ty.printPrologue(mapper, langopts, w); | |
| 2435 | if (simple) try w.writeByte(' '); | |
| 2436 | if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte('('); | |
| 2437 | try w.writeByte('*'); | |
| 2438 | try ty.qual.dump(w); | |
| 2439 | return false; | |
| 2440 | } | |
| 2475 | 2441 | switch (ty.specifier) { |
| 2476 | .pointer, | |
| 2477 | .decayed_array, | |
| 2478 | .decayed_static_array, | |
| 2479 | .decayed_incomplete_array, | |
| 2480 | .decayed_variable_len_array, | |
| 2481 | .decayed_unspecified_variable_len_array, | |
| 2482 | .decayed_typeof_type, | |
| 2483 | .decayed_typeof_expr, | |
| 2484 | => { | |
| 2485 | const elem_ty = ty.elemType(); | |
| 2486 | const simple = try elem_ty.printPrologue(mapper, langopts, w); | |
| 2487 | if (simple) try w.writeByte(' '); | |
| 2488 | if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte('('); | |
| 2489 | try w.writeByte('*'); | |
| 2490 | try ty.qual.dump(w); | |
| 2491 | return false; | |
| 2492 | }, | |
| 2442 | .pointer => unreachable, | |
| 2493 | 2443 | .func, .var_args_func, .old_style_func => { |
| 2494 | 2444 | const ret_ty = ty.data.func.return_type; |
| 2495 | 2445 | const simple = try ret_ty.printPrologue(mapper, langopts, w); |
| ... | ... | @@ -2541,20 +2491,14 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts |
| 2541 | 2491 | |
| 2542 | 2492 | fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void { |
| 2543 | 2493 | if (ty.qual.atomic) return; |
| 2494 | if (ty.isPtr()) { | |
| 2495 | const elem_ty = ty.elemType(); | |
| 2496 | if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte(')'); | |
| 2497 | try elem_ty.printEpilogue(mapper, langopts, w); | |
| 2498 | return; | |
| 2499 | } | |
| 2544 | 2500 | switch (ty.specifier) { |
| 2545 | .pointer, | |
| 2546 | .decayed_array, | |
| 2547 | .decayed_static_array, | |
| 2548 | .decayed_incomplete_array, | |
| 2549 | .decayed_variable_len_array, | |
| 2550 | .decayed_unspecified_variable_len_array, | |
| 2551 | .decayed_typeof_type, | |
| 2552 | .decayed_typeof_expr, | |
| 2553 | => { | |
| 2554 | const elem_ty = ty.elemType(); | |
| 2555 | if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte(')'); | |
| 2556 | try elem_ty.printEpilogue(mapper, langopts, w); | |
| 2557 | }, | |
| 2501 | .pointer => unreachable, // handled above | |
| 2558 | 2502 | .func, .var_args_func, .old_style_func => { |
| 2559 | 2503 | try w.writeByte('('); |
| 2560 | 2504 | for (ty.data.func.params, 0..) |param, i| { |
| ... | ... | @@ -2637,10 +2581,10 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: |
| 2637 | 2581 | try w.writeAll(") "); |
| 2638 | 2582 | try ty.data.func.return_type.dump(mapper, langopts, w); |
| 2639 | 2583 | }, |
| 2640 | .array, .static_array, .decayed_array, .decayed_static_array => { | |
| 2641 | if (ty.specifier == .decayed_array or ty.specifier == .decayed_static_array) try w.writeAll("*d"); | |
| 2584 | .array, .static_array => { | |
| 2585 | if (ty.isDecayed()) try w.writeAll("*d"); | |
| 2642 | 2586 | try w.writeByte('['); |
| 2643 | if (ty.specifier == .static_array or ty.specifier == .decayed_static_array) try w.writeAll("static "); | |
| 2587 | if (ty.specifier == .static_array) try w.writeAll("static "); | |
| 2644 | 2588 | try w.print("{d}]", .{ty.data.array.len}); |
| 2645 | 2589 | try ty.data.array.elem.dump(mapper, langopts, w); |
| 2646 | 2590 | }, |
| ... | ... | @@ -2649,8 +2593,8 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: |
| 2649 | 2593 | try ty.data.array.elem.dump(mapper, langopts, w); |
| 2650 | 2594 | try w.writeAll(")"); |
| 2651 | 2595 | }, |
| 2652 | .incomplete_array, .decayed_incomplete_array => { | |
| 2653 | if (ty.specifier == .decayed_incomplete_array) try w.writeAll("*d"); | |
| 2596 | .incomplete_array => { | |
| 2597 | if (ty.isDecayed()) try w.writeAll("*d"); | |
| 2654 | 2598 | try w.writeAll("[]"); |
| 2655 | 2599 | try ty.data.array.elem.dump(mapper, langopts, w); |
| 2656 | 2600 | }, |
| ... | ... | @@ -2672,27 +2616,28 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: |
| 2672 | 2616 | try w.print("union {s}", .{mapper.lookup(ty.data.record.name)}); |
| 2673 | 2617 | if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w); |
| 2674 | 2618 | }, |
| 2675 | .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => { | |
| 2676 | if (ty.specifier == .decayed_unspecified_variable_len_array) try w.writeAll("*d"); | |
| 2619 | .unspecified_variable_len_array => { | |
| 2620 | if (ty.isDecayed()) try w.writeAll("*d"); | |
| 2677 | 2621 | try w.writeAll("[*]"); |
| 2678 | 2622 | try ty.data.sub_type.dump(mapper, langopts, w); |
| 2679 | 2623 | }, |
| 2680 | .variable_len_array, .decayed_variable_len_array => { | |
| 2681 | if (ty.specifier == .decayed_variable_len_array) try w.writeAll("*d"); | |
| 2624 | .variable_len_array => { | |
| 2625 | if (ty.isDecayed()) try w.writeAll("*d"); | |
| 2682 | 2626 | try w.writeAll("[<expr>]"); |
| 2683 | 2627 | try ty.data.expr.ty.dump(mapper, langopts, w); |
| 2684 | 2628 | }, |
| 2685 | .typeof_type, .decayed_typeof_type => { | |
| 2629 | .typeof_type => { | |
| 2686 | 2630 | try w.writeAll("typeof("); |
| 2687 | 2631 | try ty.data.sub_type.dump(mapper, langopts, w); |
| 2688 | 2632 | try w.writeAll(")"); |
| 2689 | 2633 | }, |
| 2690 | .typeof_expr, .decayed_typeof_expr => { | |
| 2634 | .typeof_expr => { | |
| 2691 | 2635 | try w.writeAll("typeof(<expr>: "); |
| 2692 | 2636 | try ty.data.expr.ty.dump(mapper, langopts, w); |
| 2693 | 2637 | try w.writeAll(")"); |
| 2694 | 2638 | }, |
| 2695 | 2639 | .attributed => { |
| 2640 | if (ty.isDecayed()) try w.writeAll("*d:"); | |
| 2696 | 2641 | try w.writeAll("attributed("); |
| 2697 | 2642 | try ty.data.attributed.base.dump(mapper, langopts, w); |
| 2698 | 2643 | try w.writeAll(")"); |
deps/aro/aro/Value.zig+1-1| ... | ... | @@ -215,7 +215,7 @@ pub fn intCast(v: *Value, dest_ty: Type, comp: *Compilation) !void { |
| 215 | 215 | |
| 216 | 216 | const limbs = try comp.gpa.alloc( |
| 217 | 217 | std.math.big.Limb, |
| 218 | std.math.big.int.calcTwosCompLimbCount(bits), | |
| 218 | std.math.big.int.calcTwosCompLimbCount(@max(big.bitCountTwosComp(), bits)), | |
| 219 | 219 | ); |
| 220 | 220 | defer comp.gpa.free(limbs); |
| 221 | 221 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
deps/aro/aro/number_affixes.zig deleted-169| ... | ... | @@ -1,169 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const mem = std.mem; | |
| 3 | ||
| 4 | pub const Prefix = enum(u8) { | |
| 5 | binary = 2, | |
| 6 | octal = 8, | |
| 7 | decimal = 10, | |
| 8 | hex = 16, | |
| 9 | ||
| 10 | pub fn digitAllowed(prefix: Prefix, c: u8) bool { | |
| 11 | return switch (c) { | |
| 12 | '0', '1' => true, | |
| 13 | '2'...'7' => prefix != .binary, | |
| 14 | '8'...'9' => prefix == .decimal or prefix == .hex, | |
| 15 | 'a'...'f', 'A'...'F' => prefix == .hex, | |
| 16 | else => false, | |
| 17 | }; | |
| 18 | } | |
| 19 | ||
| 20 | pub fn fromString(buf: []const u8) Prefix { | |
| 21 | if (buf.len == 1) return .decimal; | |
| 22 | // tokenizer enforces that first byte is a decimal digit or period | |
| 23 | switch (buf[0]) { | |
| 24 | '.', '1'...'9' => return .decimal, | |
| 25 | '0' => {}, | |
| 26 | else => unreachable, | |
| 27 | } | |
| 28 | switch (buf[1]) { | |
| 29 | 'x', 'X' => return if (buf.len == 2) .decimal else .hex, | |
| 30 | 'b', 'B' => return if (buf.len == 2) .decimal else .binary, | |
| 31 | else => { | |
| 32 | if (mem.indexOfAny(u8, buf, "eE.")) |_| { | |
| 33 | // This is a decimal floating point number that happens to start with zero | |
| 34 | return .decimal; | |
| 35 | } else if (Suffix.fromString(buf[1..], .int)) |_| { | |
| 36 | // This is `0` with a valid suffix | |
| 37 | return .decimal; | |
| 38 | } else { | |
| 39 | return .octal; | |
| 40 | } | |
| 41 | }, | |
| 42 | } | |
| 43 | } | |
| 44 | ||
| 45 | /// Length of this prefix as a string | |
| 46 | pub fn stringLen(prefix: Prefix) usize { | |
| 47 | return switch (prefix) { | |
| 48 | .binary => 2, | |
| 49 | .octal => 1, | |
| 50 | .decimal => 0, | |
| 51 | .hex => 2, | |
| 52 | }; | |
| 53 | } | |
| 54 | }; | |
| 55 | ||
| 56 | pub const Suffix = enum { | |
| 57 | // zig fmt: off | |
| 58 | ||
| 59 | // int and imaginary int | |
| 60 | None, I, | |
| 61 | ||
| 62 | // unsigned real integers | |
| 63 | U, UL, ULL, | |
| 64 | ||
| 65 | // unsigned imaginary integers | |
| 66 | IU, IUL, IULL, | |
| 67 | ||
| 68 | // long or long double, real and imaginary | |
| 69 | L, IL, | |
| 70 | ||
| 71 | // long long and imaginary long long | |
| 72 | LL, ILL, | |
| 73 | ||
| 74 | // float and imaginary float | |
| 75 | F, IF, | |
| 76 | ||
| 77 | // _Float16 | |
| 78 | F16, | |
| 79 | ||
| 80 | // Imaginary _Bitint | |
| 81 | IWB, IUWB, | |
| 82 | ||
| 83 | // _Bitint | |
| 84 | WB, UWB, | |
| 85 | ||
| 86 | // zig fmt: on | |
| 87 | ||
| 88 | const Tuple = struct { Suffix, []const []const u8 }; | |
| 89 | ||
| 90 | const IntSuffixes = &[_]Tuple{ | |
| 91 | .{ .U, &.{"U"} }, | |
| 92 | .{ .L, &.{"L"} }, | |
| 93 | .{ .WB, &.{"WB"} }, | |
| 94 | .{ .UL, &.{ "U", "L" } }, | |
| 95 | .{ .UWB, &.{ "U", "WB" } }, | |
| 96 | .{ .LL, &.{"LL"} }, | |
| 97 | .{ .ULL, &.{ "U", "LL" } }, | |
| 98 | ||
| 99 | .{ .I, &.{"I"} }, | |
| 100 | ||
| 101 | .{ .IWB, &.{ "I", "WB" } }, | |
| 102 | .{ .IU, &.{ "I", "U" } }, | |
| 103 | .{ .IL, &.{ "I", "L" } }, | |
| 104 | .{ .IUL, &.{ "I", "U", "L" } }, | |
| 105 | .{ .IUWB, &.{ "I", "U", "WB" } }, | |
| 106 | .{ .ILL, &.{ "I", "LL" } }, | |
| 107 | .{ .IULL, &.{ "I", "U", "LL" } }, | |
| 108 | }; | |
| 109 | ||
| 110 | const FloatSuffixes = &[_]Tuple{ | |
| 111 | .{ .F16, &.{"F16"} }, | |
| 112 | .{ .F, &.{"F"} }, | |
| 113 | .{ .L, &.{"L"} }, | |
| 114 | ||
| 115 | .{ .I, &.{"I"} }, | |
| 116 | .{ .IL, &.{ "I", "L" } }, | |
| 117 | .{ .IF, &.{ "I", "F" } }, | |
| 118 | }; | |
| 119 | ||
| 120 | pub fn fromString(buf: []const u8, suffix_kind: enum { int, float }) ?Suffix { | |
| 121 | if (buf.len == 0) return .None; | |
| 122 | ||
| 123 | const suffixes = switch (suffix_kind) { | |
| 124 | .float => FloatSuffixes, | |
| 125 | .int => IntSuffixes, | |
| 126 | }; | |
| 127 | var scratch: [3]u8 = undefined; | |
| 128 | top: for (suffixes) |candidate| { | |
| 129 | const tag = candidate[0]; | |
| 130 | const parts = candidate[1]; | |
| 131 | var len: usize = 0; | |
| 132 | for (parts) |part| len += part.len; | |
| 133 | if (len != buf.len) continue; | |
| 134 | ||
| 135 | for (parts) |part| { | |
| 136 | const lower = std.ascii.lowerString(&scratch, part); | |
| 137 | if (mem.indexOf(u8, buf, part) == null and mem.indexOf(u8, buf, lower) == null) continue :top; | |
| 138 | } | |
| 139 | return tag; | |
| 140 | } | |
| 141 | return null; | |
| 142 | } | |
| 143 | ||
| 144 | pub fn isImaginary(suffix: Suffix) bool { | |
| 145 | return switch (suffix) { | |
| 146 | .I, .IL, .IF, .IU, .IUL, .ILL, .IULL, .IWB, .IUWB => true, | |
| 147 | .None, .L, .F16, .F, .U, .UL, .LL, .ULL, .WB, .UWB => false, | |
| 148 | }; | |
| 149 | } | |
| 150 | ||
| 151 | pub fn isSignedInteger(suffix: Suffix) bool { | |
| 152 | return switch (suffix) { | |
| 153 | .None, .L, .LL, .I, .IL, .ILL, .WB, .IWB => true, | |
| 154 | .U, .UL, .ULL, .IU, .IUL, .IULL, .UWB, .IUWB => false, | |
| 155 | .F, .IF, .F16 => unreachable, | |
| 156 | }; | |
| 157 | } | |
| 158 | ||
| 159 | pub fn signedness(suffix: Suffix) std.builtin.Signedness { | |
| 160 | return if (suffix.isSignedInteger()) .signed else .unsigned; | |
| 161 | } | |
| 162 | ||
| 163 | pub fn isBitInt(suffix: Suffix) bool { | |
| 164 | return switch (suffix) { | |
| 165 | .WB, .UWB, .IWB, .IUWB => true, | |
| 166 | else => false, | |
| 167 | }; | |
| 168 | } | |
| 169 | }; |
deps/aro/aro/target.zig-1| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const LangOpts = @import("LangOpts.zig"); |
| 3 | 3 | const Type = @import("Type.zig"); |
| 4 | const llvm = @import("root").codegen.llvm; | |
| 5 | 4 | const TargetSet = @import("Builtins/Properties.zig").TargetSet; |
| 6 | 5 | |
| 7 | 6 | /// intmax_t for this target |