authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-11-20 11:19:52+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-11-25 04:52:21+02:00
logd2a8660d0467c024790c7dcdeb9366d993723fd7
tree07323947e797161c2c182dca99a16de6116f22ce
parent54f4abae2f811c6de1d5c5156961e1bd75405aa6

sync Aro dependency

ref: 9d538ea0253bb63c0b35ec907a3a734d1e22fc32

17 files changed, 979 insertions(+), 675 deletions(-)

deps/aro/aro/Builtins/Builtin.def+152
...@@ -17008,3 +17008,155 @@ wmemmove...@@ -17008,3 +17008,155 @@ wmemmove
17008 .param_str = "w*w*wC*z"17008 .param_str = "w*w*wC*z"
17009 .header = .wchar17009 .header = .wchar
17010 .attributes = .{ .lib_function_without_prefix = true, .const_evaluable = true }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,6 +408,17 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void {
408 \\408 \\
409 );409 );
410410
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 // types422 // types
412 if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");423 if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
413 try w.writeAll("#define __CHAR_BIT__ 8\n");424 try w.writeAll("#define __CHAR_BIT__ 8\n");
...@@ -445,6 +456,10 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void {...@@ -445,6 +456,10 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void {
445 try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar);456 try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar);
446 // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer });457 // try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer });
447458
459 if (target_util.hasInt128(comp.target)) {
460 try comp.generateSizeofType(w, "__SIZEOF_INT128__", .{ .specifier = .int128 });
461 }
462
448 // various int types463 // various int types
449 const mapper = comp.string_interner.getSlowTypeMapper();464 const mapper = comp.string_interner.getSlowTypeMapper();
450 try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts);465 try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts);
...@@ -461,6 +476,7 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void {...@@ -461,6 +476,7 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void {
461 try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts);476 try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts);
462477
463 try comp.generateExactWidthTypes(w, mapper);478 try comp.generateExactWidthTypes(w, mapper);
479 try comp.generateFastAndLeastWidthTypes(w, mapper);
464480
465 if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| {481 if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| {
466 try generateFloatMacros(w, "FLT16", half, "F16");482 try generateFloatMacros(w, "FLT16", half, "F16");
...@@ -497,10 +513,11 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi...@@ -497,10 +513,11 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi
497 );513 );
498 }514 }
499515
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 // standard macros519 // standard macros
501 try buf.appendSlice(520 try buf.appendSlice(
502 \\#define __STDC__ 1
503 \\#define __STDC_HOSTED__ 1
504 \\#define __STDC_NO_ATOMICS__ 1521 \\#define __STDC_NO_ATOMICS__ 1
505 \\#define __STDC_NO_COMPLEX__ 1522 \\#define __STDC_NO_COMPLEX__ 1
506 \\#define __STDC_NO_THREADS__ 1523 \\#define __STDC_NO_THREADS__ 1
...@@ -678,6 +695,14 @@ fn generateBuiltinTypes(comp: *Compilation) !void {...@@ -678,6 +695,14 @@ fn generateBuiltinTypes(comp: *Compilation) !void {
678695
679/// Smallest integer type with at least N bits696/// Smallest integer type with at least N bits
680fn intLeastN(comp: *const Compilation, bits: usize, signedness: std.builtin.Signedness) Type {697fn 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 const candidates = switch (signedness) {706 const candidates = switch (signedness) {
682 .signed => &[_]Type.Specifier{ .schar, .short, .int, .long, .long_long },707 .signed => &[_]Type.Specifier{ .schar, .short, .int, .long, .long_long },
683 .unsigned => &[_]Type.Specifier{ .uchar, .ushort, .uint, .ulong, .ulong_long },708 .unsigned => &[_]Type.Specifier{ .uchar, .ushort, .uint, .ulong, .ulong_long },
...@@ -693,6 +718,52 @@ fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 {...@@ -693,6 +718,52 @@ fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 {
693 return ty.sizeof(comp).?;718 return ty.sizeof(comp).?;
694}719}
695720
721fn 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
757fn 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
696fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper) !void {767fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper) !void {
697 try comp.generateExactWidthType(w, mapper, .schar);768 try comp.generateExactWidthType(w, mapper, .schar);
698769
deps/aro/aro/Diagnostics.zig+4-3
...@@ -236,7 +236,7 @@ pub fn set(d: *Diagnostics, name: []const u8, to: Kind) !void {...@@ -236,7 +236,7 @@ pub fn set(d: *Diagnostics, name: []const u8, to: Kind) !void {
236 try d.addExtra(.{}, .{236 try d.addExtra(.{}, .{
237 .tag = .unknown_warning,237 .tag = .unknown_warning,
238 .extra = .{ .str = name },238 .extra = .{ .str = name },
239 }, &.{});239 }, &.{}, true);
240}240}
241241
242pub fn init(gpa: Allocator) Diagnostics {242pub fn init(gpa: Allocator) Diagnostics {
...@@ -251,7 +251,7 @@ pub fn deinit(d: *Diagnostics) void {...@@ -251,7 +251,7 @@ pub fn deinit(d: *Diagnostics) void {
251}251}
252252
253pub fn add(comp: *Compilation, msg: Message, expansion_locs: []const Source.Location) Compilation.Error!void {253pub 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}
256256
257pub fn addExtra(257pub fn addExtra(
...@@ -259,6 +259,7 @@ pub fn addExtra(...@@ -259,6 +259,7 @@ pub fn addExtra(
259 langopts: LangOpts,259 langopts: LangOpts,
260 msg: Message,260 msg: Message,
261 expansion_locs: []const Source.Location,261 expansion_locs: []const Source.Location,
262 note_msg_loc: bool,
262) Compilation.Error!void {263) Compilation.Error!void {
263 const kind = d.tagKind(msg.tag, langopts);264 const kind = d.tagKind(msg.tag, langopts);
264 if (kind == .off) return;265 if (kind == .off) return;
...@@ -301,7 +302,7 @@ pub fn addExtra(...@@ -301,7 +302,7 @@ pub fn addExtra(
301 }302 }
302 }303 }
303304
304 d.list.appendAssumeCapacity(.{305 if (note_msg_loc) d.list.appendAssumeCapacity(.{
305 .tag = .expanded_from_here,306 .tag = .expanded_from_here,
306 .kind = .note,307 .kind = .note,
307 .loc = msg.loc,308 .loc = msg.loc,
deps/aro/aro/Driver.zig+16
...@@ -98,8 +98,10 @@ pub const usage =...@@ -98,8 +98,10 @@ pub const usage =
98 \\ -fno-declspec Disable support for __declspec attributes98 \\ -fno-declspec Disable support for __declspec attributes
99 \\ -ffp-eval-method=[source|double|extended]99 \\ -ffp-eval-method=[source|double|extended]
100 \\ Evaluation method to use for floating-point arithmetic100 \\ Evaluation method to use for floating-point arithmetic
101 \\ -ffreestanding Compilation in a freestanding environment
101 \\ -fgnu-inline-asm Enable GNU style inline asm (default: enabled)102 \\ -fgnu-inline-asm Enable GNU style inline asm (default: enabled)
102 \\ -fno-gnu-inline-asm Disable GNU style inline asm103 \\ -fno-gnu-inline-asm Disable GNU style inline asm
104 \\ -fhosted Compilation in a hosted environment
103 \\ -fms-extensions Enable support for Microsoft extensions105 \\ -fms-extensions Enable support for Microsoft extensions
104 \\ -fno-ms-extensions Disable support for Microsoft extensions106 \\ -fno-ms-extensions Disable support for Microsoft extensions
105 \\ -fdollars-in-identifiers 107 \\ -fdollars-in-identifiers
...@@ -177,6 +179,7 @@ pub fn parseArgs(...@@ -177,6 +179,7 @@ pub fn parseArgs(
177) !bool {179) !bool {
178 var i: usize = 1;180 var i: usize = 1;
179 var comment_arg: []const u8 = "";181 var comment_arg: []const u8 = "";
182 var hosted: ?bool = null;
180 while (i < args.len) : (i += 1) {183 while (i < args.len) : (i += 1) {
181 const arg = args[i];184 const arg = args[i];
182 if (mem.startsWith(u8, arg, "-") and arg.len > 1) {185 if (mem.startsWith(u8, arg, "-") and arg.len > 1) {
...@@ -277,6 +280,10 @@ pub fn parseArgs(...@@ -277,6 +280,10 @@ pub fn parseArgs(
277 d.comp.langopts.declspec_attrs = true;280 d.comp.langopts.declspec_attrs = true;
278 } else if (mem.eql(u8, arg, "-fno-declspec")) {281 } else if (mem.eql(u8, arg, "-fno-declspec")) {
279 d.comp.langopts.declspec_attrs = false;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 } else if (mem.eql(u8, arg, "-fms-extensions")) {287 } else if (mem.eql(u8, arg, "-fms-extensions")) {
281 d.comp.langopts.enableMSExtensions();288 d.comp.langopts.enableMSExtensions();
282 } else if (mem.eql(u8, arg, "-fno-ms-extensions")) {289 } else if (mem.eql(u8, arg, "-fno-ms-extensions")) {
...@@ -440,6 +447,15 @@ pub fn parseArgs(...@@ -440,6 +447,15 @@ pub fn parseArgs(
440 if (d.comp.langopts.preserve_comments and !d.only_preprocess) {447 if (d.comp.langopts.preserve_comments and !d.only_preprocess) {
441 return d.fatal("invalid argument '{s}' only allowed with '-E'", .{comment_arg});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 return false;459 return false;
444}460}
445461
deps/aro/aro/Driver/Filesystem.zig+10-10
...@@ -121,7 +121,7 @@ pub const Filesystem = union(enum) {...@@ -121,7 +121,7 @@ pub const Filesystem = union(enum) {
121 base: []const u8,121 base: []const u8,
122 i: usize = 0,122 i: usize = 0,
123123
124 fn next(self: *@This()) !?std.fs.IterableDir.Entry {124 fn next(self: *@This()) !?std.fs.Dir.Entry {
125 while (self.i < self.entries.len) {125 while (self.i < self.entries.len) {
126 const entry = self.entries[self.i];126 const entry = self.entries[self.i];
127 self.i += 1;127 self.i += 1;
...@@ -130,7 +130,7 @@ pub const Filesystem = union(enum) {...@@ -130,7 +130,7 @@ pub const Filesystem = union(enum) {
130 const remaining = entry.path[self.base.len + 1 ..];130 const remaining = entry.path[self.base.len + 1 ..];
131 if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue;131 if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue;
132 const extension = std.fs.path.extension(remaining);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 return .{ .name = remaining, .kind = kind };134 return .{ .name = remaining, .kind = kind };
135 }135 }
136 }136 }
...@@ -139,18 +139,18 @@ pub const Filesystem = union(enum) {...@@ -139,18 +139,18 @@ pub const Filesystem = union(enum) {
139 };139 };
140 };140 };
141141
142 const IterableDir = union(enum) {142 const Dir = union(enum) {
143 dir: std.fs.IterableDir,143 dir: std.fs.Dir,
144 fake: FakeDir,144 fake: FakeDir,
145145
146 pub fn iterate(self: IterableDir) Iterator {146 pub fn iterate(self: Dir) Iterator {
147 return switch (self) {147 return switch (self) {
148 .dir => |dir| .{ .iterator = dir.iterate() },148 .dir => |dir| .{ .iterator = dir.iterate() },
149 .fake => |fake| .{ .fake = fake.iterate() },149 .fake => |fake| .{ .fake = fake.iterate() },
150 };150 };
151 }151 }
152152
153 pub fn close(self: *IterableDir) void {153 pub fn close(self: *Dir) void {
154 switch (self.*) {154 switch (self.*) {
155 .dir => |*d| d.close(),155 .dir => |*d| d.close(),
156 .fake => {},156 .fake => {},
...@@ -159,10 +159,10 @@ pub const Filesystem = union(enum) {...@@ -159,10 +159,10 @@ pub const Filesystem = union(enum) {
159 };159 };
160160
161 const Iterator = union(enum) {161 const Iterator = union(enum) {
162 iterator: std.fs.IterableDir.Iterator,162 iterator: std.fs.Dir.Iterator,
163 fake: FakeDir.Iterator,163 fake: FakeDir.Iterator,
164164
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 return switch (self.*) {166 return switch (self.*) {
167 .iterator => |*it| it.next(),167 .iterator => |*it| it.next(),
168 .fake => |*it| it.next(),168 .fake => |*it| it.next(),
...@@ -221,9 +221,9 @@ pub const Filesystem = union(enum) {...@@ -221,9 +221,9 @@ pub const Filesystem = union(enum) {
221 };221 };
222 }222 }
223223
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 return switch (fs) {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 .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } },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,7 +602,7 @@ fn scanLibDirForGCCTriple(
602 const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue;602 const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue;
603603
604 const dir_name = std.fs.path.join(fib.allocator(), &.{ lib_dir, lib_suffix }) catch continue;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 defer parent_dir.close();606 defer parent_dir.close();
607607
608 var it = parent_dir.iterate();608 var it = parent_dir.iterate();
deps/aro/aro/Parser.zig+79-32
...@@ -9,6 +9,8 @@ const Tokenizer = @import("Tokenizer.zig");...@@ -9,6 +9,8 @@ const Tokenizer = @import("Tokenizer.zig");
9const Preprocessor = @import("Preprocessor.zig");9const Preprocessor = @import("Preprocessor.zig");
10const Tree = @import("Tree.zig");10const Tree = @import("Tree.zig");
11const Token = Tree.Token;11const Token = Tree.Token;
12const NumberPrefix = Token.NumberPrefix;
13const NumberSuffix = Token.NumberSuffix;
12const TokenIndex = Tree.TokenIndex;14const TokenIndex = Tree.TokenIndex;
13const NodeIndex = Tree.NodeIndex;15const NodeIndex = Tree.NodeIndex;
14const Type = @import("Type.zig");16const Type = @import("Type.zig");
...@@ -24,9 +26,6 @@ const Symbol = SymbolStack.Symbol;...@@ -24,9 +26,6 @@ const Symbol = SymbolStack.Symbol;
24const record_layout = @import("record_layout.zig");26const record_layout = @import("record_layout.zig");
25const StrInt = @import("StringInterner.zig");27const StrInt = @import("StringInterner.zig");
26const StringId = StrInt.StringId;28const StringId = StrInt.StringId;
27const number_affixes = @import("number_affixes.zig");
28const NumberPrefix = number_affixes.Prefix;
29const NumberSuffix = number_affixes.Suffix;
30const Builtins = @import("Builtins.zig");29const Builtins = @import("Builtins.zig");
31const Builtin = Builtins.Builtin;30const Builtin = Builtins.Builtin;
32const target_util = @import("target.zig");31const target_util = @import("target.zig");
...@@ -323,7 +322,7 @@ fn expectIdentifier(p: *Parser) Error!TokenIndex {...@@ -323,7 +322,7 @@ fn expectIdentifier(p: *Parser) Error!TokenIndex {
323 return p.errExpectedToken(.identifier, actual);322 return p.errExpectedToken(.identifier, actual);
324 }323 }
325324
326 return (try p.eatIdentifier()) orelse unreachable;325 return (try p.eatIdentifier()) orelse error.ParsingFailed;
327}326}
328327
329fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex {328fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex {
...@@ -347,7 +346,7 @@ pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 {...@@ -347,7 +346,7 @@ pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 {
347 const loc = p.pp.tokens.items(.loc)[tok];346 const loc = p.pp.tokens.items(.loc)[tok];
348 var tmp_tokenizer = Tokenizer{347 var tmp_tokenizer = Tokenizer{
349 .buf = p.comp.getSource(loc.id).buf,348 .buf = p.comp.getSource(loc.id).buf,
350 .comp = p.comp,349 .langopts = p.comp.langopts,
351 .index = loc.byte_offset,350 .index = loc.byte_offset,
352 .source = .generated,351 .source = .generated,
353 };352 };
...@@ -715,6 +714,9 @@ pub fn parse(pp: *Preprocessor) Compilation.Error!Tree {...@@ -715,6 +714,9 @@ pub fn parse(pp: *Preprocessor) Compilation.Error!Tree {
715 p.field_attr_buf.deinit();714 p.field_attr_buf.deinit();
716 }715 }
717716
717 try p.syms.pushScope(&p);
718 defer p.syms.popScope();
719
718 // NodeIndex 0 must be invalid720 // NodeIndex 0 must be invalid
719 _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined });721 _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined });
720722
...@@ -1010,7 +1012,7 @@ fn decl(p: *Parser) Error!bool {...@@ -1010,7 +1012,7 @@ fn decl(p: *Parser) Error!bool {
1010 // Collect old style parameter declarations.1012 // Collect old style parameter declarations.
1011 if (init_d.d.old_style_func != null) {1013 if (init_d.d.old_style_func != null) {
1012 const attrs = init_d.d.ty.getAttributes();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 base_ty.specifier = .func;1016 base_ty.specifier = .func;
1015 init_d.d.ty = try base_ty.withAttributes(p.arena, attrs);1017 init_d.d.ty = try base_ty.withAttributes(p.arena, attrs);
10161018
...@@ -1066,7 +1068,7 @@ fn decl(p: *Parser) Error!bool {...@@ -1066,7 +1068,7 @@ fn decl(p: *Parser) Error!bool {
1066 d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param);1068 d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param);
10671069
1068 // bypass redefinition check to avoid duplicate errors1070 // bypass redefinition check to avoid duplicate errors
1069 try p.syms.syms.append(p.gpa, .{1071 try p.syms.define(p.gpa, .{
1070 .kind = .def,1072 .kind = .def,
1071 .name = interned_name,1073 .name = interned_name,
1072 .tok = d.name,1074 .tok = d.name,
...@@ -1088,7 +1090,7 @@ fn decl(p: *Parser) Error!bool {...@@ -1088,7 +1090,7 @@ fn decl(p: *Parser) Error!bool {
1088 }1090 }
10891091
1090 // bypass redefinition check to avoid duplicate errors1092 // bypass redefinition check to avoid duplicate errors
1091 try p.syms.syms.append(p.gpa, .{1093 try p.syms.define(p.gpa, .{
1092 .kind = .def,1094 .kind = .def,
1093 .name = param.name,1095 .name = param.name,
1094 .tok = param.name_tok,1096 .tok = param.name_tok,
...@@ -1428,12 +1430,14 @@ fn typeof(p: *Parser) Error!?Type {...@@ -1428,12 +1430,14 @@ fn typeof(p: *Parser) Error!?Type {
1428 .data = typeof_expr.ty.data,1430 .data = typeof_expr.ty.data,
1429 .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),1431 .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),
1430 .specifier = typeof_expr.ty.specifier,1432 .specifier = typeof_expr.ty.specifier,
1433 .decayed = typeof_expr.ty.decayed,
1431 },1434 },
1432 };1435 };
14331436
1434 return Type{1437 return Type{
1435 .data = .{ .expr = inner },1438 .data = .{ .expr = inner },
1436 .specifier = .typeof_expr,1439 .specifier = .typeof_expr,
1440 .decayed = typeof_expr.ty.decayed,
1437 };1441 };
1438}1442}
14391443
...@@ -1814,6 +1818,7 @@ fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!?...@@ -1814,6 +1818,7 @@ fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!?
1814 } else {1818 } else {
1815 init_d.d.ty.specifier = init_d.initializer.ty.specifier;1819 init_d.d.ty.specifier = init_d.initializer.ty.specifier;
1816 init_d.d.ty.data = init_d.initializer.ty.data;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 if (apply_var_attributes) {1824 if (apply_var_attributes) {
...@@ -2105,7 +2110,7 @@ fn recordSpec(p: *Parser) Error!Type {...@@ -2105,7 +2110,7 @@ fn recordSpec(p: *Parser) Error!Type {
2105 .specifier = if (is_struct) .@"struct" else .@"union",2110 .specifier = if (is_struct) .@"struct" else .@"union",
2106 .data = .{ .record = record_ty },2111 .data = .{ .record = record_ty },
2107 }, attr_buf_top, null);2112 }, attr_buf_top, null);
2108 try p.syms.syms.append(p.gpa, .{2113 try p.syms.define(p.gpa, .{
2109 .kind = if (is_struct) .@"struct" else .@"union",2114 .kind = if (is_struct) .@"struct" else .@"union",
2110 .name = interned_name,2115 .name = interned_name,
2111 .tok = ident,2116 .tok = ident,
...@@ -2151,10 +2156,8 @@ fn recordSpec(p: *Parser) Error!Type {...@@ -2151,10 +2156,8 @@ fn recordSpec(p: *Parser) Error!Type {
21512156
2152 // declare a symbol for the type2157 // declare a symbol for the type
2153 // We need to replace the symbol's type if it has attributes2158 // We need to replace the symbol's type if it has attributes
2154 var symbol_index: ?usize = null;
2155 if (maybe_ident != null and !defined) {2159 if (maybe_ident != null and !defined) {
2156 symbol_index = p.syms.syms.len;2160 try p.syms.define(p.gpa, .{
2157 try p.syms.syms.append(p.gpa, .{
2158 .kind = if (is_struct) .@"struct" else .@"union",2161 .kind = if (is_struct) .@"struct" else .@"union",
2159 .name = record_ty.name,2162 .name = record_ty.name,
2160 .tok = maybe_ident.?,2163 .tok = maybe_ident.?,
...@@ -2216,8 +2219,11 @@ fn recordSpec(p: *Parser) Error!Type {...@@ -2216,8 +2219,11 @@ fn recordSpec(p: *Parser) Error!Type {
2216 .specifier = if (is_struct) .@"struct" else .@"union",2219 .specifier = if (is_struct) .@"struct" else .@"union",
2217 .data = .{ .record = record_ty },2220 .data = .{ .record = record_ty },
2218 }, attr_buf_top, null);2221 }, attr_buf_top, null);
2219 if (ty.specifier == .attributed and symbol_index != null) {2222 if (ty.specifier == .attributed and maybe_ident != null) {
2220 p.syms.syms.items(.ty)[symbol_index.?] = ty;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 }
22222228
2223 if (!ty.hasIncompleteSize()) {2229 if (!ty.hasIncompleteSize()) {
...@@ -2474,7 +2480,7 @@ fn enumSpec(p: *Parser) Error!Type {...@@ -2474,7 +2480,7 @@ fn enumSpec(p: *Parser) Error!Type {
2474 .specifier = .@"enum",2480 .specifier = .@"enum",
2475 .data = .{ .@"enum" = enum_ty },2481 .data = .{ .@"enum" = enum_ty },
2476 }, attr_buf_top, null);2482 }, attr_buf_top, null);
2477 try p.syms.syms.append(p.gpa, .{2483 try p.syms.define(p.gpa, .{
2478 .kind = .@"enum",2484 .kind = .@"enum",
2479 .name = interned_name,2485 .name = interned_name,
2480 .tok = ident,2486 .tok = ident,
...@@ -2525,7 +2531,6 @@ fn enumSpec(p: *Parser) Error!Type {...@@ -2525,7 +2531,6 @@ fn enumSpec(p: *Parser) Error!Type {
2525 p.enum_buf.items.len = enum_buf_top;2531 p.enum_buf.items.len = enum_buf_top;
2526 }2532 }
25272533
2528 const sym_stack_top = p.syms.syms.len;
2529 var e = Enumerator.init(fixed_ty);2534 var e = Enumerator.init(fixed_ty);
2530 while (try p.enumerator(&e)) |field_and_node| {2535 while (try p.enumerator(&e)) |field_and_node| {
2531 try p.enum_buf.append(field_and_node.field);2536 try p.enum_buf.append(field_and_node.field);
...@@ -2551,13 +2556,12 @@ fn enumSpec(p: *Parser) Error!Type {...@@ -2551,13 +2556,12 @@ fn enumSpec(p: *Parser) Error!Type {
2551 const field_nodes = p.list_buf.items[list_buf_top..];2556 const field_nodes = p.list_buf.items[list_buf_top..];
25522557
2553 if (fixed_ty == null) {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 for (enum_fields, 0..) |*field, i| {2559 for (enum_fields, 0..) |*field, i| {
2558 if (field.ty.eql(Type.int, p.comp, false)) continue;2560 if (field.ty.eql(Type.int, p.comp, false)) continue;
25592561
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 const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some|2565 const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some|
2562 Type{ .specifier = some }2566 Type{ .specifier = some }
2563 else if (try res.intFitsInType(p, Type.int))2567 else if (try res.intFitsInType(p, Type.int))
...@@ -2567,8 +2571,9 @@ fn enumSpec(p: *Parser) Error!Type {...@@ -2567,8 +2571,9 @@ fn enumSpec(p: *Parser) Error!Type {
2567 else2571 else
2568 continue;2572 continue;
25692573
2570 try vals[i].intCast(dest_ty, p.comp);2574 const symbol = p.syms.getPtr(field.name, .vars);
2571 types[i] = dest_ty;2575 try symbol.val.intCast(dest_ty, p.comp);
2576 symbol.ty = dest_ty;
2572 p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty;2577 p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty;
2573 field.ty = dest_ty;2578 field.ty = dest_ty;
2574 res.ty = dest_ty;2579 res.ty = dest_ty;
...@@ -2585,7 +2590,7 @@ fn enumSpec(p: *Parser) Error!Type {...@@ -2585,7 +2590,7 @@ fn enumSpec(p: *Parser) Error!Type {
25852590
2586 // declare a symbol for the type2591 // declare a symbol for the type
2587 if (maybe_ident != null and !defined) {2592 if (maybe_ident != null and !defined) {
2588 try p.syms.syms.append(p.gpa, .{2593 try p.syms.define(p.gpa, .{
2589 .kind = .@"enum",2594 .kind = .@"enum",
2590 .name = enum_ty.name,2595 .name = enum_ty.name,
2591 .ty = ty,2596 .ty = ty,
...@@ -2885,7 +2890,7 @@ fn declarator(...@@ -2885,7 +2890,7 @@ fn declarator(
2885 try res.ty.combine(outer);2890 try res.ty.combine(outer);
2886 try res.ty.validateCombinedType(p, suffix_start);2891 try res.ty.validateCombinedType(p, suffix_start);
2887 res.old_style_func = d.old_style_func;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 return res;2894 return res;
2890 }2895 }
28912896
...@@ -4376,7 +4381,7 @@ fn stmt(p: *Parser) Error!NodeIndex {...@@ -4376,7 +4381,7 @@ fn stmt(p: *Parser) Error!NodeIndex {
4376/// | keyword_default ':' stmt4381/// | keyword_default ':' stmt
4377fn labeledStmt(p: *Parser) Error!?NodeIndex {4382fn labeledStmt(p: *Parser) Error!?NodeIndex {
4378 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) {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 const str = p.tokSlice(name_tok);4385 const str = p.tokSlice(name_tok);
4381 if (p.findLabel(str)) |some| {4386 if (p.findLabel(str)) |some| {
4382 try p.errStr(.duplicate_label, name_tok, str);4387 try p.errStr(.duplicate_label, name_tok, str);
...@@ -4814,10 +4819,23 @@ const CallExpr = union(enum) {...@@ -4814,10 +4819,23 @@ const CallExpr = union(enum) {
4814 /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for4819 /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for
4815 /// these custom-typechecked functions.4820 /// these custom-typechecked functions.
4816 fn paramCountOverride(self: CallExpr) ?u32 {4821 fn paramCountOverride(self: CallExpr) ?u32 {
4822 @setEvalBranchQuota(10_000);
4817 return switch (self) {4823 return switch (self) {
4818 .standard => null,4824 .standard => null,
4819 .builtin => |builtin| switch (builtin.tag) {4825 .builtin => |builtin| switch (builtin.tag) {
4820 Builtin.tagFromName("__builtin_complex").? => 2,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 else => null,4839 else => null,
4822 },4840 },
4823 };4841 };
...@@ -4827,10 +4845,25 @@ const CallExpr = union(enum) {...@@ -4827,10 +4845,25 @@ const CallExpr = union(enum) {
4827 return switch (self) {4845 return switch (self) {
4828 .standard => callable_ty.returnType(),4846 .standard => callable_ty.returnType(),
4829 .builtin => |builtin| switch (builtin.tag) {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 Builtin.tagFromName("__builtin_complex").? => {4859 Builtin.tagFromName("__builtin_complex").? => {
4860 if (p.list_buf.items.len < 1) return Type.invalid; // not enough arguments; already an error
4831 const last_param = p.list_buf.items[p.list_buf.items.len - 1];4861 const last_param = p.list_buf.items[p.list_buf.items.len - 1];
4832 return p.nodes.items(.ty)[@intFromEnum(last_param)].makeComplex();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 else => callable_ty.returnType(),4867 else => callable_ty.returnType(),
4835 },4868 },
4836 };4869 };
...@@ -7458,7 +7491,7 @@ fn primaryExpr(p: *Parser) Error!Result {...@@ -7458,7 +7491,7 @@ fn primaryExpr(p: *Parser) Error!Result {
7458 }7491 }
7459 switch (p.tok_ids[p.tok_i]) {7492 switch (p.tok_ids[p.tok_i]) {
7460 .identifier, .extended_identifier => {7493 .identifier, .extended_identifier => {
7461 const name_tok = p.expectIdentifier() catch unreachable;7494 const name_tok = try p.expectIdentifier();
7462 const name = p.tokSlice(name_tok);7495 const name = p.tokSlice(name_tok);
7463 const interned_name = try StrInt.intern(p.comp, name);7496 const interned_name = try StrInt.intern(p.comp, name);
7464 if (p.syms.findSymbol(interned_name)) |sym| {7497 if (p.syms.findSymbol(interned_name)) |sym| {
...@@ -7938,6 +7971,8 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {...@@ -7938,6 +7971,8 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
7938 .F, .IF => .float,7971 .F, .IF => .float,
7939 .F16 => .float16,7972 .F16 => .float16,
7940 .L, .IL => .long_double,7973 .L, .IL => .long_double,
7974 .W, .IW => .float80,
7975 .Q, .IQ, .F128, .IF128 => .float128,
7941 else => unreachable,7976 else => unreachable,
7942 } };7977 } };
7943 const val = try Value.intern(p.comp, key: {7978 const val = try Value.intern(p.comp, key: {
...@@ -7946,7 +7981,7 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {...@@ -7946,7 +7981,7 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
7946 const strings_top = p.strings.items.len;7981 const strings_top = p.strings.items.len;
7947 defer p.strings.items.len = strings_top;7982 defer p.strings.items.len = strings_top;
7948 for (buf) |c| {7983 for (buf) |c| {
7949 if (c != '_') p.strings.appendAssumeCapacity(c);7984 if (c != '\'') p.strings.appendAssumeCapacity(c);
7950 }7985 }
79517986
7952 const float = std.fmt.parseFloat(f128, p.strings.items[strings_top..]) catch unreachable;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,6 +8006,8 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
7971 .I => .complex_double,8006 .I => .complex_double,
7972 .IF => .complex_float,8007 .IF => .complex_float,
7973 .IL => .complex_long_double,8008 .IL => .complex_long_double,
8009 .IW => .complex_float80,
8010 .IQ, .IF128 => .complex_float128,
7974 else => unreachable,8011 else => unreachable,
7975 } };8012 } };
7976 res.val = .{}; // TODO add complex values8013 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,11 +8160,21 @@ fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: To
8123 var managed = try big.int.Managed.init(p.gpa);8160 var managed = try big.int.Managed.init(p.gpa);
8124 defer managed.deinit();8161 defer managed.deinit();
81258162
8126 managed.setString(base, buf) catch |e| switch (e) {8163 {
8127 error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 168164 try p.strings.ensureUnusedCapacity(buf.len);
8128 error.InvalidCharacter => unreachable, // digits validated by Tokenizer8165
8129 else => |er| return er,8166 const strings_top = p.strings.items.len;
8130 };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 const c = managed.toConst();8178 const c = managed.toConst();
8132 const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: {8179 const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: {
8133 // Literal `0` requires at least 1 bit8180 // 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,7 +315,7 @@ fn invalidTokenDiagnostic(tok_id: Token.Id) Diagnostics.Tag {
315fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 {315fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 {
316 var tokenizer = Tokenizer{316 var tokenizer = Tokenizer{
317 .buf = source.buf,317 .buf = source.buf,
318 .comp = pp.comp,318 .langopts = pp.comp.langopts,
319 .source = source.id,319 .source = source.id,
320 };320 };
321 var hash = tokenizer.nextNoWS();321 var hash = tokenizer.nextNoWS();
...@@ -334,7 +334,7 @@ fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!Token {...@@ -334,7 +334,7 @@ fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!Token {
334 pp.preprocess_count += 1;334 pp.preprocess_count += 1;
335 var tokenizer = Tokenizer{335 var tokenizer = Tokenizer{
336 .buf = source.buf,336 .buf = source.buf,
337 .comp = pp.comp,337 .langopts = pp.comp.langopts,
338 .source = source.id,338 .source = source.id,
339 };339 };
340340
...@@ -747,6 +747,17 @@ fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anyty...@@ -747,6 +747,17 @@ fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anyty
747 return error.FatalError;747 return error.FatalError;
748}748}
749749
750fn 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
750fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void {761fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void {
751 const source = pp.comp.getSource(raw.source);762 const source = pp.comp.getSource(raw.source);
752 const line_col = source.lineCol(.{ .id = raw.source, .line = raw.line, .byte_offset = raw.start });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,7 +1196,7 @@ fn pragmaOperator(pp: *Preprocessor, arg_tok: Token, operator_loc: Source.Locati
1185 try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items);1196 try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items);
1186 var tmp_tokenizer = Tokenizer{1197 var tmp_tokenizer = Tokenizer{
1187 .buf = pp.comp.generated_buf.items,1198 .buf = pp.comp.generated_buf.items,
1188 .comp = pp.comp,1199 .langopts = pp.comp.langopts,
1189 .index = @intCast(start),1200 .index = @intCast(start),
1190 .source = .generated,1201 .source = .generated,
1191 .line = pp.generated_line,1202 .line = pp.generated_line,
...@@ -1864,7 +1875,7 @@ fn expandVaOpt(...@@ -1864,7 +1875,7 @@ fn expandVaOpt(
1864 .buf = source.buf,1875 .buf = source.buf,
1865 .index = raw.start,1876 .index = raw.start,
1866 .source = raw.source,1877 .source = raw.source,
1867 .comp = pp.comp,1878 .langopts = pp.comp.langopts,
1868 .line = raw.line,1879 .line = raw.line,
1869 };1880 };
1870 while (tokenizer.index < raw.end) {1881 while (tokenizer.index < raw.end) {
...@@ -2282,11 +2293,11 @@ fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroErr...@@ -2282,11 +2293,11 @@ fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroErr
22822293
2283fn expandedSliceExtra(pp: *const Preprocessor, tok: Token, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 {2294fn expandedSliceExtra(pp: *const Preprocessor, tok: Token, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 {
2284 if (tok.id.lexeme()) |some| {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 var tmp_tokenizer = Tokenizer{2298 var tmp_tokenizer = Tokenizer{
2288 .buf = pp.comp.getSource(tok.loc.id).buf,2299 .buf = pp.comp.getSource(tok.loc.id).buf,
2289 .comp = pp.comp,2300 .langopts = pp.comp.langopts,
2290 .index = tok.loc.byte_offset,2301 .index = tok.loc.byte_offset,
2291 .source = .generated,2302 .source = .generated,
2292 };2303 };
...@@ -2340,7 +2351,7 @@ fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const Token)...@@ -2340,7 +2351,7 @@ fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const Token)
2340 // Try to tokenize the result.2351 // Try to tokenize the result.
2341 var tmp_tokenizer = Tokenizer{2352 var tmp_tokenizer = Tokenizer{
2342 .buf = pp.comp.generated_buf.items,2353 .buf = pp.comp.generated_buf.items,
2343 .comp = pp.comp,2354 .langopts = pp.comp.langopts,
2344 .index = @intCast(start),2355 .index = @intCast(start),
2345 .source = .generated,2356 .source = .generated,
2346 };2357 };
...@@ -2703,6 +2714,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {...@@ -2703,6 +2714,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
2703 error.InvalidInclude => return,2714 error.InvalidInclude => return,
2704 else => |e| return e,2715 else => |e| return e,
2705 };2716 };
2717 defer Token.free(filename_tok.expansion_locs, pp.gpa);
27062718
2707 // Check for empty filename.2719 // Check for empty filename.
2708 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);2720 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);
...@@ -2836,7 +2848,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {...@@ -2836,7 +2848,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
2836 }2848 }
28372849
2838 const embed_bytes = (try pp.comp.findEmbed(filename, first.source, include_type, limit)) orelse2850 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 defer pp.comp.gpa.free(embed_bytes);2852 defer pp.comp.gpa.free(embed_bytes);
28412853
2842 try Range.expand(prefix, pp, tokenizer);2854 try Range.expand(prefix, pp, tokenizer);
...@@ -2984,8 +2996,6 @@ fn findIncludeFilenameToken(...@@ -2984,8 +2996,6 @@ fn findIncludeFilenameToken(
2984 tokenizer: *Tokenizer,2996 tokenizer: *Tokenizer,
2985 trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof },2997 trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof },
2986) !Token {2998) !Token {
2987 const start = pp.tokens.len;
2988 defer pp.tokens.len = start;
2989 var first = first_token;2999 var first = first_token;
29903000
2991 if (first.id == .angle_bracket_left) to_end: {3001 if (first.id == .angle_bracket_left) to_end: {
...@@ -3008,35 +3018,60 @@ fn findIncludeFilenameToken(...@@ -3008,35 +3018,60 @@ fn findIncludeFilenameToken(
3008 }, &.{});3018 }, &.{});
3009 try pp.err(first, .header_str_match);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);
30133021
3014 // Check that we actually got a string.3022 const source_tok = tokFromRaw(first);
3015 const filename_tok = pp.tokens.get(start);3023 const filename_tok, const expanded_trailing = switch (source_tok.id) {
3016 switch (filename_tok.id) {3024 .string_literal, .macro_string => .{ source_tok, false },
3017 .string_literal, .macro_string => {},3025 else => expanded: {
3018 else => {3026 // Try to expand if the argument is a macro.
3019 try pp.err(first, .expected_filename);3027 pp.top_expansion_buf.items.len = 0;
3020 try pp.expectNl(tokenizer);3028 defer for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa);
3021 return error.InvalidInclude;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 switch (trailing_token_behavior) {3050 switch (trailing_token_behavior) {
3025 .expect_nl_eof => {3051 .expect_nl_eof => {
3026 // Error on extra tokens.3052 // Error on extra tokens.
3027 const nl = tokenizer.nextNoWS();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 skipToNl(tokenizer);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 return filename_tok;3069 return filename_tok;
3036}3070}
30373071
3038fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source {3072fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source {
3039 const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof);3073 const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof);
3074 defer Token.free(filename_tok.expansion_locs, pp.gpa);
30403075
3041 // Check for empty filename.3076 // Check for empty filename.
3042 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);3077 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);
...@@ -3054,7 +3089,7 @@ fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken,...@@ -3054,7 +3089,7 @@ fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken,
3054 };3089 };
30553090
3056 return (try pp.comp.findInclude(filename, first, include_type, which)) orelse3091 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}
30593094
3060fn printLinemarker(3095fn printLinemarker(
deps/aro/aro/SymbolStack.zig+201-184
...@@ -11,6 +11,8 @@ const Parser = @import("Parser.zig");...@@ -11,6 +11,8 @@ const Parser = @import("Parser.zig");
11const Value = @import("Value.zig");11const Value = @import("Value.zig");
12const StringId = @import("StringInterner.zig").StringId;12const StringId = @import("StringInterner.zig").StringId;
1313
14const SymbolStack = @This();
15
14pub const Symbol = struct {16pub const Symbol = struct {
15 name: StringId,17 name: StringId,
16 ty: Type,18 ty: Type,
...@@ -31,72 +33,74 @@ pub const Kind = enum {...@@ -31,72 +33,74 @@ pub const Kind = enum {
31 constexpr,33 constexpr,
32};34};
3335
34const SymbolStack = @This();36scopes: std.ArrayListUnmanaged(Scope) = .{},
37/// allocations from nested scopes are retained after popping; `active_len` is the number
38/// of currently-active items in `scopes`.
39active_len: usize = 0,
3540
36syms: std.MultiArrayList(Symbol) = .{},41const Scope = struct {
37scopes: std.ArrayListUnmanaged(u32) = .{},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};
3855
39pub fn deinit(s: *SymbolStack, gpa: Allocator) void {56pub 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 s.scopes.deinit(gpa);61 s.scopes.deinit(gpa);
42 s.* = undefined;62 s.* = undefined;
43}63}
4464
45pub 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
50pub fn pushScope(s: *SymbolStack, p: *Parser) !void {65pub 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}
5374
54pub fn popScope(s: *SymbolStack) void {75pub fn popScope(s: *SymbolStack) void {
55 s.syms.len = s.scopes.pop();76 s.active_len -= 1;
56}77}
5778
58pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol {79pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol {
59 const kinds = s.syms.items(.kind);80 const prev = s.lookup(name, .vars) orelse s.lookup(name, .tags) orelse return null;
60 const names = s.syms.items(.name);81 switch (prev.kind) {
61 var i = s.syms.len;82 .typedef => return prev,
62 while (i > 0) {83 .@"struct" => {
63 i -= 1;84 if (no_type_yet) return null;
64 switch (kinds[i]) {85 try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok));
65 .typedef => if (names[i] == name) return s.syms.get(i),86 return prev;
66 .@"struct" => if (names[i] == name) {87 },
67 if (no_type_yet) return null;88 .@"union" => {
68 try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok));89 if (no_type_yet) return null;
69 return s.syms.get(i);90 try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok));
70 },91 return prev;
71 .@"union" => if (names[i] == name) {92 },
72 if (no_type_yet) return null;93 .@"enum" => {
73 try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok));94 if (no_type_yet) return null;
74 return s.syms.get(i);95 try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok));
75 },96 return prev;
76 .@"enum" => if (names[i] == name) {97 },
77 if (no_type_yet) return null;98 else => 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 }
84 }99 }
85 return null;
86}100}
87101
88pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol {102pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol {
89 const kinds = s.syms.items(.kind);103 return s.lookup(name, .vars);
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;
100}104}
101105
102pub fn findTag(106pub fn findTag(
...@@ -107,36 +111,62 @@ pub fn findTag(...@@ -107,36 +111,62 @@ pub fn findTag(
107 name_tok: TokenIndex,111 name_tok: TokenIndex,
108 next_tok_id: Token.Id,112 next_tok_id: Token.Id,
109) !?Symbol {113) !?Symbol {
110 const kinds = s.syms.items(.kind);
111 const names = s.syms.items(.name);
112 // `tag Name;` should always result in a new type if in a new scope.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;115 const prev = (if (next_tok_id == .semicolon) s.get(name, .tags) else s.lookup(name, .tags)) orelse return null;
114 var i = s.syms.len;116 switch (prev.kind) {
115 while (i > end) {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
128const 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
136pub 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.
145fn lookup(s: *SymbolStack, name: StringId, kind: ScopeKind) ?Symbol {
146 var i = s.active_len;
147 while (i > 0) {
116 i -= 1;148 i -= 1;
117 switch (kinds[i]) {149 switch (kind) {
118 .@"enum" => if (names[i] == name) {150 .vars => if (s.scopes.items[i].vars.get(name)) |sym| return sym,
119 if (kind == .keyword_enum) return s.syms.get(i);151 .tags => if (s.scopes.items[i].tags.get(name)) |sym| return sym,
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 => {},
131 }152 }
132 } else return null;153 }
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]);
137 return null;154 return null;
138}155}
139156
157/// Define a symbol in the innermost scope. Does not issue diagnostics or check correctness
158/// with regard to the C standard.
159pub 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
140pub fn defineTypedef(170pub fn defineTypedef(
141 s: *SymbolStack,171 s: *SymbolStack,
142 p: *Parser,172 p: *Parser,
...@@ -145,25 +175,22 @@ pub fn defineTypedef(...@@ -145,25 +175,22 @@ pub fn defineTypedef(
145 tok: TokenIndex,175 tok: TokenIndex,
146 node: NodeIndex,176 node: NodeIndex,
147) !void {177) !void {
148 const kinds = s.syms.items(.kind);178 if (s.get(name, .vars)) |prev| {
149 const names = s.syms.items(.name);179 switch (prev.kind) {
150 const end = s.scopeEnd();180 .typedef => {
151 var i = s.syms.len;181 if (!ty.eql(prev.ty, p.comp, true)) {
152 while (i > end) {182 try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev.ty));
153 i -= 1;183 if (prev.tok != 0) try p.errTok(.previous_definition, prev.tok);
154 switch (kinds[i]) {184 }
155 .typedef => if (names[i] == name) {185 },
156 const prev_ty = s.syms.items(.ty)[i];186 .enumeration, .decl, .def, .constexpr => {
157 if (ty.eql(prev_ty, p.comp, true)) break;187 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
158 try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev_ty));188 try p.errTok(.previous_definition, prev.tok);
159 const previous_tok = s.syms.items(.tok)[i];
160 if (previous_tok != 0) try p.errTok(.previous_definition, previous_tok);
161 break;
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 .kind = .typedef,194 .kind = .typedef,
168 .name = name,195 .name = name,
169 .tok = tok,196 .tok = tok,
...@@ -183,35 +210,31 @@ pub fn defineSymbol(...@@ -183,35 +210,31 @@ pub fn defineSymbol(
183 val: Value,210 val: Value,
184 constexpr: bool,211 constexpr: bool,
185) !void {212) !void {
186 const kinds = s.syms.items(.kind);213 if (s.get(name, .vars)) |prev| {
187 const names = s.syms.items(.name);214 switch (prev.kind) {
188 const end = s.scopeEnd();215 .enumeration => {
189 var i = s.syms.len;
190 while (i > end) {
191 i -= 1;
192 switch (kinds[i]) {
193 .enumeration => if (names[i] == name) {
194 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));216 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
195 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);217 try p.errTok(.previous_definition, prev.tok);
196 break;
197 },218 },
198 .decl => if (names[i] == name) {219 .decl => {
199 const prev_ty = s.syms.items(.ty)[i];220 if (!ty.eql(prev.ty, p.comp, true)) {
200 if (!ty.eql(prev_ty, p.comp, true)) {
201 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));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 try p.errStr(.redefinition, tok, p.tokSlice(tok));226 try p.errStr(.redefinition, tok, p.tokSlice(tok));
208 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);227 try p.errTok(.previous_definition, prev.tok);
209 break;
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 .kind = if (constexpr) .constexpr else .def,238 .kind = if (constexpr) .constexpr else .def,
216 .name = name,239 .name = name,
217 .tok = tok,240 .tok = tok,
...@@ -221,6 +244,15 @@ pub fn defineSymbol(...@@ -221,6 +244,15 @@ pub fn defineSymbol(
221 });244 });
222}245}
223246
247/// Get a pointer to the named symbol in the innermost scope.
248/// Asserts that a symbol with the name exists.
249pub 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
224pub fn declareSymbol(256pub fn declareSymbol(
225 s: *SymbolStack,257 s: *SymbolStack,
226 p: *Parser,258 p: *Parser,
...@@ -229,39 +261,34 @@ pub fn declareSymbol(...@@ -229,39 +261,34 @@ pub fn declareSymbol(
229 tok: TokenIndex,261 tok: TokenIndex,
230 node: NodeIndex,262 node: NodeIndex,
231) !void {263) !void {
232 const kinds = s.syms.items(.kind);264 if (s.get(name, .vars)) |prev| {
233 const names = s.syms.items(.name);265 switch (prev.kind) {
234 const end = s.scopeEnd();266 .enumeration => {
235 var i = s.syms.len;
236 while (i > end) {
237 i -= 1;
238 switch (kinds[i]) {
239 .enumeration => if (names[i] == name) {
240 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));267 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
241 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);268 try p.errTok(.previous_definition, prev.tok);
242 break;
243 },269 },
244 .decl => if (names[i] == name) {270 .decl => {
245 const prev_ty = s.syms.items(.ty)[i];271 if (!ty.eql(prev.ty, p.comp, true)) {
246 if (!ty.eql(prev_ty, p.comp, true)) {
247 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));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) {276 .def, .constexpr => {
253 const prev_ty = s.syms.items(.ty)[i];277 if (!ty.eql(prev.ty, p.comp, true)) {
254 if (!ty.eql(prev_ty, p.comp, true)) {
255 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));278 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
256 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);279 try p.errTok(.previous_definition, prev.tok);
257 break;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 .kind = .decl,292 .kind = .decl,
266 .name = name,293 .name = name,
267 .tok = tok,294 .tok = tok,
...@@ -272,25 +299,23 @@ pub fn declareSymbol(...@@ -272,25 +299,23 @@ pub fn declareSymbol(
272}299}
273300
274pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void {301pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void {
275 const kinds = s.syms.items(.kind);302 if (s.get(name, .vars)) |prev| {
276 const names = s.syms.items(.name);303 switch (prev.kind) {
277 const end = s.scopeEnd();304 .enumeration, .decl, .def, .constexpr => {
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) {
283 try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok));305 try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok));
284 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);306 try p.errTok(.previous_definition, prev.tok);
285 break;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 if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {315 if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
291 try p.errStr(.suggest_pointer_for_invalid_fp16, tok, "parameters");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 .kind = .def,319 .kind = .def,
295 .name = name,320 .name = name,
296 .tok = tok,321 .tok = tok,
...@@ -306,35 +331,28 @@ pub fn defineTag(...@@ -306,35 +331,28 @@ pub fn defineTag(
306 kind: Token.Id,331 kind: Token.Id,
307 tok: TokenIndex,332 tok: TokenIndex,
308) !?Symbol {333) !?Symbol {
309 const kinds = s.syms.items(.kind);334 const prev = s.get(name, .tags) orelse return null;
310 const names = s.syms.items(.name);335 switch (prev.kind) {
311 const end = s.scopeEnd();336 .@"enum" => {
312 var i = s.syms.len;337 if (kind == .keyword_enum) return prev;
313 while (i > end) {338 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
314 i -= 1;339 try p.errTok(.previous_definition, prev.tok);
315 switch (kinds[i]) {340 return null;
316 .@"enum" => if (names[i] == name) {341 },
317 if (kind == .keyword_enum) return s.syms.get(i);342 .@"struct" => {
318 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));343 if (kind == .keyword_struct) return prev;
319 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);344 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
320 return null;345 try p.errTok(.previous_definition, prev.tok);
321 },346 return null;
322 .@"struct" => if (names[i] == name) {347 },
323 if (kind == .keyword_struct) return s.syms.get(i);348 .@"union" => {
324 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));349 if (kind == .keyword_union) return prev;
325 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);350 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
326 return null;351 try p.errTok(.previous_definition, prev.tok);
327 },352 return null;
328 .@"union" => if (names[i] == name) {353 },
329 if (kind == .keyword_union) return s.syms.get(i);354 else => unreachable,
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 }
336 }355 }
337 return null;
338}356}
339357
340pub fn defineEnumeration(358pub fn defineEnumeration(
...@@ -345,27 +363,26 @@ pub fn defineEnumeration(...@@ -345,27 +363,26 @@ pub fn defineEnumeration(
345 tok: TokenIndex,363 tok: TokenIndex,
346 val: Value,364 val: Value,
347) !void {365) !void {
348 const kinds = s.syms.items(.kind);366 if (s.get(name, .vars)) |prev| {
349 const names = s.syms.items(.name);367 switch (prev.kind) {
350 const end = s.scopeEnd();368 .enumeration => {
351 var i = s.syms.len;
352 while (i > end) {
353 i -= 1;
354 switch (kinds[i]) {
355 .enumeration => if (names[i] == name) {
356 try p.errStr(.redefinition, tok, p.tokSlice(tok));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 return;371 return;
359 },372 },
360 .decl, .def, .constexpr => if (names[i] == name) {373 .decl, .def, .constexpr => {
361 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));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 return;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 .kind = .enumeration,386 .kind = .enumeration,
370 .name = name,387 .name = name,
371 .tok = tok,388 .tok = tok,
deps/aro/aro/Tokenizer.zig+26-23
...@@ -749,12 +749,15 @@ pub const Token = struct {...@@ -749,12 +749,15 @@ pub const Token = struct {
749 .string_literal_utf_8,749 .string_literal_utf_8,
750 .string_literal_utf_32,750 .string_literal_utf_32,
751 .string_literal_wide,751 .string_literal_wide,
752 .unterminated_string_literal,
752 => "a string literal",753 => "a string literal",
753 .char_literal,754 .char_literal,
754 .char_literal_utf_8,755 .char_literal_utf_8,
755 .char_literal_utf_16,756 .char_literal_utf_16,
756 .char_literal_utf_32,757 .char_literal_utf_32,
757 .char_literal_wide,758 .char_literal_wide,
759 .unterminated_char_literal,
760 .empty_char_literal,
758 => "a character literal",761 => "a character literal",
759 .pp_num, .embed_byte => "A number",762 .pp_num, .embed_byte => "A number",
760 else => id.lexeme().?,763 else => id.lexeme().?,
...@@ -798,7 +801,7 @@ pub const Token = struct {...@@ -798,7 +801,7 @@ pub const Token = struct {
798 };801 };
799 }802 }
800803
801 pub fn allowsDigraphs(id: Id, comp: *const Compilation) bool {804 pub fn allowsDigraphs(id: Id, langopts: LangOpts) bool {
802 return switch (id) {805 return switch (id) {
803 .l_bracket,806 .l_bracket,
804 .r_bracket,807 .r_bracket,
...@@ -806,7 +809,7 @@ pub const Token = struct {...@@ -806,7 +809,7 @@ pub const Token = struct {
806 .r_brace,809 .r_brace,
807 .hash,810 .hash,
808 .hash_hash,811 .hash_hash,
809 => comp.langopts.hasDigraphs(),812 => langopts.hasDigraphs(),
810 else => false,813 else => false,
811 };814 };
812 }815 }
...@@ -829,15 +832,15 @@ pub const Token = struct {...@@ -829,15 +832,15 @@ pub const Token = struct {
829 /// double underscore and underscore + capital letter identifiers832 /// double underscore and underscore + capital letter identifiers
830 /// belong to the implementation namespace, so we always convert them833 /// belong to the implementation namespace, so we always convert them
831 /// to keywords.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 const kw = all_kws.get(str) orelse return .identifier;836 const kw = all_kws.get(str) orelse return .identifier;
834 const standard = comp.langopts.standard;837 const standard = langopts.standard;
835 return switch (kw) {838 return switch (kw) {
836 .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier,839 .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier,
837 .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier,840 .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier,
838 .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c23)) kw else .identifier,841 .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c23)) kw else .identifier,
839 .keyword_asm => if (standard.isGNU()) kw else .identifier,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,
841844
842 .keyword_c23_alignas,845 .keyword_c23_alignas,
843 .keyword_c23_alignof,846 .keyword_c23_alignof,
...@@ -864,7 +867,7 @@ pub const Token = struct {...@@ -864,7 +867,7 @@ pub const Token = struct {
864 .keyword_stdcall2,867 .keyword_stdcall2,
865 .keyword_thiscall2,868 .keyword_thiscall2,
866 .keyword_vectorcall2,869 .keyword_vectorcall2,
867 => if (comp.langopts.ms_extensions) kw else .identifier,870 => if (langopts.ms_extensions) kw else .identifier,
868 else => kw,871 else => kw,
869 };872 };
870 }873 }
...@@ -1023,7 +1026,7 @@ const Tokenizer = @This();...@@ -1023,7 +1026,7 @@ const Tokenizer = @This();
1023buf: []const u8,1026buf: []const u8,
1024index: u32 = 0,1027index: u32 = 0,
1025source: Source.Id,1028source: Source.Id,
1026comp: *const Compilation,1029langopts: LangOpts,
1027line: u32 = 1,1030line: u32 = 1,
10281031
1029pub fn next(self: *Tokenizer) Token {1032pub fn next(self: *Tokenizer) Token {
...@@ -1162,14 +1165,14 @@ pub fn next(self: *Tokenizer) Token {...@@ -1162,14 +1165,14 @@ pub fn next(self: *Tokenizer) Token {
1162 '#' => state = .hash,1165 '#' => state = .hash,
1163 '0'...'9' => state = .pp_num,1166 '0'...'9' => state = .pp_num,
1164 '\t', '\x0B', '\x0C', ' ' => state = .whitespace,1167 '\t', '\x0B', '\x0C', ' ' => state = .whitespace,
1165 '$' => if (self.comp.langopts.dollars_in_identifiers) {1168 '$' => if (self.langopts.dollars_in_identifiers) {
1166 state = .extended_identifier;1169 state = .extended_identifier;
1167 } else {1170 } else {
1168 id = .invalid;1171 id = .invalid;
1169 self.index += 1;1172 self.index += 1;
1170 break;1173 break;
1171 },1174 },
1172 0x1A => if (self.comp.langopts.ms_extensions) {1175 0x1A => if (self.langopts.ms_extensions) {
1173 id = .eof;1176 id = .eof;
1174 break;1177 break;
1175 } else {1178 } else {
...@@ -1306,15 +1309,15 @@ pub fn next(self: *Tokenizer) Token {...@@ -1306,15 +1309,15 @@ pub fn next(self: *Tokenizer) Token {
1306 },1309 },
1307 .identifier, .extended_identifier => switch (c) {1310 .identifier, .extended_identifier => switch (c) {
1308 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},1311 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
1309 '$' => if (self.comp.langopts.dollars_in_identifiers) {1312 '$' => if (self.langopts.dollars_in_identifiers) {
1310 state = .extended_identifier;1313 state = .extended_identifier;
1311 } else {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 break;1316 break;
1314 },1317 },
1315 0x80...0xFF => state = .extended_identifier,1318 0x80...0xFF => state = .extended_identifier,
1316 else => {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 break;1321 break;
1319 },1322 },
1320 },1323 },
...@@ -1358,7 +1361,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1358,7 +1361,7 @@ pub fn next(self: *Tokenizer) Token {
1358 },1361 },
1359 .colon => switch (c) {1362 .colon => switch (c) {
1360 '>' => {1363 '>' => {
1361 if (self.comp.langopts.hasDigraphs()) {1364 if (self.langopts.hasDigraphs()) {
1362 id = .r_bracket;1365 id = .r_bracket;
1363 self.index += 1;1366 self.index += 1;
1364 } else {1367 } else {
...@@ -1367,7 +1370,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1367,7 +1370,7 @@ pub fn next(self: *Tokenizer) Token {
1367 break;1370 break;
1368 },1371 },
1369 ':' => {1372 ':' => {
1370 if (self.comp.langopts.standard.atLeast(.c23)) {1373 if (self.langopts.standard.atLeast(.c23)) {
1371 id = .colon_colon;1374 id = .colon_colon;
1372 self.index += 1;1375 self.index += 1;
1373 break;1376 break;
...@@ -1388,7 +1391,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1388,7 +1391,7 @@ pub fn next(self: *Tokenizer) Token {
1388 break;1391 break;
1389 },1392 },
1390 '>' => {1393 '>' => {
1391 if (self.comp.langopts.hasDigraphs()) {1394 if (self.langopts.hasDigraphs()) {
1392 id = .r_brace;1395 id = .r_brace;
1393 self.index += 1;1396 self.index += 1;
1394 } else {1397 } else {
...@@ -1397,7 +1400,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1397,7 +1400,7 @@ pub fn next(self: *Tokenizer) Token {
1397 break;1400 break;
1398 },1401 },
1399 ':' => {1402 ':' => {
1400 if (self.comp.langopts.hasDigraphs()) {1403 if (self.langopts.hasDigraphs()) {
1401 state = .hash_digraph;1404 state = .hash_digraph;
1402 } else {1405 } else {
1403 id = .percent;1406 id = .percent;
...@@ -1444,7 +1447,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1444,7 +1447,7 @@ pub fn next(self: *Tokenizer) Token {
1444 break;1447 break;
1445 },1448 },
1446 ':' => {1449 ':' => {
1447 if (self.comp.langopts.hasDigraphs()) {1450 if (self.langopts.hasDigraphs()) {
1448 id = .l_bracket;1451 id = .l_bracket;
1449 self.index += 1;1452 self.index += 1;
1450 } else {1453 } else {
...@@ -1453,7 +1456,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1453,7 +1456,7 @@ pub fn next(self: *Tokenizer) Token {
1453 break;1456 break;
1454 },1457 },
1455 '%' => {1458 '%' => {
1456 if (self.comp.langopts.hasDigraphs()) {1459 if (self.langopts.hasDigraphs()) {
1457 id = .l_brace;1460 id = .l_brace;
1458 self.index += 1;1461 self.index += 1;
1459 } else {1462 } else {
...@@ -1613,7 +1616,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1613,7 +1616,7 @@ pub fn next(self: *Tokenizer) Token {
1613 },1616 },
1614 .line_comment => switch (c) {1617 .line_comment => switch (c) {
1615 '\n' => {1618 '\n' => {
1616 if (self.comp.langopts.preserve_comments) {1619 if (self.langopts.preserve_comments) {
1617 id = .comment;1620 id = .comment;
1618 break;1621 break;
1619 }1622 }
...@@ -1629,7 +1632,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1629,7 +1632,7 @@ pub fn next(self: *Tokenizer) Token {
1629 },1632 },
1630 .multi_line_comment_asterisk => switch (c) {1633 .multi_line_comment_asterisk => switch (c) {
1631 '/' => {1634 '/' => {
1632 if (self.comp.langopts.preserve_comments) {1635 if (self.langopts.preserve_comments) {
1633 self.index += 1;1636 self.index += 1;
1634 id = .comment;1637 id = .comment;
1635 break;1638 break;
...@@ -1673,7 +1676,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1673,7 +1676,7 @@ pub fn next(self: *Tokenizer) Token {
1673 '.',1676 '.',
1674 => {},1677 => {},
1675 'e', 'E', 'p', 'P' => state = .pp_num_exponent,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 state = .pp_num_digit_separator;1680 state = .pp_num_digit_separator;
1678 } else {1681 } else {
1679 id = .pp_num;1682 id = .pp_num;
...@@ -1721,7 +1724,7 @@ pub fn next(self: *Tokenizer) Token {...@@ -1721,7 +1724,7 @@ pub fn next(self: *Tokenizer) Token {
1721 } else if (self.index == self.buf.len) {1724 } else if (self.index == self.buf.len) {
1722 switch (state) {1725 switch (state) {
1723 .start, .line_comment => {},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 .extended_identifier => id = .extended_identifier,1728 .extended_identifier => id = .extended_identifier,
17261729
1727 .period2 => {1730 .period2 => {
...@@ -2149,7 +2152,7 @@ fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, st...@@ -2149,7 +2152,7 @@ fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, st
2149 var tokenizer = Tokenizer{2152 var tokenizer = Tokenizer{
2150 .buf = source.buf,2153 .buf = source.buf,
2151 .source = source.id,2154 .source = source.id,
2152 .comp = &comp,2155 .langopts = comp.langopts,
2153 };2156 };
2154 var i: usize = 0;2157 var i: usize = 0;
2155 while (i < expected_tokens.len) {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,18 +183,15 @@ pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 {
183 return tc.getProgramPath(default_linker, buf);183 return tc.getProgramPath(default_linker, buf);
184}184}
185185
186const TargetSpecificToolName = std.BoundedArray(u8, 64);
187
188/// If an explicit target is provided, also check the prefixed tool-specific name186/// If an explicit target is provided, also check the prefixed tool-specific name
189/// TODO: this isn't exactly right since our target names don't necessarily match up187/// TODO: this isn't exactly right since our target names don't necessarily match up
190/// with GCC's.188/// with GCC's.
191/// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools189/// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools
192fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, target_specific: *TargetSpecificToolName) std.BoundedArray([]const u8, 2) {190fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, buf: *[64]u8) std.BoundedArray([]const u8, 2) {
193 var possible_names: std.BoundedArray([]const u8, 2) = .{};191 var possible_names: std.BoundedArray([]const u8, 2) = .{};
194 if (raw_triple) |triple| {192 if (raw_triple) |triple| {
195 const w = target_specific.writer();193 if (std.fmt.bufPrint(buf, "{s}-{s}", .{ triple, name })) |res| {
196 if (w.print("{s}-{s}", .{ triple, name })) {194 possible_names.appendAssumeCapacity(res);
197 possible_names.appendAssumeCapacity(target_specific.constSlice());
198 } else |_| {}195 } else |_| {}
199 }196 }
200 possible_names.appendAssumeCapacity(name);197 possible_names.appendAssumeCapacity(name);
...@@ -227,8 +224,8 @@ fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8...@@ -227,8 +224,8 @@ fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8
227 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;224 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
228 var fib = std.heap.FixedBufferAllocator.init(&path_buf);225 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
229226
230 var tool_specific_name: TargetSpecificToolName = .{};227 var tool_specific_buf: [64]u8 = undefined;
231 const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_name);228 const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_buf);
232229
233 for (possible_names.constSlice()) |tool_name| {230 for (possible_names.constSlice()) |tool_name| {
234 for (tc.program_paths.items) |program_path| {231 for (tc.program_paths.items) |program_path| {
deps/aro/aro/Tree.zig+7-4
...@@ -1,11 +1,12 @@...@@ -1,11 +1,12 @@
1const std = @import("std");1const std = @import("std");
2const Interner = @import("backend").Interner;2const Interner = @import("backend").Interner;
3const Type = @import("Type.zig");3const Attribute = @import("Attribute.zig");
4const Tokenizer = @import("Tokenizer.zig");
5const CodeGen = @import("CodeGen.zig");4const CodeGen = @import("CodeGen.zig");
6const Compilation = @import("Compilation.zig");5const Compilation = @import("Compilation.zig");
6const number_affixes = @import("Tree/number_affixes.zig");
7const Source = @import("Source.zig");7const Source = @import("Source.zig");
8const Attribute = @import("Attribute.zig");8const Tokenizer = @import("Tokenizer.zig");
9const Type = @import("Type.zig");
9const Value = @import("Value.zig");10const Value = @import("Value.zig");
10const StringInterner = @import("StringInterner.zig");11const StringInterner = @import("StringInterner.zig");
1112
...@@ -92,6 +93,8 @@ pub const Token = struct {...@@ -92,6 +93,8 @@ pub const Token = struct {
9293
93 pub const List = std.MultiArrayList(Token);94 pub const List = std.MultiArrayList(Token);
94 pub const Id = Tokenizer.Token.Id;95 pub const Id = Tokenizer.Token.Id;
96 pub const NumberPrefix = number_affixes.Prefix;
97 pub const NumberSuffix = number_affixes.Suffix;
95};98};
9699
97pub const TokenIndex = u32;100pub const TokenIndex = u32;
...@@ -669,7 +672,7 @@ pub fn tokSlice(tree: *const Tree, tok_i: TokenIndex) []const u8 {...@@ -669,7 +672,7 @@ pub fn tokSlice(tree: *const Tree, tok_i: TokenIndex) []const u8 {
669 const loc = tree.tokens.items(.loc)[tok_i];672 const loc = tree.tokens.items(.loc)[tok_i];
670 var tmp_tokenizer = Tokenizer{673 var tmp_tokenizer = Tokenizer{
671 .buf = tree.comp.getSource(loc.id).buf,674 .buf = tree.comp.getSource(loc.id).buf,
672 .comp = tree.comp,675 .langopts = tree.comp.langopts,
673 .index = loc.byte_offset,676 .index = loc.byte_offset,
674 .source = .generated,677 .source = .generated,
675 };678 };
deps/aro/aro/Tree/number_affixes.zig created+187
...@@ -0,0 +1,187 @@
1const std = @import("std");
2const mem = std.mem;
3
4pub 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
56pub 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,7 +363,6 @@ pub const Specifier = enum {
363 // data.sub_type363 // data.sub_type
364 pointer,364 pointer,
365 unspecified_variable_len_array,365 unspecified_variable_len_array,
366 decayed_unspecified_variable_len_array,
367 // data.func366 // data.func
368 /// int foo(int bar, char baz) and int (void)367 /// int foo(int bar, char baz) and int (void)
369 func,368 func,
...@@ -375,15 +374,11 @@ pub const Specifier = enum {...@@ -375,15 +374,11 @@ pub const Specifier = enum {
375374
376 // data.array375 // data.array
377 array,376 array,
378 decayed_array,
379 static_array,377 static_array,
380 decayed_static_array,
381 incomplete_array,378 incomplete_array,
382 decayed_incomplete_array,
383 vector,379 vector,
384 // data.expr380 // data.expr
385 variable_len_array,381 variable_len_array,
386 decayed_variable_len_array,
387382
388 // data.record383 // data.record
389 @"struct",384 @"struct",
...@@ -394,13 +389,9 @@ pub const Specifier = enum {...@@ -394,13 +389,9 @@ pub const Specifier = enum {
394389
395 /// typeof(type-name)390 /// typeof(type-name)
396 typeof_type,391 typeof_type,
397 /// decayed array created with typeof(type-name)
398 decayed_typeof_type,
399392
400 /// typeof(expression)393 /// typeof(expression)
401 typeof_expr,394 typeof_expr,
402 /// decayed array created with typeof(expression)
403 decayed_typeof_expr,
404395
405 /// data.attributed396 /// data.attributed
406 attributed,397 attributed,
...@@ -428,6 +419,7 @@ data: union {...@@ -428,6 +419,7 @@ data: union {
428} = .{ .none = {} },419} = .{ .none = {} },
429specifier: Specifier,420specifier: Specifier,
430qual: Qualifiers = .{},421qual: Qualifiers = .{},
422decayed: bool = false,
431423
432pub const int = Type{ .specifier = .int };424pub const int = Type{ .specifier = .int };
433pub const invalid = Type{ .specifier = .invalid };425pub const invalid = Type{ .specifier = .invalid };
...@@ -442,7 +434,7 @@ pub fn is(ty: Type, specifier: Specifier) bool {...@@ -442,7 +434,7 @@ pub fn is(ty: Type, specifier: Specifier) bool {
442pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type {434pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type {
443 if (attributes.len == 0) return self;435 if (attributes.len == 0) return self;
444 const attributed_type = try Type.Attributed.create(allocator, self, self.getAttributes(), attributes);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}
447439
448pub fn isCallable(ty: Type) ?Type {440pub fn isCallable(ty: Type) ?Type {
...@@ -468,10 +460,10 @@ pub fn isFunc(ty: Type) bool {...@@ -468,10 +460,10 @@ pub fn isFunc(ty: Type) bool {
468460
469pub fn isArray(ty: Type) bool {461pub fn isArray(ty: Type) bool {
470 return switch (ty.specifier) {462 return switch (ty.specifier) {
471 .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => true,463 .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => !ty.isDecayed(),
472 .typeof_type => ty.data.sub_type.isArray(),464 .typeof_type => !ty.isDecayed() and ty.data.sub_type.isArray(),
473 .typeof_expr => ty.data.expr.ty.isArray(),465 .typeof_expr => !ty.isDecayed() and ty.data.expr.ty.isArray(),
474 .attributed => ty.data.attributed.base.isArray(),466 .attributed => !ty.isDecayed() and ty.data.attributed.base.isArray(),
475 else => false,467 else => false,
476 };468 };
477}469}
...@@ -502,35 +494,22 @@ pub fn isScalarNonInt(ty: Type) bool {...@@ -502,35 +494,22 @@ pub fn isScalarNonInt(ty: Type) bool {
502}494}
503495
504pub fn isDecayed(ty: Type) bool {496pub fn isDecayed(ty: Type) bool {
505 const decayed = switch (ty.specifier) {497 return ty.decayed;
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;
518}498}
519499
520pub fn isPtr(ty: Type) bool {500pub fn isPtr(ty: Type) bool {
521 return switch (ty.specifier) {501 return switch (ty.specifier) {
522 .pointer,502 .pointer => true,
523 .decayed_array,503
524 .decayed_static_array,504 .array,
525 .decayed_incomplete_array,505 .static_array,
526 .decayed_variable_len_array,506 .incomplete_array,
527 .decayed_unspecified_variable_len_array,507 .variable_len_array,
528 .decayed_typeof_type,508 .unspecified_variable_len_array,
529 .decayed_typeof_expr,509 => ty.isDecayed(),
530 => true,510 .typeof_type => ty.isDecayed() or ty.data.sub_type.isPtr(),
531 .typeof_type => ty.data.sub_type.isPtr(),511 .typeof_expr => ty.isDecayed() or ty.data.expr.ty.isPtr(),
532 .typeof_expr => ty.data.expr.ty.isPtr(),512 .attributed => ty.isDecayed() or ty.data.attributed.base.isPtr(),
533 .attributed => ty.data.attributed.base.isPtr(),
534 else => false,513 else => false,
535 };514 };
536}515}
...@@ -608,15 +587,15 @@ pub fn isVoidStar(ty: Type) bool {...@@ -608,15 +587,15 @@ pub fn isVoidStar(ty: Type) bool {
608587
609pub fn isTypeof(ty: Type) bool {588pub fn isTypeof(ty: Type) bool {
610 return switch (ty.specifier) {589 return switch (ty.specifier) {
611 .typeof_type, .typeof_expr, .decayed_typeof_type, .decayed_typeof_expr => true,590 .typeof_type, .typeof_expr => true,
612 else => false,591 else => false,
613 };592 };
614}593}
615594
616pub fn isConst(ty: Type) bool {595pub fn isConst(ty: Type) bool {
617 return switch (ty.specifier) {596 return switch (ty.specifier) {
618 .typeof_type, .decayed_typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(),597 .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(),598 .typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(),
620 .attributed => ty.data.attributed.base.isConst(),599 .attributed => ty.data.attributed.base.isConst(),
621 else => ty.qual.@"const",600 else => ty.qual.@"const",
622 };601 };
...@@ -630,7 +609,7 @@ pub fn signedness(ty: Type, comp: *const Compilation) std.builtin.Signedness {...@@ -630,7 +609,7 @@ pub fn signedness(ty: Type, comp: *const Compilation) std.builtin.Signedness {
630 return switch (ty.specifier) {609 return switch (ty.specifier) {
631 // zig fmt: off610 // zig fmt: off
632 .char, .complex_char => return comp.getCharSignedness(),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 .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => .unsigned,613 .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => .unsigned,
635 // zig fmt: on614 // zig fmt: on
636 .bit_int, .complex_bit_int => ty.data.int.signedness,615 .bit_int, .complex_bit_int => ty.data.int.signedness,
...@@ -678,16 +657,16 @@ pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool {...@@ -678,16 +657,16 @@ pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool {
678657
679pub fn elemType(ty: Type) Type {658pub fn elemType(ty: Type) Type {
680 return switch (ty.specifier) {659 return switch (ty.specifier) {
681 .pointer, .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => ty.data.sub_type.*,660 .pointer, .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,661 .array, .static_array, .incomplete_array, .vector => ty.data.array.elem,
683 .variable_len_array, .decayed_variable_len_array => ty.data.expr.ty,662 .variable_len_array => ty.data.expr.ty,
684 .typeof_type, .decayed_typeof_type, .typeof_expr, .decayed_typeof_expr => {663 .typeof_type, .typeof_expr => {
685 const unwrapped = ty.canonicalize(.preserve_quals);664 const unwrapped = ty.canonicalize(.preserve_quals);
686 var elem = unwrapped.elemType();665 var elem = unwrapped.elemType();
687 elem.qual = elem.qual.mergeAll(unwrapped.qual);666 elem.qual = elem.qual.mergeAll(unwrapped.qual);
688 return elem;667 return elem;
689 },668 },
690 .attributed => ty.data.attributed.base,669 .attributed => ty.data.attributed.base.elemType(),
691 .invalid => Type.invalid,670 .invalid => Type.invalid,
692 // zig fmt: off671 // zig fmt: off
693 .complex_float, .complex_double, .complex_long_double, .complex_float80,672 .complex_float, .complex_double, .complex_long_double, .complex_float80,
...@@ -703,8 +682,8 @@ pub fn elemType(ty: Type) Type {...@@ -703,8 +682,8 @@ pub fn elemType(ty: Type) Type {
703pub fn returnType(ty: Type) Type {682pub fn returnType(ty: Type) Type {
704 return switch (ty.specifier) {683 return switch (ty.specifier) {
705 .func, .var_args_func, .old_style_func => ty.data.func.return_type,684 .func, .var_args_func, .old_style_func => ty.data.func.return_type,
706 .typeof_type, .decayed_typeof_type => ty.data.sub_type.returnType(),685 .typeof_type => ty.data.sub_type.returnType(),
707 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.returnType(),686 .typeof_expr => ty.data.expr.ty.returnType(),
708 .attributed => ty.data.attributed.base.returnType(),687 .attributed => ty.data.attributed.base.returnType(),
709 .invalid => Type.invalid,688 .invalid => Type.invalid,
710 else => unreachable,689 else => unreachable,
...@@ -714,8 +693,8 @@ pub fn returnType(ty: Type) Type {...@@ -714,8 +693,8 @@ pub fn returnType(ty: Type) Type {
714pub fn params(ty: Type) []Func.Param {693pub fn params(ty: Type) []Func.Param {
715 return switch (ty.specifier) {694 return switch (ty.specifier) {
716 .func, .var_args_func, .old_style_func => ty.data.func.params,695 .func, .var_args_func, .old_style_func => ty.data.func.params,
717 .typeof_type, .decayed_typeof_type => ty.data.sub_type.params(),696 .typeof_type => ty.data.sub_type.params(),
718 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.params(),697 .typeof_expr => ty.data.expr.ty.params(),
719 .attributed => ty.data.attributed.base.params(),698 .attributed => ty.data.attributed.base.params(),
720 .invalid => &.{},699 .invalid => &.{},
721 else => unreachable,700 else => unreachable,
...@@ -724,9 +703,9 @@ pub fn params(ty: Type) []Func.Param {...@@ -724,9 +703,9 @@ pub fn params(ty: Type) []Func.Param {
724703
725pub fn arrayLen(ty: Type) ?u64 {704pub fn arrayLen(ty: Type) ?u64 {
726 return switch (ty.specifier) {705 return switch (ty.specifier) {
727 .array, .static_array, .decayed_array, .decayed_static_array => ty.data.array.len,706 .array, .static_array => ty.data.array.len,
728 .typeof_type, .decayed_typeof_type => ty.data.sub_type.arrayLen(),707 .typeof_type => ty.data.sub_type.arrayLen(),
729 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.arrayLen(),708 .typeof_expr => ty.data.expr.ty.arrayLen(),
730 .attributed => ty.data.attributed.base.arrayLen(),709 .attributed => ty.data.attributed.base.arrayLen(),
731 else => null,710 else => null,
732 };711 };
...@@ -748,8 +727,8 @@ pub fn anyQual(ty: Type) bool {...@@ -748,8 +727,8 @@ pub fn anyQual(ty: Type) bool {
748pub fn getAttributes(ty: Type) []const Attribute {727pub fn getAttributes(ty: Type) []const Attribute {
749 return switch (ty.specifier) {728 return switch (ty.specifier) {
750 .attributed => ty.data.attributed.attributes,729 .attributed => ty.data.attributed.attributes,
751 .typeof_type, .decayed_typeof_type => ty.data.sub_type.getAttributes(),730 .typeof_type => ty.data.sub_type.getAttributes(),
752 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getAttributes(),731 .typeof_expr => ty.data.expr.ty.getAttributes(),
753 else => &.{},732 else => &.{},
754 };733 };
755}734}
...@@ -757,8 +736,8 @@ pub fn getAttributes(ty: Type) []const Attribute {...@@ -757,8 +736,8 @@ pub fn getAttributes(ty: Type) []const Attribute {
757pub fn getRecord(ty: Type) ?*const Type.Record {736pub fn getRecord(ty: Type) ?*const Type.Record {
758 return switch (ty.specifier) {737 return switch (ty.specifier) {
759 .attributed => ty.data.attributed.base.getRecord(),738 .attributed => ty.data.attributed.base.getRecord(),
760 .typeof_type, .decayed_typeof_type => ty.data.sub_type.getRecord(),739 .typeof_type => ty.data.sub_type.getRecord(),
761 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getRecord(),740 .typeof_expr => ty.data.expr.ty.getRecord(),
762 .@"struct", .@"union" => ty.data.record,741 .@"struct", .@"union" => ty.data.record,
763 else => null,742 else => null,
764 };743 };
...@@ -901,6 +880,7 @@ pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type {...@@ -901,6 +880,7 @@ pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type {
901}880}
902881
903pub fn hasIncompleteSize(ty: Type) bool {882pub fn hasIncompleteSize(ty: Type) bool {
883 if (ty.isDecayed()) return false;
904 return switch (ty.specifier) {884 return switch (ty.specifier) {
905 .void, .incomplete_array => true,885 .void, .incomplete_array => true,
906 .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed,886 .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed,
...@@ -917,20 +897,14 @@ pub fn hasUnboundVLA(ty: Type) bool {...@@ -917,20 +897,14 @@ pub fn hasUnboundVLA(ty: Type) bool {
917 var cur = ty;897 var cur = ty;
918 while (true) {898 while (true) {
919 switch (cur.specifier) {899 switch (cur.specifier) {
920 .unspecified_variable_len_array,900 .unspecified_variable_len_array => return true,
921 .decayed_unspecified_variable_len_array,
922 => return true,
923 .array,901 .array,
924 .static_array,902 .static_array,
925 .incomplete_array,903 .incomplete_array,
926 .variable_len_array,904 .variable_len_array,
927 .decayed_array,
928 .decayed_static_array,
929 .decayed_incomplete_array,
930 .decayed_variable_len_array,
931 => cur = cur.elemType(),905 => cur = cur.elemType(),
932 .typeof_type, .decayed_typeof_type => cur = cur.data.sub_type.*,906 .typeof_type => cur = cur.data.sub_type.*,
933 .typeof_expr, .decayed_typeof_expr => cur = cur.data.expr.ty,907 .typeof_expr => cur = cur.data.expr.ty,
934 .attributed => cur = cur.data.attributed.base,908 .attributed => cur = cur.data.attributed.base,
935 else => return false,909 else => return false,
936 }910 }
...@@ -1006,9 +980,11 @@ pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder {...@@ -1006,9 +980,11 @@ pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder {
1006980
1007/// Size of type as reported by sizeof981/// Size of type as reported by sizeof
1008pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {982pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
983 if (ty.isPtr()) return comp.target.ptrBitWidth() / 8;
984
1009 return switch (ty.specifier) {985 return switch (ty.specifier) {
1010 .auto_type, .c23_auto => unreachable,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 .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null,988 .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null,
1013 .func, .var_args_func, .old_style_func, .void, .bool => 1,989 .func, .var_args_func, .old_style_func, .void, .bool => 1,
1014 .char, .schar, .uchar => 1,990 .char, .schar, .uchar => 1,
...@@ -1037,14 +1013,7 @@ pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {...@@ -1037,14 +1013,7 @@ pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
1037 .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,1013 .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
1038 => return 2 * ty.makeReal().sizeof(comp).?,1014 => return 2 * ty.makeReal().sizeof(comp).?,
1039 // zig fmt: on1015 // zig fmt: on
1040 .pointer,1016 .pointer => unreachable,
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,
1048 .static_array,1017 .static_array,
1049 .nullptr_t,1018 .nullptr_t,
1050 => comp.target.ptrBitWidth() / 8,1019 => comp.target.ptrBitWidth() / 8,
...@@ -1073,8 +1042,8 @@ pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {...@@ -1073,8 +1042,8 @@ pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
1073pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 {1042pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 {
1074 return switch (ty.specifier) {1043 return switch (ty.specifier) {
1075 .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1,1044 .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1,
1076 .typeof_type, .decayed_typeof_type => ty.data.sub_type.bitSizeof(comp),1045 .typeof_type => ty.data.sub_type.bitSizeof(comp),
1077 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.bitSizeof(comp),1046 .typeof_expr => ty.data.expr.ty.bitSizeof(comp),
1078 .attributed => ty.data.attributed.base.bitSizeof(comp),1047 .attributed => ty.data.attributed.base.bitSizeof(comp),
1079 .bit_int => return ty.data.int.bits,1048 .bit_int => return ty.data.int.bits,
1080 .long_double => comp.target.c_type_bit_size(.longdouble),1049 .long_double => comp.target.c_type_bit_size(.longdouble),
...@@ -1117,7 +1086,10 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {...@@ -1117,7 +1086,10 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
1117 .unspecified_variable_len_array,1086 .unspecified_variable_len_array,
1118 .array,1087 .array,
1119 .vector,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 .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target),1093 .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target),
1122 .char, .schar, .uchar, .void, .bool => 1,1094 .char, .schar, .uchar, .void, .bool => 1,
11231095
...@@ -1153,11 +1125,6 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {...@@ -1153,11 +1125,6 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
11531125
1154 .float80, .float128 => 16,1126 .float80, .float128 => 16,
1155 .pointer,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 .static_array,1128 .static_array,
1162 .nullptr_t,1129 .nullptr_t,
1163 => switch (comp.target.cpu.arch) {1130 => switch (comp.target.cpu.arch) {
...@@ -1166,8 +1133,8 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {...@@ -1166,8 +1133,8 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
1166 },1133 },
1167 .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8),1134 .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8),
1168 .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp),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),1136 .typeof_type => ty.data.sub_type.alignof(comp),
1170 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.alignof(comp),1137 .typeof_expr => ty.data.expr.ty.alignof(comp),
1171 .attributed => ty.data.attributed.base.alignof(comp),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,7 +1146,10 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
1179/// arrays and pointers.1146/// arrays and pointers.
1180pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type {1147pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type {
1181 var cur = ty;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 if (!cur.isTypeof()) return cur;1153 if (!cur.isTypeof()) return cur;
11841154
1185 var qual = cur.qual;1155 var qual = cur.qual;
...@@ -1187,14 +1157,6 @@ pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals })...@@ -1187,14 +1157,6 @@ pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals })
1187 switch (cur.specifier) {1157 switch (cur.specifier) {
1188 .typeof_type => cur = cur.data.sub_type.*,1158 .typeof_type => cur = cur.data.sub_type.*,
1189 .typeof_expr => cur = cur.data.expr.ty,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 else => break,1160 else => break,
1199 }1161 }
1200 qual = qual.mergeAll(cur.qual);1162 qual = qual.mergeAll(cur.qual);
...@@ -1204,6 +1166,7 @@ pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals })...@@ -1204,6 +1166,7 @@ pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals })
1204 } else {1166 } else {
1205 cur.qual = qual;1167 cur.qual = qual;
1206 }1168 }
1169 cur.decayed = ty.decayed;
1207 return cur;1170 return cur;
1208}1171}
12091172
...@@ -1219,8 +1182,8 @@ pub fn get(ty: *const Type, specifier: Specifier) ?*const Type {...@@ -1219,8 +1182,8 @@ pub fn get(ty: *const Type, specifier: Specifier) ?*const Type {
12191182
1220pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 {1183pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 {
1221 return switch (ty.specifier) {1184 return switch (ty.specifier) {
1222 .typeof_type, .decayed_typeof_type => ty.data.sub_type.requestedAlignment(comp),1185 .typeof_type => ty.data.sub_type.requestedAlignment(comp),
1223 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.requestedAlignment(comp),1186 .typeof_expr => ty.data.expr.ty.requestedAlignment(comp),
1224 .attributed => annotationAlignment(comp, ty.data.attributed.attributes),1187 .attributed => annotationAlignment(comp, ty.data.attributed.attributes),
1225 else => null,1188 else => null,
1226 };1189 };
...@@ -1265,14 +1228,11 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi...@@ -1265,14 +1228,11 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi
1265 if (a.qual.@"volatile" != b.qual.@"volatile") return false;1228 if (a.qual.@"volatile" != b.qual.@"volatile") return false;
1266 }1229 }
12671230
1231 if (a.isPtr()) {
1232 return a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers);
1233 }
1268 switch (a.specifier) {1234 switch (a.specifier) {
1269 .pointer,1235 .pointer => unreachable,
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,
12761236
1277 .func,1237 .func,
1278 .var_args_func,1238 .var_args_func,
...@@ -1293,8 +1253,9 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi...@@ -1293,8 +1253,9 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi
1293 }1253 }
1294 if (!a.elemType().eql(b.elemType(), comp, false)) return false;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,1256 .variable_len_array => {
12971257 if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false;
1258 },
1298 .@"struct", .@"union" => if (a.data.record != b.data.record) return false,1259 .@"struct", .@"union" => if (a.data.record != b.data.record) return false,
1299 .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false,1260 .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false,
1300 .bit_int, .complex_bit_int => return a.data.int.bits == b.data.int.bits and a.data.int.signedness == b.data.int.signedness,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,14 +1267,14 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi
13061267
1307/// Decays an array to a pointer1268/// Decays an array to a pointer
1308pub fn decayArray(ty: *Type) void {1269pub fn decayArray(ty: *Type) void {
1309 // the decayed array type is the current specifier +11270 std.debug.assert(ty.isArray());
1310 ty.specifier = @enumFromInt(@intFromEnum(ty.specifier) + 1);1271 ty.decayed = true;
1311}1272}
13121273
1313pub fn originalTypeOfDecayedArray(ty: Type) Type {1274pub fn originalTypeOfDecayedArray(ty: Type) Type {
1314 std.debug.assert(ty.isDecayed());1275 std.debug.assert(ty.isDecayed());
1315 var copy = ty;1276 var copy = ty;
1316 copy.specifier = @enumFromInt(@intFromEnum(ty.specifier) - 1);1277 copy.decayed = false;
1317 return copy;1278 return copy;
1318}1279}
13191280
...@@ -1405,25 +1366,23 @@ pub fn combine(inner: *Type, outer: Type) Parser.Error!void {...@@ -1405,25 +1366,23 @@ pub fn combine(inner: *Type, outer: Type) Parser.Error!void {
1405 switch (inner.specifier) {1366 switch (inner.specifier) {
1406 .pointer => return inner.data.sub_type.combine(outer),1367 .pointer => return inner.data.sub_type.combine(outer),
1407 .unspecified_variable_len_array => {1368 .unspecified_variable_len_array => {
1369 std.debug.assert(!inner.isDecayed());
1408 try inner.data.sub_type.combine(outer);1370 try inner.data.sub_type.combine(outer);
1409 },1371 },
1410 .variable_len_array => {1372 .variable_len_array => {
1373 std.debug.assert(!inner.isDecayed());
1411 try inner.data.expr.ty.combine(outer);1374 try inner.data.expr.ty.combine(outer);
1412 },1375 },
1413 .array, .static_array, .incomplete_array => {1376 .array, .static_array, .incomplete_array => {
1377 std.debug.assert(!inner.isDecayed());
1414 try inner.data.array.elem.combine(outer);1378 try inner.data.array.elem.combine(outer);
1415 },1379 },
1416 .func, .var_args_func, .old_style_func => {1380 .func, .var_args_func, .old_style_func => {
1417 try inner.data.func.return_type.combine(outer);1381 try inner.data.func.return_type.combine(outer);
1418 },1382 },
1419 .decayed_array,1383 .typeof_type,
1420 .decayed_static_array,1384 .typeof_expr,
1421 .decayed_incomplete_array,1385 => std.debug.assert(!inner.isDecayed()),
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
1427 .void, .invalid => inner.* = outer,1386 .void, .invalid => inner.* = outer,
1428 else => unreachable,1387 else => unreachable,
1429 }1388 }
...@@ -1474,8 +1433,8 @@ pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser...@@ -1474,8 +1433,8 @@ pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser
1474 try p.errStr(.suggest_pointer_for_invalid_fp16, source_tok, "function return value");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),1436 .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),1437 .typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok),
1479 .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok),1438 .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok),
1480 else => {},1439 else => {},
1481 }1440 }
...@@ -1610,6 +1569,7 @@ pub const Builder = struct {...@@ -1610,6 +1569,7 @@ pub const Builder = struct {
1610 decayed_typeof_expr: *Expr,1569 decayed_typeof_expr: *Expr,
16111570
1612 attributed: *Attributed,1571 attributed: *Attributed,
1572 decayed_attributed: *Attributed,
16131573
1614 pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 {1574 pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 {
1615 return switch (spec) {1575 return switch (spec) {
...@@ -1835,13 +1795,10 @@ pub const Builder = struct {...@@ -1835,13 +1795,10 @@ pub const Builder = struct {
1835 ty.specifier = .pointer;1795 ty.specifier = .pointer;
1836 ty.data = .{ .sub_type = data };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 ty.specifier = .unspecified_variable_len_array;1799 ty.specifier = .unspecified_variable_len_array;
1840 ty.data = .{ .sub_type = data };1800 ty.data = .{ .sub_type = data };
1841 },1801 ty.decayed = b.specifier == .decayed_unspecified_variable_len_array;
1842 .decayed_unspecified_variable_len_array => |data| {
1843 ty.specifier = .decayed_unspecified_variable_len_array;
1844 ty.data = .{ .sub_type = data };
1845 },1802 },
1846 .func => |data| {1803 .func => |data| {
1847 ty.specifier = .func;1804 ty.specifier = .func;
...@@ -1855,41 +1812,29 @@ pub const Builder = struct {...@@ -1855,41 +1812,29 @@ pub const Builder = struct {
1855 ty.specifier = .old_style_func;1812 ty.specifier = .old_style_func;
1856 ty.data = .{ .func = data };1813 ty.data = .{ .func = data };
1857 },1814 },
1858 .array => |data| {1815 .array, .decayed_array => |data| {
1859 ty.specifier = .array;1816 ty.specifier = .array;
1860 ty.data = .{ .array = data };1817 ty.data = .{ .array = data };
1818 ty.decayed = b.specifier == .decayed_array;
1861 },1819 },
1862 .decayed_array => |data| {1820 .static_array, .decayed_static_array => |data| {
1863 ty.specifier = .decayed_array;
1864 ty.data = .{ .array = data };
1865 },
1866 .static_array => |data| {
1867 ty.specifier = .static_array;1821 ty.specifier = .static_array;
1868 ty.data = .{ .array = data };1822 ty.data = .{ .array = data };
1823 ty.decayed = b.specifier == .decayed_static_array;
1869 },1824 },
1870 .decayed_static_array => |data| {1825 .incomplete_array, .decayed_incomplete_array => |data| {
1871 ty.specifier = .decayed_static_array;
1872 ty.data = .{ .array = data };
1873 },
1874 .incomplete_array => |data| {
1875 ty.specifier = .incomplete_array;1826 ty.specifier = .incomplete_array;
1876 ty.data = .{ .array = data };1827 ty.data = .{ .array = data };
1877 },1828 ty.decayed = b.specifier == .decayed_incomplete_array;
1878 .decayed_incomplete_array => |data| {
1879 ty.specifier = .decayed_incomplete_array;
1880 ty.data = .{ .array = data };
1881 },1829 },
1882 .vector => |data| {1830 .vector => |data| {
1883 ty.specifier = .vector;1831 ty.specifier = .vector;
1884 ty.data = .{ .array = data };1832 ty.data = .{ .array = data };
1885 },1833 },
1886 .variable_len_array => |data| {1834 .variable_len_array, .decayed_variable_len_array => |data| {
1887 ty.specifier = .variable_len_array;1835 ty.specifier = .variable_len_array;
1888 ty.data = .{ .expr = data };1836 ty.data = .{ .expr = data };
1889 },1837 ty.decayed = b.specifier == .decayed_variable_len_array;
1890 .decayed_variable_len_array => |data| {
1891 ty.specifier = .decayed_variable_len_array;
1892 ty.data = .{ .expr = data };
1893 },1838 },
1894 .@"struct" => |data| {1839 .@"struct" => |data| {
1895 ty.specifier = .@"struct";1840 ty.specifier = .@"struct";
...@@ -1903,25 +1848,20 @@ pub const Builder = struct {...@@ -1903,25 +1848,20 @@ pub const Builder = struct {
1903 ty.specifier = .@"enum";1848 ty.specifier = .@"enum";
1904 ty.data = .{ .@"enum" = data };1849 ty.data = .{ .@"enum" = data };
1905 },1850 },
1906 .typeof_type => |data| {1851 .typeof_type, .decayed_typeof_type => |data| {
1907 ty.specifier = .typeof_type;1852 ty.specifier = .typeof_type;
1908 ty.data = .{ .sub_type = data };1853 ty.data = .{ .sub_type = data };
1854 ty.decayed = b.specifier == .decayed_typeof_type;
1909 },1855 },
1910 .decayed_typeof_type => |data| {1856 .typeof_expr, .decayed_typeof_expr => |data| {
1911 ty.specifier = .decayed_typeof_type;
1912 ty.data = .{ .sub_type = data };
1913 },
1914 .typeof_expr => |data| {
1915 ty.specifier = .typeof_expr;1857 ty.specifier = .typeof_expr;
1916 ty.data = .{ .expr = data };1858 ty.data = .{ .expr = data };
1859 ty.decayed = b.specifier == .decayed_typeof_expr;
1917 },1860 },
1918 .decayed_typeof_expr => |data| {1861 .attributed, .decayed_attributed => |data| {
1919 ty.specifier = .decayed_typeof_expr;
1920 ty.data = .{ .expr = data };
1921 },
1922 .attributed => |data| {
1923 ty.specifier = .attributed;1862 ty.specifier = .attributed;
1924 ty.data = .{ .attributed = data };1863 ty.data = .{ .attributed = data };
1864 ty.decayed = b.specifier == .decayed_attributed;
1925 },1865 },
1926 }1866 }
1927 if (!ty.isReal() and ty.isInt()) {1867 if (!ty.isReal() and ty.isInt()) {
...@@ -2359,30 +2299,47 @@ pub const Builder = struct {...@@ -2359,30 +2299,47 @@ pub const Builder = struct {
2359 .complex_float128 => .complex_float128,2299 .complex_float128 => .complex_float128,
23602300
2361 .pointer => .{ .pointer = ty.data.sub_type },2301 .pointer => .{ .pointer = ty.data.sub_type },
2362 .unspecified_variable_len_array => .{ .unspecified_variable_len_array = ty.data.sub_type },2302 .unspecified_variable_len_array => if (ty.isDecayed())
2363 .decayed_unspecified_variable_len_array => .{ .decayed_unspecified_variable_len_array = ty.data.sub_type },2303 .{ .decayed_unspecified_variable_len_array = ty.data.sub_type }
2304 else
2305 .{ .unspecified_variable_len_array = ty.data.sub_type },
2364 .func => .{ .func = ty.data.func },2306 .func => .{ .func = ty.data.func },
2365 .var_args_func => .{ .var_args_func = ty.data.func },2307 .var_args_func => .{ .var_args_func = ty.data.func },
2366 .old_style_func => .{ .old_style_func = ty.data.func },2308 .old_style_func => .{ .old_style_func = ty.data.func },
2367 .array => .{ .array = ty.data.array },2309 .array => if (ty.isDecayed())
2368 .decayed_array => .{ .decayed_array = ty.data.array },2310 .{ .decayed_array = ty.data.array }
2369 .static_array => .{ .static_array = ty.data.array },2311 else
2370 .decayed_static_array => .{ .decayed_static_array = ty.data.array },2312 .{ .array = ty.data.array },
2371 .incomplete_array => .{ .incomplete_array = ty.data.array },2313 .static_array => if (ty.isDecayed())
2372 .decayed_incomplete_array => .{ .decayed_incomplete_array = ty.data.array },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 .vector => .{ .vector = ty.data.array },2321 .vector => .{ .vector = ty.data.array },
2374 .variable_len_array => .{ .variable_len_array = ty.data.expr },2322 .variable_len_array => if (ty.isDecayed())
2375 .decayed_variable_len_array => .{ .decayed_variable_len_array = ty.data.expr },2323 .{ .decayed_variable_len_array = ty.data.expr }
2324 else
2325 .{ .variable_len_array = ty.data.expr },
2376 .@"struct" => .{ .@"struct" = ty.data.record },2326 .@"struct" => .{ .@"struct" = ty.data.record },
2377 .@"union" => .{ .@"union" = ty.data.record },2327 .@"union" => .{ .@"union" = ty.data.record },
2378 .@"enum" => .{ .@"enum" = ty.data.@"enum" },2328 .@"enum" => .{ .@"enum" = ty.data.@"enum" },
23792329
2380 .typeof_type => .{ .typeof_type = ty.data.sub_type },2330 .typeof_type => if (ty.isDecayed())
2381 .decayed_typeof_type => .{ .decayed_typeof_type = ty.data.sub_type },2331 .{ .decayed_typeof_type = ty.data.sub_type }
2382 .typeof_expr => .{ .typeof_expr = ty.data.expr },2332 else
2383 .decayed_typeof_expr => .{ .decayed_typeof_expr = ty.data.expr },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 },
23842338
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 else => unreachable,2343 else => unreachable,
2387 };2344 };
2388 }2345 }
...@@ -2472,24 +2429,17 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts...@@ -2472,24 +2429,17 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts
2472 try w.writeAll(")");2429 try w.writeAll(")");
2473 return true;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 switch (ty.specifier) {2441 switch (ty.specifier) {
2476 .pointer,2442 .pointer => unreachable,
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 },
2493 .func, .var_args_func, .old_style_func => {2443 .func, .var_args_func, .old_style_func => {
2494 const ret_ty = ty.data.func.return_type;2444 const ret_ty = ty.data.func.return_type;
2495 const simple = try ret_ty.printPrologue(mapper, langopts, w);2445 const simple = try ret_ty.printPrologue(mapper, langopts, w);
...@@ -2541,20 +2491,14 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts...@@ -2541,20 +2491,14 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts
25412491
2542fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {2492fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
2543 if (ty.qual.atomic) return;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 switch (ty.specifier) {2500 switch (ty.specifier) {
2545 .pointer,2501 .pointer => unreachable, // handled above
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 },
2558 .func, .var_args_func, .old_style_func => {2502 .func, .var_args_func, .old_style_func => {
2559 try w.writeByte('(');2503 try w.writeByte('(');
2560 for (ty.data.func.params, 0..) |param, i| {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,10 +2581,10 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w:
2637 try w.writeAll(") ");2581 try w.writeAll(") ");
2638 try ty.data.func.return_type.dump(mapper, langopts, w);2582 try ty.data.func.return_type.dump(mapper, langopts, w);
2639 },2583 },
2640 .array, .static_array, .decayed_array, .decayed_static_array => {2584 .array, .static_array => {
2641 if (ty.specifier == .decayed_array or ty.specifier == .decayed_static_array) try w.writeAll("*d");2585 if (ty.isDecayed()) try w.writeAll("*d");
2642 try w.writeByte('[');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 try w.print("{d}]", .{ty.data.array.len});2588 try w.print("{d}]", .{ty.data.array.len});
2645 try ty.data.array.elem.dump(mapper, langopts, w);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,8 +2593,8 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w:
2649 try ty.data.array.elem.dump(mapper, langopts, w);2593 try ty.data.array.elem.dump(mapper, langopts, w);
2650 try w.writeAll(")");2594 try w.writeAll(")");
2651 },2595 },
2652 .incomplete_array, .decayed_incomplete_array => {2596 .incomplete_array => {
2653 if (ty.specifier == .decayed_incomplete_array) try w.writeAll("*d");2597 if (ty.isDecayed()) try w.writeAll("*d");
2654 try w.writeAll("[]");2598 try w.writeAll("[]");
2655 try ty.data.array.elem.dump(mapper, langopts, w);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,27 +2616,28 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w:
2672 try w.print("union {s}", .{mapper.lookup(ty.data.record.name)});2616 try w.print("union {s}", .{mapper.lookup(ty.data.record.name)});
2673 if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);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 => {2619 .unspecified_variable_len_array => {
2676 if (ty.specifier == .decayed_unspecified_variable_len_array) try w.writeAll("*d");2620 if (ty.isDecayed()) try w.writeAll("*d");
2677 try w.writeAll("[*]");2621 try w.writeAll("[*]");
2678 try ty.data.sub_type.dump(mapper, langopts, w);2622 try ty.data.sub_type.dump(mapper, langopts, w);
2679 },2623 },
2680 .variable_len_array, .decayed_variable_len_array => {2624 .variable_len_array => {
2681 if (ty.specifier == .decayed_variable_len_array) try w.writeAll("*d");2625 if (ty.isDecayed()) try w.writeAll("*d");
2682 try w.writeAll("[<expr>]");2626 try w.writeAll("[<expr>]");
2683 try ty.data.expr.ty.dump(mapper, langopts, w);2627 try ty.data.expr.ty.dump(mapper, langopts, w);
2684 },2628 },
2685 .typeof_type, .decayed_typeof_type => {2629 .typeof_type => {
2686 try w.writeAll("typeof(");2630 try w.writeAll("typeof(");
2687 try ty.data.sub_type.dump(mapper, langopts, w);2631 try ty.data.sub_type.dump(mapper, langopts, w);
2688 try w.writeAll(")");2632 try w.writeAll(")");
2689 },2633 },
2690 .typeof_expr, .decayed_typeof_expr => {2634 .typeof_expr => {
2691 try w.writeAll("typeof(<expr>: ");2635 try w.writeAll("typeof(<expr>: ");
2692 try ty.data.expr.ty.dump(mapper, langopts, w);2636 try ty.data.expr.ty.dump(mapper, langopts, w);
2693 try w.writeAll(")");2637 try w.writeAll(")");
2694 },2638 },
2695 .attributed => {2639 .attributed => {
2640 if (ty.isDecayed()) try w.writeAll("*d:");
2696 try w.writeAll("attributed(");2641 try w.writeAll("attributed(");
2697 try ty.data.attributed.base.dump(mapper, langopts, w);2642 try ty.data.attributed.base.dump(mapper, langopts, w);
2698 try w.writeAll(")");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,7 +215,7 @@ pub fn intCast(v: *Value, dest_ty: Type, comp: *Compilation) !void {
215215
216 const limbs = try comp.gpa.alloc(216 const limbs = try comp.gpa.alloc(
217 std.math.big.Limb,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 defer comp.gpa.free(limbs);220 defer comp.gpa.free(limbs);
221 var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined };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 @@
1const std = @import("std");
2const mem = std.mem;
3
4pub 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
56pub 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,7 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const LangOpts = @import("LangOpts.zig");2const LangOpts = @import("LangOpts.zig");
3const Type = @import("Type.zig");3const Type = @import("Type.zig");
4const llvm = @import("root").codegen.llvm;
5const TargetSet = @import("Builtins/Properties.zig").TargetSet;4const TargetSet = @import("Builtins/Properties.zig").TargetSet;
65
7/// intmax_t for this target6/// intmax_t for this target