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
1700817008 .param_str = "w*w*wC*z"
1700917009 .header = .wchar
1701017010 .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 {
408408 \\
409409 );
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
411422 // types
412423 if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
413424 try w.writeAll("#define __CHAR_BIT__ 8\n");
......@@ -445,6 +456,10 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void {
445456 try comp.generateSizeofType(w, "__SIZEOF_WCHAR_T__", comp.types.wchar);
446457 // 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
448463 // various int types
449464 const mapper = comp.string_interner.getSlowTypeMapper();
450465 try generateTypeMacro(w, mapper, "__INTPTR_TYPE__", comp.types.intptr, comp.langopts);
......@@ -461,6 +476,7 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void {
461476 try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar, comp.langopts);
462477
463478 try comp.generateExactWidthTypes(w, mapper);
479 try comp.generateFastAndLeastWidthTypes(w, mapper);
464480
465481 if (target_util.FPSemantics.halfPrecisionType(comp.target)) |half| {
466482 try generateFloatMacros(w, "FLT16", half, "F16");
......@@ -497,10 +513,11 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi
497513 );
498514 }
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
500519 // standard macros
501520 try buf.appendSlice(
502 \\#define __STDC__ 1
503 \\#define __STDC_HOSTED__ 1
504521 \\#define __STDC_NO_ATOMICS__ 1
505522 \\#define __STDC_NO_COMPLEX__ 1
506523 \\#define __STDC_NO_THREADS__ 1
......@@ -678,6 +695,14 @@ fn generateBuiltinTypes(comp: *Compilation) !void {
678695
679696/// Smallest integer type with at least N bits
680697fn 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 }
681706 const candidates = switch (signedness) {
682707 .signed => &[_]Type.Specifier{ .schar, .short, .int, .long, .long_long },
683708 .unsigned => &[_]Type.Specifier{ .uchar, .ushort, .uint, .ulong, .ulong_long },
......@@ -693,6 +718,52 @@ fn intSize(comp: *const Compilation, specifier: Type.Specifier) u64 {
693718 return ty.sizeof(comp).?;
694719}
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
696767fn generateExactWidthTypes(comp: *const Compilation, w: anytype, mapper: StrInt.TypeMapper) !void {
697768 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 {
236236 try d.addExtra(.{}, .{
237237 .tag = .unknown_warning,
238238 .extra = .{ .str = name },
239 }, &.{});
239 }, &.{}, true);
240240}
241241
242242pub fn init(gpa: Allocator) Diagnostics {
......@@ -251,7 +251,7 @@ pub fn deinit(d: *Diagnostics) void {
251251}
252252
253253pub 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);
255255}
256256
257257pub fn addExtra(
......@@ -259,6 +259,7 @@ pub fn addExtra(
259259 langopts: LangOpts,
260260 msg: Message,
261261 expansion_locs: []const Source.Location,
262 note_msg_loc: bool,
262263) Compilation.Error!void {
263264 const kind = d.tagKind(msg.tag, langopts);
264265 if (kind == .off) return;
......@@ -301,7 +302,7 @@ pub fn addExtra(
301302 }
302303 }
303304
304 d.list.appendAssumeCapacity(.{
305 if (note_msg_loc) d.list.appendAssumeCapacity(.{
305306 .tag = .expanded_from_here,
306307 .kind = .note,
307308 .loc = msg.loc,
deps/aro/aro/Driver.zig+16
......@@ -98,8 +98,10 @@ pub const usage =
9898 \\ -fno-declspec Disable support for __declspec attributes
9999 \\ -ffp-eval-method=[source|double|extended]
100100 \\ Evaluation method to use for floating-point arithmetic
101 \\ -ffreestanding Compilation in a freestanding environment
101102 \\ -fgnu-inline-asm Enable GNU style inline asm (default: enabled)
102103 \\ -fno-gnu-inline-asm Disable GNU style inline asm
104 \\ -fhosted Compilation in a hosted environment
103105 \\ -fms-extensions Enable support for Microsoft extensions
104106 \\ -fno-ms-extensions Disable support for Microsoft extensions
105107 \\ -fdollars-in-identifiers
......@@ -177,6 +179,7 @@ pub fn parseArgs(
177179) !bool {
178180 var i: usize = 1;
179181 var comment_arg: []const u8 = "";
182 var hosted: ?bool = null;
180183 while (i < args.len) : (i += 1) {
181184 const arg = args[i];
182185 if (mem.startsWith(u8, arg, "-") and arg.len > 1) {
......@@ -277,6 +280,10 @@ pub fn parseArgs(
277280 d.comp.langopts.declspec_attrs = true;
278281 } else if (mem.eql(u8, arg, "-fno-declspec")) {
279282 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;
280287 } else if (mem.eql(u8, arg, "-fms-extensions")) {
281288 d.comp.langopts.enableMSExtensions();
282289 } else if (mem.eql(u8, arg, "-fno-ms-extensions")) {
......@@ -440,6 +447,15 @@ pub fn parseArgs(
440447 if (d.comp.langopts.preserve_comments and !d.only_preprocess) {
441448 return d.fatal("invalid argument '{s}' only allowed with '-E'", .{comment_arg});
442449 }
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 }
443459 return false;
444460}
445461
deps/aro/aro/Driver/Filesystem.zig+10-10
......@@ -121,7 +121,7 @@ pub const Filesystem = union(enum) {
121121 base: []const u8,
122122 i: usize = 0,
123123
124 fn next(self: *@This()) !?std.fs.IterableDir.Entry {
124 fn next(self: *@This()) !?std.fs.Dir.Entry {
125125 while (self.i < self.entries.len) {
126126 const entry = self.entries[self.i];
127127 self.i += 1;
......@@ -130,7 +130,7 @@ pub const Filesystem = union(enum) {
130130 const remaining = entry.path[self.base.len + 1 ..];
131131 if (std.mem.indexOfScalar(u8, remaining, std.fs.path.sep) != null) continue;
132132 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;
134134 return .{ .name = remaining, .kind = kind };
135135 }
136136 }
......@@ -139,18 +139,18 @@ pub const Filesystem = union(enum) {
139139 };
140140 };
141141
142 const IterableDir = union(enum) {
143 dir: std.fs.IterableDir,
142 const Dir = union(enum) {
143 dir: std.fs.Dir,
144144 fake: FakeDir,
145145
146 pub fn iterate(self: IterableDir) Iterator {
146 pub fn iterate(self: Dir) Iterator {
147147 return switch (self) {
148148 .dir => |dir| .{ .iterator = dir.iterate() },
149149 .fake => |fake| .{ .fake = fake.iterate() },
150150 };
151151 }
152152
153 pub fn close(self: *IterableDir) void {
153 pub fn close(self: *Dir) void {
154154 switch (self.*) {
155155 .dir => |*d| d.close(),
156156 .fake => {},
......@@ -159,10 +159,10 @@ pub const Filesystem = union(enum) {
159159 };
160160
161161 const Iterator = union(enum) {
162 iterator: std.fs.IterableDir.Iterator,
162 iterator: std.fs.Dir.Iterator,
163163 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 {
166166 return switch (self.*) {
167167 .iterator => |*it| it.next(),
168168 .fake => |*it| it.next(),
......@@ -221,9 +221,9 @@ pub const Filesystem = union(enum) {
221221 };
222222 }
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 {
225225 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 }) },
227227 .fake => |entries| .{ .fake = .{ .entries = entries, .path = dir_name } },
228228 };
229229 }
deps/aro/aro/Driver/GCCDetector.zig+1-1
......@@ -602,7 +602,7 @@ fn scanLibDirForGCCTriple(
602602 const lib_suffix = std.fs.path.join(suffix_buf_fib.allocator(), &.{ base, candidate_triple }) catch continue;
603603
604604 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;
606606 defer parent_dir.close();
607607
608608 var it = parent_dir.iterate();
deps/aro/aro/Parser.zig+79-32
......@@ -9,6 +9,8 @@ const Tokenizer = @import("Tokenizer.zig");
99const Preprocessor = @import("Preprocessor.zig");
1010const Tree = @import("Tree.zig");
1111const Token = Tree.Token;
12const NumberPrefix = Token.NumberPrefix;
13const NumberSuffix = Token.NumberSuffix;
1214const TokenIndex = Tree.TokenIndex;
1315const NodeIndex = Tree.NodeIndex;
1416const Type = @import("Type.zig");
......@@ -24,9 +26,6 @@ const Symbol = SymbolStack.Symbol;
2426const record_layout = @import("record_layout.zig");
2527const StrInt = @import("StringInterner.zig");
2628const StringId = StrInt.StringId;
27const number_affixes = @import("number_affixes.zig");
28const NumberPrefix = number_affixes.Prefix;
29const NumberSuffix = number_affixes.Suffix;
3029const Builtins = @import("Builtins.zig");
3130const Builtin = Builtins.Builtin;
3231const target_util = @import("target.zig");
......@@ -323,7 +322,7 @@ fn expectIdentifier(p: *Parser) Error!TokenIndex {
323322 return p.errExpectedToken(.identifier, actual);
324323 }
325324
326 return (try p.eatIdentifier()) orelse unreachable;
325 return (try p.eatIdentifier()) orelse error.ParsingFailed;
327326}
328327
329328fn eatToken(p: *Parser, id: Token.Id) ?TokenIndex {
......@@ -347,7 +346,7 @@ pub fn tokSlice(p: *Parser, tok: TokenIndex) []const u8 {
347346 const loc = p.pp.tokens.items(.loc)[tok];
348347 var tmp_tokenizer = Tokenizer{
349348 .buf = p.comp.getSource(loc.id).buf,
350 .comp = p.comp,
349 .langopts = p.comp.langopts,
351350 .index = loc.byte_offset,
352351 .source = .generated,
353352 };
......@@ -715,6 +714,9 @@ pub fn parse(pp: *Preprocessor) Compilation.Error!Tree {
715714 p.field_attr_buf.deinit();
716715 }
717716
717 try p.syms.pushScope(&p);
718 defer p.syms.popScope();
719
718720 // NodeIndex 0 must be invalid
719721 _ = try p.addNode(.{ .tag = .invalid, .ty = undefined, .data = undefined });
720722
......@@ -1010,7 +1012,7 @@ fn decl(p: *Parser) Error!bool {
10101012 // Collect old style parameter declarations.
10111013 if (init_d.d.old_style_func != null) {
10121014 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;
10141016 base_ty.specifier = .func;
10151017 init_d.d.ty = try base_ty.withAttributes(p.arena, attrs);
10161018
......@@ -1066,7 +1068,7 @@ fn decl(p: *Parser) Error!bool {
10661068 d.ty = try Attribute.applyParameterAttributes(p, d.ty, attr_buf_top_declarator, .alignas_on_param);
10671069
10681070 // bypass redefinition check to avoid duplicate errors
1069 try p.syms.syms.append(p.gpa, .{
1071 try p.syms.define(p.gpa, .{
10701072 .kind = .def,
10711073 .name = interned_name,
10721074 .tok = d.name,
......@@ -1088,7 +1090,7 @@ fn decl(p: *Parser) Error!bool {
10881090 }
10891091
10901092 // bypass redefinition check to avoid duplicate errors
1091 try p.syms.syms.append(p.gpa, .{
1093 try p.syms.define(p.gpa, .{
10921094 .kind = .def,
10931095 .name = param.name,
10941096 .tok = param.name_tok,
......@@ -1428,12 +1430,14 @@ fn typeof(p: *Parser) Error!?Type {
14281430 .data = typeof_expr.ty.data,
14291431 .qual = if (unqual) .{} else typeof_expr.ty.qual.inheritFromTypeof(),
14301432 .specifier = typeof_expr.ty.specifier,
1433 .decayed = typeof_expr.ty.decayed,
14311434 },
14321435 };
14331436
14341437 return Type{
14351438 .data = .{ .expr = inner },
14361439 .specifier = .typeof_expr,
1440 .decayed = typeof_expr.ty.decayed,
14371441 };
14381442}
14391443
......@@ -1814,6 +1818,7 @@ fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize) Error!?
18141818 } else {
18151819 init_d.d.ty.specifier = init_d.initializer.ty.specifier;
18161820 init_d.d.ty.data = init_d.initializer.ty.data;
1821 init_d.d.ty.decayed = init_d.initializer.ty.decayed;
18171822 }
18181823 }
18191824 if (apply_var_attributes) {
......@@ -2105,7 +2110,7 @@ fn recordSpec(p: *Parser) Error!Type {
21052110 .specifier = if (is_struct) .@"struct" else .@"union",
21062111 .data = .{ .record = record_ty },
21072112 }, attr_buf_top, null);
2108 try p.syms.syms.append(p.gpa, .{
2113 try p.syms.define(p.gpa, .{
21092114 .kind = if (is_struct) .@"struct" else .@"union",
21102115 .name = interned_name,
21112116 .tok = ident,
......@@ -2151,10 +2156,8 @@ fn recordSpec(p: *Parser) Error!Type {
21512156
21522157 // declare a symbol for the type
21532158 // We need to replace the symbol's type if it has attributes
2154 var symbol_index: ?usize = null;
21552159 if (maybe_ident != null and !defined) {
2156 symbol_index = p.syms.syms.len;
2157 try p.syms.syms.append(p.gpa, .{
2160 try p.syms.define(p.gpa, .{
21582161 .kind = if (is_struct) .@"struct" else .@"union",
21592162 .name = record_ty.name,
21602163 .tok = maybe_ident.?,
......@@ -2216,8 +2219,11 @@ fn recordSpec(p: *Parser) Error!Type {
22162219 .specifier = if (is_struct) .@"struct" else .@"union",
22172220 .data = .{ .record = record_ty },
22182221 }, attr_buf_top, null);
2219 if (ty.specifier == .attributed and symbol_index != null) {
2220 p.syms.syms.items(.ty)[symbol_index.?] = ty;
2222 if (ty.specifier == .attributed and maybe_ident != null) {
2223 const ident_str = p.tokSlice(maybe_ident.?);
2224 const interned_name = try StrInt.intern(p.comp, ident_str);
2225 const ptr = p.syms.getPtr(interned_name, .tags);
2226 ptr.ty = ty;
22212227 }
22222228
22232229 if (!ty.hasIncompleteSize()) {
......@@ -2474,7 +2480,7 @@ fn enumSpec(p: *Parser) Error!Type {
24742480 .specifier = .@"enum",
24752481 .data = .{ .@"enum" = enum_ty },
24762482 }, attr_buf_top, null);
2477 try p.syms.syms.append(p.gpa, .{
2483 try p.syms.define(p.gpa, .{
24782484 .kind = .@"enum",
24792485 .name = interned_name,
24802486 .tok = ident,
......@@ -2525,7 +2531,6 @@ fn enumSpec(p: *Parser) Error!Type {
25252531 p.enum_buf.items.len = enum_buf_top;
25262532 }
25272533
2528 const sym_stack_top = p.syms.syms.len;
25292534 var e = Enumerator.init(fixed_ty);
25302535 while (try p.enumerator(&e)) |field_and_node| {
25312536 try p.enum_buf.append(field_and_node.field);
......@@ -2551,13 +2556,12 @@ fn enumSpec(p: *Parser) Error!Type {
25512556 const field_nodes = p.list_buf.items[list_buf_top..];
25522557
25532558 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
25572559 for (enum_fields, 0..) |*field, i| {
25582560 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 };
25612565 const dest_ty = if (p.comp.fixedEnumTagSpecifier()) |some|
25622566 Type{ .specifier = some }
25632567 else if (try res.intFitsInType(p, Type.int))
......@@ -2567,8 +2571,9 @@ fn enumSpec(p: *Parser) Error!Type {
25672571 else
25682572 continue;
25692573
2570 try vals[i].intCast(dest_ty, p.comp);
2571 types[i] = dest_ty;
2574 const symbol = p.syms.getPtr(field.name, .vars);
2575 try symbol.val.intCast(dest_ty, p.comp);
2576 symbol.ty = dest_ty;
25722577 p.nodes.items(.ty)[@intFromEnum(field_nodes[i])] = dest_ty;
25732578 field.ty = dest_ty;
25742579 res.ty = dest_ty;
......@@ -2585,7 +2590,7 @@ fn enumSpec(p: *Parser) Error!Type {
25852590
25862591 // declare a symbol for the type
25872592 if (maybe_ident != null and !defined) {
2588 try p.syms.syms.append(p.gpa, .{
2593 try p.syms.define(p.gpa, .{
25892594 .kind = .@"enum",
25902595 .name = enum_ty.name,
25912596 .ty = ty,
......@@ -2885,7 +2890,7 @@ fn declarator(
28852890 try res.ty.combine(outer);
28862891 try res.ty.validateCombinedType(p, suffix_start);
28872892 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;
28892894 return res;
28902895 }
28912896
......@@ -4376,7 +4381,7 @@ fn stmt(p: *Parser) Error!NodeIndex {
43764381/// | keyword_default ':' stmt
43774382fn labeledStmt(p: *Parser) Error!?NodeIndex {
43784383 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();
43804385 const str = p.tokSlice(name_tok);
43814386 if (p.findLabel(str)) |some| {
43824387 try p.errStr(.duplicate_label, name_tok, str);
......@@ -4814,10 +4819,23 @@ const CallExpr = union(enum) {
48144819 /// of arguments, `paramCountOverride` is used to tell us how many arguments we should actually expect to see for
48154820 /// these custom-typechecked functions.
48164821 fn paramCountOverride(self: CallExpr) ?u32 {
4822 @setEvalBranchQuota(10_000);
48174823 return switch (self) {
48184824 .standard => null,
48194825 .builtin => |builtin| switch (builtin.tag) {
48204826 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,
48214839 else => null,
48224840 },
48234841 };
......@@ -4827,10 +4845,25 @@ const CallExpr = union(enum) {
48274845 return switch (self) {
48284846 .standard => callable_ty.returnType(),
48294847 .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 },
48304859 Builtin.tagFromName("__builtin_complex").? => {
4860 if (p.list_buf.items.len < 1) return Type.invalid; // not enough arguments; already an error
48314861 const last_param = p.list_buf.items[p.list_buf.items.len - 1];
48324862 return p.nodes.items(.ty)[@intFromEnum(last_param)].makeComplex();
48334863 },
4864 Builtin.tagFromName("__atomic_compare_exchange").?,
4865 Builtin.tagFromName("__atomic_compare_exchange_n").?,
4866 => .{ .specifier = .bool },
48344867 else => callable_ty.returnType(),
48354868 },
48364869 };
......@@ -7458,7 +7491,7 @@ fn primaryExpr(p: *Parser) Error!Result {
74587491 }
74597492 switch (p.tok_ids[p.tok_i]) {
74607493 .identifier, .extended_identifier => {
7461 const name_tok = p.expectIdentifier() catch unreachable;
7494 const name_tok = try p.expectIdentifier();
74627495 const name = p.tokSlice(name_tok);
74637496 const interned_name = try StrInt.intern(p.comp, name);
74647497 if (p.syms.findSymbol(interned_name)) |sym| {
......@@ -7938,6 +7971,8 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
79387971 .F, .IF => .float,
79397972 .F16 => .float16,
79407973 .L, .IL => .long_double,
7974 .W, .IW => .float80,
7975 .Q, .IQ, .F128, .IF128 => .float128,
79417976 else => unreachable,
79427977 } };
79437978 const val = try Value.intern(p.comp, key: {
......@@ -7946,7 +7981,7 @@ fn parseFloat(p: *Parser, buf: []const u8, suffix: NumberSuffix) !Result {
79467981 const strings_top = p.strings.items.len;
79477982 defer p.strings.items.len = strings_top;
79487983 for (buf) |c| {
7949 if (c != '_') p.strings.appendAssumeCapacity(c);
7984 if (c != '\'') p.strings.appendAssumeCapacity(c);
79507985 }
79517986
79527987 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 {
79718006 .I => .complex_double,
79728007 .IF => .complex_float,
79738008 .IL => .complex_long_double,
8009 .IW => .complex_float80,
8010 .IQ, .IF128 => .complex_float128,
79748011 else => unreachable,
79758012 } };
79768013 res.val = .{}; // TODO add complex values
......@@ -8123,11 +8160,21 @@ fn bitInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok_i: To
81238160 var managed = try big.int.Managed.init(p.gpa);
81248161 defer managed.deinit();
81258162
8126 managed.setString(base, buf) catch |e| switch (e) {
8127 error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16
8128 error.InvalidCharacter => unreachable, // digits validated by Tokenizer
8129 else => |er| return er,
8130 };
8163 {
8164 try p.strings.ensureUnusedCapacity(buf.len);
8165
8166 const strings_top = p.strings.items.len;
8167 defer p.strings.items.len = strings_top;
8168 for (buf) |c| {
8169 if (c != '\'') p.strings.appendAssumeCapacity(c);
8170 }
8171
8172 managed.setString(base, p.strings.items[strings_top..]) catch |e| switch (e) {
8173 error.InvalidBase => unreachable, // `base` is one of 2, 8, 10, 16
8174 error.InvalidCharacter => unreachable, // digits validated by Tokenizer
8175 else => |er| return er,
8176 };
8177 }
81318178 const c = managed.toConst();
81328179 const bits_needed: std.math.IntFittingRange(0, Compilation.bit_int_max_bits) = blk: {
81338180 // 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 {
315315fn findIncludeGuard(pp: *Preprocessor, source: Source) ?[]const u8 {
316316 var tokenizer = Tokenizer{
317317 .buf = source.buf,
318 .comp = pp.comp,
318 .langopts = pp.comp.langopts,
319319 .source = source.id,
320320 };
321321 var hash = tokenizer.nextNoWS();
......@@ -334,7 +334,7 @@ fn preprocessExtra(pp: *Preprocessor, source: Source) MacroError!Token {
334334 pp.preprocess_count += 1;
335335 var tokenizer = Tokenizer{
336336 .buf = source.buf,
337 .comp = pp.comp,
337 .langopts = pp.comp.langopts,
338338 .source = source.id,
339339 };
340340
......@@ -747,6 +747,17 @@ fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anyty
747747 return error.FatalError;
748748}
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
750761fn verboseLog(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) void {
751762 const source = pp.comp.getSource(raw.source);
752763 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
11851196 try pp.comp.generated_buf.appendSlice(pp.gpa, pp.char_buf.items);
11861197 var tmp_tokenizer = Tokenizer{
11871198 .buf = pp.comp.generated_buf.items,
1188 .comp = pp.comp,
1199 .langopts = pp.comp.langopts,
11891200 .index = @intCast(start),
11901201 .source = .generated,
11911202 .line = pp.generated_line,
......@@ -1864,7 +1875,7 @@ fn expandVaOpt(
18641875 .buf = source.buf,
18651876 .index = raw.start,
18661877 .source = raw.source,
1867 .comp = pp.comp,
1878 .langopts = pp.comp.langopts,
18681879 .line = raw.line,
18691880 };
18701881 while (tokenizer.index < raw.end) {
......@@ -2282,11 +2293,11 @@ fn expandMacro(pp: *Preprocessor, tokenizer: *Tokenizer, raw: RawToken) MacroErr
22822293
22832294fn expandedSliceExtra(pp: *const Preprocessor, tok: Token, macro_ws_handling: enum { single_macro_ws, preserve_macro_ws }) []const u8 {
22842295 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;
22862297 }
22872298 var tmp_tokenizer = Tokenizer{
22882299 .buf = pp.comp.getSource(tok.loc.id).buf,
2289 .comp = pp.comp,
2300 .langopts = pp.comp.langopts,
22902301 .index = tok.loc.byte_offset,
22912302 .source = .generated,
22922303 };
......@@ -2340,7 +2351,7 @@ fn pasteTokens(pp: *Preprocessor, lhs_toks: *ExpandBuf, rhs_toks: []const Token)
23402351 // Try to tokenize the result.
23412352 var tmp_tokenizer = Tokenizer{
23422353 .buf = pp.comp.generated_buf.items,
2343 .comp = pp.comp,
2354 .langopts = pp.comp.langopts,
23442355 .index = @intCast(start),
23452356 .source = .generated,
23462357 };
......@@ -2703,6 +2714,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
27032714 error.InvalidInclude => return,
27042715 else => |e| return e,
27052716 };
2717 defer Token.free(filename_tok.expansion_locs, pp.gpa);
27062718
27072719 // Check for empty filename.
27082720 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);
......@@ -2836,7 +2848,7 @@ fn embed(pp: *Preprocessor, tokenizer: *Tokenizer) MacroError!void {
28362848 }
28372849
28382850 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);
28402852 defer pp.comp.gpa.free(embed_bytes);
28412853
28422854 try Range.expand(prefix, pp, tokenizer);
......@@ -2984,8 +2996,6 @@ fn findIncludeFilenameToken(
29842996 tokenizer: *Tokenizer,
29852997 trailing_token_behavior: enum { ignore_trailing_tokens, expect_nl_eof },
29862998) !Token {
2987 const start = pp.tokens.len;
2988 defer pp.tokens.len = start;
29892999 var first = first_token;
29903000
29913001 if (first.id == .angle_bracket_left) to_end: {
......@@ -3008,35 +3018,60 @@ fn findIncludeFilenameToken(
30083018 }, &.{});
30093019 try pp.err(first, .header_str_match);
30103020 }
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.
3015 const filename_tok = pp.tokens.get(start);
3016 switch (filename_tok.id) {
3017 .string_literal, .macro_string => {},
3018 else => {
3019 try pp.err(first, .expected_filename);
3020 try pp.expectNl(tokenizer);
3021 return error.InvalidInclude;
3022 const source_tok = tokFromRaw(first);
3023 const filename_tok, const expanded_trailing = switch (source_tok.id) {
3024 .string_literal, .macro_string => .{ source_tok, false },
3025 else => expanded: {
3026 // Try to expand if the argument is a macro.
3027 pp.top_expansion_buf.items.len = 0;
3028 defer for (pp.top_expansion_buf.items) |tok| Token.free(tok.expansion_locs, pp.gpa);
3029 try pp.top_expansion_buf.append(source_tok);
3030 pp.expansion_source_loc = source_tok.loc;
3031
3032 try pp.expandMacroExhaustive(tokenizer, &pp.top_expansion_buf, 0, 1, true, .non_expr);
3033 var trailing_toks: []const Token = &.{};
3034 const include_str = (try pp.reconstructIncludeString(pp.top_expansion_buf.items, &trailing_toks)) orelse {
3035 try pp.err(first, .expected_filename);
3036 try pp.expectNl(tokenizer);
3037 return error.InvalidInclude;
3038 };
3039 const start = pp.comp.generated_buf.items.len;
3040 try pp.comp.generated_buf.appendSlice(pp.gpa, include_str);
3041
3042 break :expanded .{ try pp.makeGeneratedToken(start, switch (include_str[0]) {
3043 '"' => .string_literal,
3044 '<' => .macro_string,
3045 else => unreachable,
3046 }, pp.top_expansion_buf.items[0]), trailing_toks.len != 0 };
30223047 },
3023 }
3048 };
3049
30243050 switch (trailing_token_behavior) {
30253051 .expect_nl_eof => {
30263052 // Error on extra tokens.
30273053 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) {
30293055 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);
30313060 }
30323061 },
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 },
30343068 }
30353069 return filename_tok;
30363070}
30373071
30383072fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken, which: Compilation.WhichInclude) !Source {
30393073 const filename_tok = try pp.findIncludeFilenameToken(first, tokenizer, .expect_nl_eof);
3074 defer Token.free(filename_tok.expansion_locs, pp.gpa);
30403075
30413076 // Check for empty filename.
30423077 const tok_slice = pp.expandedSliceExtra(filename_tok, .single_macro_ws);
......@@ -3054,7 +3089,7 @@ fn findIncludeSource(pp: *Preprocessor, tokenizer: *Tokenizer, first: RawToken,
30543089 };
30553090
30563091 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);
30583093}
30593094
30603095fn printLinemarker(
deps/aro/aro/SymbolStack.zig+201-184
......@@ -11,6 +11,8 @@ const Parser = @import("Parser.zig");
1111const Value = @import("Value.zig");
1212const StringId = @import("StringInterner.zig").StringId;
1313
14const SymbolStack = @This();
15
1416pub const Symbol = struct {
1517 name: StringId,
1618 ty: Type,
......@@ -31,72 +33,74 @@ pub const Kind = enum {
3133 constexpr,
3234};
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) = .{},
37scopes: std.ArrayListUnmanaged(u32) = .{},
41const Scope = struct {
42 vars: std.AutoHashMapUnmanaged(StringId, Symbol) = .{},
43 tags: std.AutoHashMapUnmanaged(StringId, Symbol) = .{},
44
45 fn deinit(self: *Scope, allocator: Allocator) void {
46 self.vars.deinit(allocator);
47 self.tags.deinit(allocator);
48 }
49
50 fn clearRetainingCapacity(self: *Scope) void {
51 self.vars.clearRetainingCapacity();
52 self.tags.clearRetainingCapacity();
53 }
54};
3855
3956pub 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 }
4161 s.scopes.deinit(gpa);
4262 s.* = undefined;
4363}
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
5065pub 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 }
5273}
5374
5475pub fn popScope(s: *SymbolStack) void {
55 s.syms.len = s.scopes.pop();
76 s.active_len -= 1;
5677}
5778
5879pub fn findTypedef(s: *SymbolStack, p: *Parser, name: StringId, name_tok: TokenIndex, no_type_yet: bool) !?Symbol {
59 const kinds = s.syms.items(.kind);
60 const names = s.syms.items(.name);
61 var i = s.syms.len;
62 while (i > 0) {
63 i -= 1;
64 switch (kinds[i]) {
65 .typedef => if (names[i] == name) return s.syms.get(i),
66 .@"struct" => if (names[i] == name) {
67 if (no_type_yet) return null;
68 try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok));
69 return s.syms.get(i);
70 },
71 .@"union" => if (names[i] == name) {
72 if (no_type_yet) return null;
73 try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok));
74 return s.syms.get(i);
75 },
76 .@"enum" => if (names[i] == name) {
77 if (no_type_yet) return null;
78 try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok));
79 return s.syms.get(i);
80 },
81 .def, .decl, .constexpr => if (names[i] == name) return null,
82 else => {},
83 }
80 const prev = s.lookup(name, .vars) orelse s.lookup(name, .tags) orelse return null;
81 switch (prev.kind) {
82 .typedef => return prev,
83 .@"struct" => {
84 if (no_type_yet) return null;
85 try p.errStr(.must_use_struct, name_tok, p.tokSlice(name_tok));
86 return prev;
87 },
88 .@"union" => {
89 if (no_type_yet) return null;
90 try p.errStr(.must_use_union, name_tok, p.tokSlice(name_tok));
91 return prev;
92 },
93 .@"enum" => {
94 if (no_type_yet) return null;
95 try p.errStr(.must_use_enum, name_tok, p.tokSlice(name_tok));
96 return prev;
97 },
98 else => return null,
8499 }
85 return null;
86100}
87101
88102pub fn findSymbol(s: *SymbolStack, name: StringId) ?Symbol {
89 const kinds = s.syms.items(.kind);
90 const names = s.syms.items(.name);
91 var i = s.syms.len;
92 while (i > 0) {
93 i -= 1;
94 switch (kinds[i]) {
95 .def, .decl, .enumeration, .constexpr => if (names[i] == name) return s.syms.get(i),
96 else => {},
97 }
98 }
99 return null;
103 return s.lookup(name, .vars);
100104}
101105
102106pub fn findTag(
......@@ -107,36 +111,62 @@ pub fn findTag(
107111 name_tok: TokenIndex,
108112 next_tok_id: Token.Id,
109113) !?Symbol {
110 const kinds = s.syms.items(.kind);
111 const names = s.syms.items(.name);
112114 // `tag Name;` should always result in a new type if in a new scope.
113 const end = if (next_tok_id == .semicolon) s.scopeEnd() else 0;
114 var i = s.syms.len;
115 while (i > end) {
115 const prev = (if (next_tok_id == .semicolon) s.get(name, .tags) else s.lookup(name, .tags)) orelse return null;
116 switch (prev.kind) {
117 .@"enum" => if (kind == .keyword_enum) return prev,
118 .@"struct" => if (kind == .keyword_struct) return prev,
119 .@"union" => if (kind == .keyword_union) return prev,
120 else => unreachable,
121 }
122 if (s.get(name, .tags) == null) return null;
123 try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok));
124 try p.errTok(.previous_definition, prev.tok);
125 return null;
126}
127
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) {
116148 i -= 1;
117 switch (kinds[i]) {
118 .@"enum" => if (names[i] == name) {
119 if (kind == .keyword_enum) return s.syms.get(i);
120 break;
121 },
122 .@"struct" => if (names[i] == name) {
123 if (kind == .keyword_struct) return s.syms.get(i);
124 break;
125 },
126 .@"union" => if (names[i] == name) {
127 if (kind == .keyword_union) return s.syms.get(i);
128 break;
129 },
130 else => {},
149 switch (kind) {
150 .vars => if (s.scopes.items[i].vars.get(name)) |sym| return sym,
151 .tags => if (s.scopes.items[i].tags.get(name)) |sym| return sym,
131152 }
132 } else return null;
133
134 if (i < s.scopeEnd()) return null;
135 try p.errStr(.wrong_tag, name_tok, p.tokSlice(name_tok));
136 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
153 }
137154 return null;
138155}
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
140170pub fn defineTypedef(
141171 s: *SymbolStack,
142172 p: *Parser,
......@@ -145,25 +175,22 @@ pub fn defineTypedef(
145175 tok: TokenIndex,
146176 node: NodeIndex,
147177) !void {
148 const kinds = s.syms.items(.kind);
149 const names = s.syms.items(.name);
150 const end = s.scopeEnd();
151 var i = s.syms.len;
152 while (i > end) {
153 i -= 1;
154 switch (kinds[i]) {
155 .typedef => if (names[i] == name) {
156 const prev_ty = s.syms.items(.ty)[i];
157 if (ty.eql(prev_ty, p.comp, true)) break;
158 try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev_ty));
159 const previous_tok = s.syms.items(.tok)[i];
160 if (previous_tok != 0) try p.errTok(.previous_definition, previous_tok);
161 break;
178 if (s.get(name, .vars)) |prev| {
179 switch (prev.kind) {
180 .typedef => {
181 if (!ty.eql(prev.ty, p.comp, true)) {
182 try p.errStr(.redefinition_of_typedef, tok, try p.typePairStrExtra(ty, " vs ", prev.ty));
183 if (prev.tok != 0) try p.errTok(.previous_definition, prev.tok);
184 }
185 },
186 .enumeration, .decl, .def, .constexpr => {
187 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
188 try p.errTok(.previous_definition, prev.tok);
162189 },
163 else => {},
190 else => unreachable,
164191 }
165192 }
166 try s.syms.append(p.gpa, .{
193 try s.define(p.gpa, .{
167194 .kind = .typedef,
168195 .name = name,
169196 .tok = tok,
......@@ -183,35 +210,31 @@ pub fn defineSymbol(
183210 val: Value,
184211 constexpr: bool,
185212) !void {
186 const kinds = s.syms.items(.kind);
187 const names = s.syms.items(.name);
188 const end = s.scopeEnd();
189 var i = s.syms.len;
190 while (i > end) {
191 i -= 1;
192 switch (kinds[i]) {
193 .enumeration => if (names[i] == name) {
213 if (s.get(name, .vars)) |prev| {
214 switch (prev.kind) {
215 .enumeration => {
194216 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
195 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
196 break;
217 try p.errTok(.previous_definition, prev.tok);
197218 },
198 .decl => if (names[i] == name) {
199 const prev_ty = s.syms.items(.ty)[i];
200 if (!ty.eql(prev_ty, p.comp, true)) {
219 .decl => {
220 if (!ty.eql(prev.ty, p.comp, true)) {
201221 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);
203223 }
204 break;
205224 },
206 .def, .constexpr => if (names[i] == name) {
225 .def, .constexpr => {
207226 try p.errStr(.redefinition, tok, p.tokSlice(tok));
208 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
209 break;
227 try p.errTok(.previous_definition, prev.tok);
210228 },
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,
212234 }
213235 }
214 try s.syms.append(p.gpa, .{
236
237 try s.define(p.gpa, .{
215238 .kind = if (constexpr) .constexpr else .def,
216239 .name = name,
217240 .tok = tok,
......@@ -221,6 +244,15 @@ pub fn defineSymbol(
221244 });
222245}
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
224256pub fn declareSymbol(
225257 s: *SymbolStack,
226258 p: *Parser,
......@@ -229,39 +261,34 @@ pub fn declareSymbol(
229261 tok: TokenIndex,
230262 node: NodeIndex,
231263) !void {
232 const kinds = s.syms.items(.kind);
233 const names = s.syms.items(.name);
234 const end = s.scopeEnd();
235 var i = s.syms.len;
236 while (i > end) {
237 i -= 1;
238 switch (kinds[i]) {
239 .enumeration => if (names[i] == name) {
264 if (s.get(name, .vars)) |prev| {
265 switch (prev.kind) {
266 .enumeration => {
240267 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
241 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
242 break;
268 try p.errTok(.previous_definition, prev.tok);
243269 },
244 .decl => if (names[i] == name) {
245 const prev_ty = s.syms.items(.ty)[i];
246 if (!ty.eql(prev_ty, p.comp, true)) {
270 .decl => {
271 if (!ty.eql(prev.ty, p.comp, true)) {
247272 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);
249274 }
250 break;
251275 },
252 .def, .constexpr => if (names[i] == name) {
253 const prev_ty = s.syms.items(.ty)[i];
254 if (!ty.eql(prev_ty, p.comp, true)) {
276 .def, .constexpr => {
277 if (!ty.eql(prev.ty, p.comp, true)) {
255278 try p.errStr(.redefinition_incompatible, tok, p.tokSlice(tok));
256 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
257 break;
279 try p.errTok(.previous_definition, prev.tok);
280 } else {
281 return;
258282 }
259 return;
260283 },
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,
262289 }
263290 }
264 try s.syms.append(p.gpa, .{
291 try s.define(p.gpa, .{
265292 .kind = .decl,
266293 .name = name,
267294 .tok = tok,
......@@ -272,25 +299,23 @@ pub fn declareSymbol(
272299}
273300
274301pub fn defineParam(s: *SymbolStack, p: *Parser, name: StringId, ty: Type, tok: TokenIndex) !void {
275 const kinds = s.syms.items(.kind);
276 const names = s.syms.items(.name);
277 const end = s.scopeEnd();
278 var i = s.syms.len;
279 while (i > end) {
280 i -= 1;
281 switch (kinds[i]) {
282 .enumeration, .decl, .def, .constexpr => if (names[i] == name) {
302 if (s.get(name, .vars)) |prev| {
303 switch (prev.kind) {
304 .enumeration, .decl, .def, .constexpr => {
283305 try p.errStr(.redefinition_of_parameter, tok, p.tokSlice(tok));
284 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
285 break;
306 try p.errTok(.previous_definition, prev.tok);
307 },
308 .typedef => {
309 try p.errStr(.redefinition_different_sym, tok, p.tokSlice(tok));
310 try p.errTok(.previous_definition, prev.tok);
286311 },
287 else => {},
312 else => unreachable,
288313 }
289314 }
290315 if (ty.is(.fp16) and !p.comp.hasHalfPrecisionFloatABI()) {
291316 try p.errStr(.suggest_pointer_for_invalid_fp16, tok, "parameters");
292317 }
293 try s.syms.append(p.gpa, .{
318 try s.define(p.gpa, .{
294319 .kind = .def,
295320 .name = name,
296321 .tok = tok,
......@@ -306,35 +331,28 @@ pub fn defineTag(
306331 kind: Token.Id,
307332 tok: TokenIndex,
308333) !?Symbol {
309 const kinds = s.syms.items(.kind);
310 const names = s.syms.items(.name);
311 const end = s.scopeEnd();
312 var i = s.syms.len;
313 while (i > end) {
314 i -= 1;
315 switch (kinds[i]) {
316 .@"enum" => if (names[i] == name) {
317 if (kind == .keyword_enum) return s.syms.get(i);
318 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
319 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
320 return null;
321 },
322 .@"struct" => if (names[i] == name) {
323 if (kind == .keyword_struct) return s.syms.get(i);
324 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
325 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
326 return null;
327 },
328 .@"union" => if (names[i] == name) {
329 if (kind == .keyword_union) return s.syms.get(i);
330 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
331 try p.errTok(.previous_definition, s.syms.items(.tok)[i]);
332 return null;
333 },
334 else => {},
335 }
334 const prev = s.get(name, .tags) orelse return null;
335 switch (prev.kind) {
336 .@"enum" => {
337 if (kind == .keyword_enum) return prev;
338 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
339 try p.errTok(.previous_definition, prev.tok);
340 return null;
341 },
342 .@"struct" => {
343 if (kind == .keyword_struct) return prev;
344 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
345 try p.errTok(.previous_definition, prev.tok);
346 return null;
347 },
348 .@"union" => {
349 if (kind == .keyword_union) return prev;
350 try p.errStr(.wrong_tag, tok, p.tokSlice(tok));
351 try p.errTok(.previous_definition, prev.tok);
352 return null;
353 },
354 else => unreachable,
336355 }
337 return null;
338356}
339357
340358pub fn defineEnumeration(
......@@ -345,27 +363,26 @@ pub fn defineEnumeration(
345363 tok: TokenIndex,
346364 val: Value,
347365) !void {
348 const kinds = s.syms.items(.kind);
349 const names = s.syms.items(.name);
350 const end = s.scopeEnd();
351 var i = s.syms.len;
352 while (i > end) {
353 i -= 1;
354 switch (kinds[i]) {
355 .enumeration => if (names[i] == name) {
366 if (s.get(name, .vars)) |prev| {
367 switch (prev.kind) {
368 .enumeration => {
356369 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);
358371 return;
359372 },
360 .decl, .def, .constexpr => if (names[i] == name) {
373 .decl, .def, .constexpr => {
361374 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);
363376 return;
364377 },
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,
366383 }
367384 }
368 try s.syms.append(p.gpa, .{
385 try s.define(p.gpa, .{
369386 .kind = .enumeration,
370387 .name = name,
371388 .tok = tok,
deps/aro/aro/Tokenizer.zig+26-23
......@@ -749,12 +749,15 @@ pub const Token = struct {
749749 .string_literal_utf_8,
750750 .string_literal_utf_32,
751751 .string_literal_wide,
752 .unterminated_string_literal,
752753 => "a string literal",
753754 .char_literal,
754755 .char_literal_utf_8,
755756 .char_literal_utf_16,
756757 .char_literal_utf_32,
757758 .char_literal_wide,
759 .unterminated_char_literal,
760 .empty_char_literal,
758761 => "a character literal",
759762 .pp_num, .embed_byte => "A number",
760763 else => id.lexeme().?,
......@@ -798,7 +801,7 @@ pub const Token = struct {
798801 };
799802 }
800803
801 pub fn allowsDigraphs(id: Id, comp: *const Compilation) bool {
804 pub fn allowsDigraphs(id: Id, langopts: LangOpts) bool {
802805 return switch (id) {
803806 .l_bracket,
804807 .r_bracket,
......@@ -806,7 +809,7 @@ pub const Token = struct {
806809 .r_brace,
807810 .hash,
808811 .hash_hash,
809 => comp.langopts.hasDigraphs(),
812 => langopts.hasDigraphs(),
810813 else => false,
811814 };
812815 }
......@@ -829,15 +832,15 @@ pub const Token = struct {
829832 /// double underscore and underscore + capital letter identifiers
830833 /// belong to the implementation namespace, so we always convert them
831834 /// 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 {
833836 const kw = all_kws.get(str) orelse return .identifier;
834 const standard = comp.langopts.standard;
837 const standard = langopts.standard;
835838 return switch (kw) {
836839 .keyword_inline => if (standard.isGNU() or standard.atLeast(.c99)) kw else .identifier,
837840 .keyword_restrict => if (standard.atLeast(.c99)) kw else .identifier,
838841 .keyword_typeof => if (standard.isGNU() or standard.atLeast(.c23)) kw else .identifier,
839842 .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
842845 .keyword_c23_alignas,
843846 .keyword_c23_alignof,
......@@ -864,7 +867,7 @@ pub const Token = struct {
864867 .keyword_stdcall2,
865868 .keyword_thiscall2,
866869 .keyword_vectorcall2,
867 => if (comp.langopts.ms_extensions) kw else .identifier,
870 => if (langopts.ms_extensions) kw else .identifier,
868871 else => kw,
869872 };
870873 }
......@@ -1023,7 +1026,7 @@ const Tokenizer = @This();
10231026buf: []const u8,
10241027index: u32 = 0,
10251028source: Source.Id,
1026comp: *const Compilation,
1029langopts: LangOpts,
10271030line: u32 = 1,
10281031
10291032pub fn next(self: *Tokenizer) Token {
......@@ -1162,14 +1165,14 @@ pub fn next(self: *Tokenizer) Token {
11621165 '#' => state = .hash,
11631166 '0'...'9' => state = .pp_num,
11641167 '\t', '\x0B', '\x0C', ' ' => state = .whitespace,
1165 '$' => if (self.comp.langopts.dollars_in_identifiers) {
1168 '$' => if (self.langopts.dollars_in_identifiers) {
11661169 state = .extended_identifier;
11671170 } else {
11681171 id = .invalid;
11691172 self.index += 1;
11701173 break;
11711174 },
1172 0x1A => if (self.comp.langopts.ms_extensions) {
1175 0x1A => if (self.langopts.ms_extensions) {
11731176 id = .eof;
11741177 break;
11751178 } else {
......@@ -1306,15 +1309,15 @@ pub fn next(self: *Tokenizer) Token {
13061309 },
13071310 .identifier, .extended_identifier => switch (c) {
13081311 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
1309 '$' => if (self.comp.langopts.dollars_in_identifiers) {
1312 '$' => if (self.langopts.dollars_in_identifiers) {
13101313 state = .extended_identifier;
13111314 } 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;
13131316 break;
13141317 },
13151318 0x80...0xFF => state = .extended_identifier,
13161319 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;
13181321 break;
13191322 },
13201323 },
......@@ -1358,7 +1361,7 @@ pub fn next(self: *Tokenizer) Token {
13581361 },
13591362 .colon => switch (c) {
13601363 '>' => {
1361 if (self.comp.langopts.hasDigraphs()) {
1364 if (self.langopts.hasDigraphs()) {
13621365 id = .r_bracket;
13631366 self.index += 1;
13641367 } else {
......@@ -1367,7 +1370,7 @@ pub fn next(self: *Tokenizer) Token {
13671370 break;
13681371 },
13691372 ':' => {
1370 if (self.comp.langopts.standard.atLeast(.c23)) {
1373 if (self.langopts.standard.atLeast(.c23)) {
13711374 id = .colon_colon;
13721375 self.index += 1;
13731376 break;
......@@ -1388,7 +1391,7 @@ pub fn next(self: *Tokenizer) Token {
13881391 break;
13891392 },
13901393 '>' => {
1391 if (self.comp.langopts.hasDigraphs()) {
1394 if (self.langopts.hasDigraphs()) {
13921395 id = .r_brace;
13931396 self.index += 1;
13941397 } else {
......@@ -1397,7 +1400,7 @@ pub fn next(self: *Tokenizer) Token {
13971400 break;
13981401 },
13991402 ':' => {
1400 if (self.comp.langopts.hasDigraphs()) {
1403 if (self.langopts.hasDigraphs()) {
14011404 state = .hash_digraph;
14021405 } else {
14031406 id = .percent;
......@@ -1444,7 +1447,7 @@ pub fn next(self: *Tokenizer) Token {
14441447 break;
14451448 },
14461449 ':' => {
1447 if (self.comp.langopts.hasDigraphs()) {
1450 if (self.langopts.hasDigraphs()) {
14481451 id = .l_bracket;
14491452 self.index += 1;
14501453 } else {
......@@ -1453,7 +1456,7 @@ pub fn next(self: *Tokenizer) Token {
14531456 break;
14541457 },
14551458 '%' => {
1456 if (self.comp.langopts.hasDigraphs()) {
1459 if (self.langopts.hasDigraphs()) {
14571460 id = .l_brace;
14581461 self.index += 1;
14591462 } else {
......@@ -1613,7 +1616,7 @@ pub fn next(self: *Tokenizer) Token {
16131616 },
16141617 .line_comment => switch (c) {
16151618 '\n' => {
1616 if (self.comp.langopts.preserve_comments) {
1619 if (self.langopts.preserve_comments) {
16171620 id = .comment;
16181621 break;
16191622 }
......@@ -1629,7 +1632,7 @@ pub fn next(self: *Tokenizer) Token {
16291632 },
16301633 .multi_line_comment_asterisk => switch (c) {
16311634 '/' => {
1632 if (self.comp.langopts.preserve_comments) {
1635 if (self.langopts.preserve_comments) {
16331636 self.index += 1;
16341637 id = .comment;
16351638 break;
......@@ -1673,7 +1676,7 @@ pub fn next(self: *Tokenizer) Token {
16731676 '.',
16741677 => {},
16751678 'e', 'E', 'p', 'P' => state = .pp_num_exponent,
1676 '\'' => if (self.comp.langopts.standard.atLeast(.c23)) {
1679 '\'' => if (self.langopts.standard.atLeast(.c23)) {
16771680 state = .pp_num_digit_separator;
16781681 } else {
16791682 id = .pp_num;
......@@ -1721,7 +1724,7 @@ pub fn next(self: *Tokenizer) Token {
17211724 } else if (self.index == self.buf.len) {
17221725 switch (state) {
17231726 .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]),
17251728 .extended_identifier => id = .extended_identifier,
17261729
17271730 .period2 => {
......@@ -2149,7 +2152,7 @@ fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, st
21492152 var tokenizer = Tokenizer{
21502153 .buf = source.buf,
21512154 .source = source.id,
2152 .comp = &comp,
2155 .langopts = comp.langopts,
21532156 };
21542157 var i: usize = 0;
21552158 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 {
183183 return tc.getProgramPath(default_linker, buf);
184184}
185185
186const TargetSpecificToolName = std.BoundedArray(u8, 64);
187
188186/// If an explicit target is provided, also check the prefixed tool-specific name
189187/// TODO: this isn't exactly right since our target names don't necessarily match up
190188/// with GCC's.
191189/// 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) {
193191 var possible_names: std.BoundedArray([]const u8, 2) = .{};
194192 if (raw_triple) |triple| {
195 const w = target_specific.writer();
196 if (w.print("{s}-{s}", .{ triple, name })) {
197 possible_names.appendAssumeCapacity(target_specific.constSlice());
193 if (std.fmt.bufPrint(buf, "{s}-{s}", .{ triple, name })) |res| {
194 possible_names.appendAssumeCapacity(res);
198195 } else |_| {}
199196 }
200197 possible_names.appendAssumeCapacity(name);
......@@ -227,8 +224,8 @@ fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8
227224 var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
228225 var fib = std.heap.FixedBufferAllocator.init(&path_buf);
229226
230 var tool_specific_name: TargetSpecificToolName = .{};
231 const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_name);
227 var tool_specific_buf: [64]u8 = undefined;
228 const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_buf);
232229
233230 for (possible_names.constSlice()) |tool_name| {
234231 for (tc.program_paths.items) |program_path| {
deps/aro/aro/Tree.zig+7-4
......@@ -1,11 +1,12 @@
11const std = @import("std");
22const Interner = @import("backend").Interner;
3const Type = @import("Type.zig");
4const Tokenizer = @import("Tokenizer.zig");
3const Attribute = @import("Attribute.zig");
54const CodeGen = @import("CodeGen.zig");
65const Compilation = @import("Compilation.zig");
6const number_affixes = @import("Tree/number_affixes.zig");
77const Source = @import("Source.zig");
8const Attribute = @import("Attribute.zig");
8const Tokenizer = @import("Tokenizer.zig");
9const Type = @import("Type.zig");
910const Value = @import("Value.zig");
1011const StringInterner = @import("StringInterner.zig");
1112
......@@ -92,6 +93,8 @@ pub const Token = struct {
9293
9394 pub const List = std.MultiArrayList(Token);
9495 pub const Id = Tokenizer.Token.Id;
96 pub const NumberPrefix = number_affixes.Prefix;
97 pub const NumberSuffix = number_affixes.Suffix;
9598};
9699
97100pub const TokenIndex = u32;
......@@ -669,7 +672,7 @@ pub fn tokSlice(tree: *const Tree, tok_i: TokenIndex) []const u8 {
669672 const loc = tree.tokens.items(.loc)[tok_i];
670673 var tmp_tokenizer = Tokenizer{
671674 .buf = tree.comp.getSource(loc.id).buf,
672 .comp = tree.comp,
675 .langopts = tree.comp.langopts,
673676 .index = loc.byte_offset,
674677 .source = .generated,
675678 };
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 {
363363 // data.sub_type
364364 pointer,
365365 unspecified_variable_len_array,
366 decayed_unspecified_variable_len_array,
367366 // data.func
368367 /// int foo(int bar, char baz) and int (void)
369368 func,
......@@ -375,15 +374,11 @@ pub const Specifier = enum {
375374
376375 // data.array
377376 array,
378 decayed_array,
379377 static_array,
380 decayed_static_array,
381378 incomplete_array,
382 decayed_incomplete_array,
383379 vector,
384380 // data.expr
385381 variable_len_array,
386 decayed_variable_len_array,
387382
388383 // data.record
389384 @"struct",
......@@ -394,13 +389,9 @@ pub const Specifier = enum {
394389
395390 /// typeof(type-name)
396391 typeof_type,
397 /// decayed array created with typeof(type-name)
398 decayed_typeof_type,
399392
400393 /// typeof(expression)
401394 typeof_expr,
402 /// decayed array created with typeof(expression)
403 decayed_typeof_expr,
404395
405396 /// data.attributed
406397 attributed,
......@@ -428,6 +419,7 @@ data: union {
428419} = .{ .none = {} },
429420specifier: Specifier,
430421qual: Qualifiers = .{},
422decayed: bool = false,
431423
432424pub const int = Type{ .specifier = .int };
433425pub const invalid = Type{ .specifier = .invalid };
......@@ -442,7 +434,7 @@ pub fn is(ty: Type, specifier: Specifier) bool {
442434pub fn withAttributes(self: Type, allocator: std.mem.Allocator, attributes: []const Attribute) !Type {
443435 if (attributes.len == 0) return self;
444436 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 };
446438}
447439
448440pub fn isCallable(ty: Type) ?Type {
......@@ -468,10 +460,10 @@ pub fn isFunc(ty: Type) bool {
468460
469461pub fn isArray(ty: Type) bool {
470462 return switch (ty.specifier) {
471 .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => true,
472 .typeof_type => ty.data.sub_type.isArray(),
473 .typeof_expr => ty.data.expr.ty.isArray(),
474 .attributed => ty.data.attributed.base.isArray(),
463 .array, .static_array, .incomplete_array, .variable_len_array, .unspecified_variable_len_array => !ty.isDecayed(),
464 .typeof_type => !ty.isDecayed() and ty.data.sub_type.isArray(),
465 .typeof_expr => !ty.isDecayed() and ty.data.expr.ty.isArray(),
466 .attributed => !ty.isDecayed() and ty.data.attributed.base.isArray(),
475467 else => false,
476468 };
477469}
......@@ -502,35 +494,22 @@ pub fn isScalarNonInt(ty: Type) bool {
502494}
503495
504496pub fn isDecayed(ty: Type) bool {
505 const decayed = switch (ty.specifier) {
506 .decayed_array,
507 .decayed_static_array,
508 .decayed_incomplete_array,
509 .decayed_variable_len_array,
510 .decayed_unspecified_variable_len_array,
511 .decayed_typeof_type,
512 .decayed_typeof_expr,
513 => true,
514 else => false,
515 };
516 std.debug.assert(decayed or !std.mem.startsWith(u8, @tagName(ty.specifier), "decayed"));
517 return decayed;
497 return ty.decayed;
518498}
519499
520500pub fn isPtr(ty: Type) bool {
521501 return switch (ty.specifier) {
522 .pointer,
523 .decayed_array,
524 .decayed_static_array,
525 .decayed_incomplete_array,
526 .decayed_variable_len_array,
527 .decayed_unspecified_variable_len_array,
528 .decayed_typeof_type,
529 .decayed_typeof_expr,
530 => true,
531 .typeof_type => ty.data.sub_type.isPtr(),
532 .typeof_expr => ty.data.expr.ty.isPtr(),
533 .attributed => ty.data.attributed.base.isPtr(),
502 .pointer => true,
503
504 .array,
505 .static_array,
506 .incomplete_array,
507 .variable_len_array,
508 .unspecified_variable_len_array,
509 => ty.isDecayed(),
510 .typeof_type => ty.isDecayed() or ty.data.sub_type.isPtr(),
511 .typeof_expr => ty.isDecayed() or ty.data.expr.ty.isPtr(),
512 .attributed => ty.isDecayed() or ty.data.attributed.base.isPtr(),
534513 else => false,
535514 };
536515}
......@@ -608,15 +587,15 @@ pub fn isVoidStar(ty: Type) bool {
608587
609588pub fn isTypeof(ty: Type) bool {
610589 return switch (ty.specifier) {
611 .typeof_type, .typeof_expr, .decayed_typeof_type, .decayed_typeof_expr => true,
590 .typeof_type, .typeof_expr => true,
612591 else => false,
613592 };
614593}
615594
616595pub fn isConst(ty: Type) bool {
617596 return switch (ty.specifier) {
618 .typeof_type, .decayed_typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(),
619 .typeof_expr, .decayed_typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(),
597 .typeof_type => ty.qual.@"const" or ty.data.sub_type.isConst(),
598 .typeof_expr => ty.qual.@"const" or ty.data.expr.ty.isConst(),
620599 .attributed => ty.data.attributed.base.isConst(),
621600 else => ty.qual.@"const",
622601 };
......@@ -630,7 +609,7 @@ pub fn signedness(ty: Type, comp: *const Compilation) std.builtin.Signedness {
630609 return switch (ty.specifier) {
631610 // zig fmt: off
632611 .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,
634613 .complex_uint, .complex_ulong, .complex_ulong_long, .complex_uint128 => .unsigned,
635614 // zig fmt: on
636615 .bit_int, .complex_bit_int => ty.data.int.signedness,
......@@ -678,16 +657,16 @@ pub fn isAnonymousRecord(ty: Type, comp: *const Compilation) bool {
678657
679658pub fn elemType(ty: Type) Type {
680659 return switch (ty.specifier) {
681 .pointer, .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => ty.data.sub_type.*,
682 .array, .static_array, .incomplete_array, .decayed_array, .decayed_static_array, .decayed_incomplete_array, .vector => ty.data.array.elem,
683 .variable_len_array, .decayed_variable_len_array => ty.data.expr.ty,
684 .typeof_type, .decayed_typeof_type, .typeof_expr, .decayed_typeof_expr => {
660 .pointer, .unspecified_variable_len_array => ty.data.sub_type.*,
661 .array, .static_array, .incomplete_array, .vector => ty.data.array.elem,
662 .variable_len_array => ty.data.expr.ty,
663 .typeof_type, .typeof_expr => {
685664 const unwrapped = ty.canonicalize(.preserve_quals);
686665 var elem = unwrapped.elemType();
687666 elem.qual = elem.qual.mergeAll(unwrapped.qual);
688667 return elem;
689668 },
690 .attributed => ty.data.attributed.base,
669 .attributed => ty.data.attributed.base.elemType(),
691670 .invalid => Type.invalid,
692671 // zig fmt: off
693672 .complex_float, .complex_double, .complex_long_double, .complex_float80,
......@@ -703,8 +682,8 @@ pub fn elemType(ty: Type) Type {
703682pub fn returnType(ty: Type) Type {
704683 return switch (ty.specifier) {
705684 .func, .var_args_func, .old_style_func => ty.data.func.return_type,
706 .typeof_type, .decayed_typeof_type => ty.data.sub_type.returnType(),
707 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.returnType(),
685 .typeof_type => ty.data.sub_type.returnType(),
686 .typeof_expr => ty.data.expr.ty.returnType(),
708687 .attributed => ty.data.attributed.base.returnType(),
709688 .invalid => Type.invalid,
710689 else => unreachable,
......@@ -714,8 +693,8 @@ pub fn returnType(ty: Type) Type {
714693pub fn params(ty: Type) []Func.Param {
715694 return switch (ty.specifier) {
716695 .func, .var_args_func, .old_style_func => ty.data.func.params,
717 .typeof_type, .decayed_typeof_type => ty.data.sub_type.params(),
718 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.params(),
696 .typeof_type => ty.data.sub_type.params(),
697 .typeof_expr => ty.data.expr.ty.params(),
719698 .attributed => ty.data.attributed.base.params(),
720699 .invalid => &.{},
721700 else => unreachable,
......@@ -724,9 +703,9 @@ pub fn params(ty: Type) []Func.Param {
724703
725704pub fn arrayLen(ty: Type) ?u64 {
726705 return switch (ty.specifier) {
727 .array, .static_array, .decayed_array, .decayed_static_array => ty.data.array.len,
728 .typeof_type, .decayed_typeof_type => ty.data.sub_type.arrayLen(),
729 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.arrayLen(),
706 .array, .static_array => ty.data.array.len,
707 .typeof_type => ty.data.sub_type.arrayLen(),
708 .typeof_expr => ty.data.expr.ty.arrayLen(),
730709 .attributed => ty.data.attributed.base.arrayLen(),
731710 else => null,
732711 };
......@@ -748,8 +727,8 @@ pub fn anyQual(ty: Type) bool {
748727pub fn getAttributes(ty: Type) []const Attribute {
749728 return switch (ty.specifier) {
750729 .attributed => ty.data.attributed.attributes,
751 .typeof_type, .decayed_typeof_type => ty.data.sub_type.getAttributes(),
752 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getAttributes(),
730 .typeof_type => ty.data.sub_type.getAttributes(),
731 .typeof_expr => ty.data.expr.ty.getAttributes(),
753732 else => &.{},
754733 };
755734}
......@@ -757,8 +736,8 @@ pub fn getAttributes(ty: Type) []const Attribute {
757736pub fn getRecord(ty: Type) ?*const Type.Record {
758737 return switch (ty.specifier) {
759738 .attributed => ty.data.attributed.base.getRecord(),
760 .typeof_type, .decayed_typeof_type => ty.data.sub_type.getRecord(),
761 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.getRecord(),
739 .typeof_type => ty.data.sub_type.getRecord(),
740 .typeof_expr => ty.data.expr.ty.getRecord(),
762741 .@"struct", .@"union" => ty.data.record,
763742 else => null,
764743 };
......@@ -901,6 +880,7 @@ pub fn bitfieldPromotion(ty: Type, comp: *Compilation, width: u32) ?Type {
901880}
902881
903882pub fn hasIncompleteSize(ty: Type) bool {
883 if (ty.isDecayed()) return false;
904884 return switch (ty.specifier) {
905885 .void, .incomplete_array => true,
906886 .@"enum" => ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed,
......@@ -917,20 +897,14 @@ pub fn hasUnboundVLA(ty: Type) bool {
917897 var cur = ty;
918898 while (true) {
919899 switch (cur.specifier) {
920 .unspecified_variable_len_array,
921 .decayed_unspecified_variable_len_array,
922 => return true,
900 .unspecified_variable_len_array => return true,
923901 .array,
924902 .static_array,
925903 .incomplete_array,
926904 .variable_len_array,
927 .decayed_array,
928 .decayed_static_array,
929 .decayed_incomplete_array,
930 .decayed_variable_len_array,
931905 => cur = cur.elemType(),
932 .typeof_type, .decayed_typeof_type => cur = cur.data.sub_type.*,
933 .typeof_expr, .decayed_typeof_expr => cur = cur.data.expr.ty,
906 .typeof_type => cur = cur.data.sub_type.*,
907 .typeof_expr => cur = cur.data.expr.ty,
934908 .attributed => cur = cur.data.attributed.base,
935909 else => return false,
936910 }
......@@ -1006,9 +980,11 @@ pub fn sizeCompare(a: Type, b: Type, comp: *Compilation) TypeSizeOrder {
1006980
1007981/// Size of type as reported by sizeof
1008982pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
983 if (ty.isPtr()) return comp.target.ptrBitWidth() / 8;
984
1009985 return switch (ty.specifier) {
1010986 .auto_type, .c23_auto => unreachable,
1011 .variable_len_array, .unspecified_variable_len_array => return null,
987 .variable_len_array, .unspecified_variable_len_array => null,
1012988 .incomplete_array => return if (comp.langopts.emulate == .msvc) @as(?u64, 0) else null,
1013989 .func, .var_args_func, .old_style_func, .void, .bool => 1,
1014990 .char, .schar, .uchar => 1,
......@@ -1037,14 +1013,7 @@ pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
10371013 .complex_long_double, .complex_float80, .complex_float128, .complex_bit_int,
10381014 => return 2 * ty.makeReal().sizeof(comp).?,
10391015 // zig fmt: on
1040 .pointer,
1041 .decayed_array,
1042 .decayed_static_array,
1043 .decayed_incomplete_array,
1044 .decayed_variable_len_array,
1045 .decayed_unspecified_variable_len_array,
1046 .decayed_typeof_type,
1047 .decayed_typeof_expr,
1016 .pointer => unreachable,
10481017 .static_array,
10491018 .nullptr_t,
10501019 => comp.target.ptrBitWidth() / 8,
......@@ -1073,8 +1042,8 @@ pub fn sizeof(ty: Type, comp: *const Compilation) ?u64 {
10731042pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 {
10741043 return switch (ty.specifier) {
10751044 .bool => if (comp.langopts.emulate == .msvc) @as(u64, 8) else 1,
1076 .typeof_type, .decayed_typeof_type => ty.data.sub_type.bitSizeof(comp),
1077 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.bitSizeof(comp),
1045 .typeof_type => ty.data.sub_type.bitSizeof(comp),
1046 .typeof_expr => ty.data.expr.ty.bitSizeof(comp),
10781047 .attributed => ty.data.attributed.base.bitSizeof(comp),
10791048 .bit_int => return ty.data.int.bits,
10801049 .long_double => comp.target.c_type_bit_size(.longdouble),
......@@ -1117,7 +1086,10 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
11171086 .unspecified_variable_len_array,
11181087 .array,
11191088 .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),
11211093 .func, .var_args_func, .old_style_func => target_util.defaultFunctionAlignment(comp.target),
11221094 .char, .schar, .uchar, .void, .bool => 1,
11231095
......@@ -1153,11 +1125,6 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
11531125
11541126 .float80, .float128 => 16,
11551127 .pointer,
1156 .decayed_array,
1157 .decayed_static_array,
1158 .decayed_incomplete_array,
1159 .decayed_variable_len_array,
1160 .decayed_unspecified_variable_len_array,
11611128 .static_array,
11621129 .nullptr_t,
11631130 => switch (comp.target.cpu.arch) {
......@@ -1166,8 +1133,8 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
11661133 },
11671134 .@"struct", .@"union" => if (ty.data.record.isIncomplete()) 0 else @intCast(ty.data.record.type_layout.field_alignment_bits / 8),
11681135 .@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp),
1169 .typeof_type, .decayed_typeof_type => ty.data.sub_type.alignof(comp),
1170 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.alignof(comp),
1136 .typeof_type => ty.data.sub_type.alignof(comp),
1137 .typeof_expr => ty.data.expr.ty.alignof(comp),
11711138 .attributed => ty.data.attributed.base.alignof(comp),
11721139 };
11731140}
......@@ -1179,7 +1146,10 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
11791146/// arrays and pointers.
11801147pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type {
11811148 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 }
11831153 if (!cur.isTypeof()) return cur;
11841154
11851155 var qual = cur.qual;
......@@ -1187,14 +1157,6 @@ pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals })
11871157 switch (cur.specifier) {
11881158 .typeof_type => cur = cur.data.sub_type.*,
11891159 .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 },
11981160 else => break,
11991161 }
12001162 qual = qual.mergeAll(cur.qual);
......@@ -1204,6 +1166,7 @@ pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals })
12041166 } else {
12051167 cur.qual = qual;
12061168 }
1169 cur.decayed = ty.decayed;
12071170 return cur;
12081171}
12091172
......@@ -1219,8 +1182,8 @@ pub fn get(ty: *const Type, specifier: Specifier) ?*const Type {
12191182
12201183pub fn requestedAlignment(ty: Type, comp: *const Compilation) ?u29 {
12211184 return switch (ty.specifier) {
1222 .typeof_type, .decayed_typeof_type => ty.data.sub_type.requestedAlignment(comp),
1223 .typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.requestedAlignment(comp),
1185 .typeof_type => ty.data.sub_type.requestedAlignment(comp),
1186 .typeof_expr => ty.data.expr.ty.requestedAlignment(comp),
12241187 .attributed => annotationAlignment(comp, ty.data.attributed.attributes),
12251188 else => null,
12261189 };
......@@ -1265,14 +1228,11 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi
12651228 if (a.qual.@"volatile" != b.qual.@"volatile") return false;
12661229 }
12671230
1231 if (a.isPtr()) {
1232 return a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers);
1233 }
12681234 switch (a.specifier) {
1269 .pointer,
1270 .decayed_array,
1271 .decayed_static_array,
1272 .decayed_incomplete_array,
1273 .decayed_variable_len_array,
1274 .decayed_unspecified_variable_len_array,
1275 => if (!a_param.elemType().eql(b_param.elemType(), comp, check_qualifiers)) return false,
1235 .pointer => unreachable,
12761236
12771237 .func,
12781238 .var_args_func,
......@@ -1293,8 +1253,9 @@ pub fn eql(a_param: Type, b_param: Type, comp: *const Compilation, check_qualifi
12931253 }
12941254 if (!a.elemType().eql(b.elemType(), comp, false)) return false;
12951255 },
1296 .variable_len_array => if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false,
1297
1256 .variable_len_array => {
1257 if (!a.elemType().eql(b.elemType(), comp, check_qualifiers)) return false;
1258 },
12981259 .@"struct", .@"union" => if (a.data.record != b.data.record) return false,
12991260 .@"enum" => if (a.data.@"enum" != b.data.@"enum") return false,
13001261 .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
13061267
13071268/// Decays an array to a pointer
13081269pub fn decayArray(ty: *Type) void {
1309 // the decayed array type is the current specifier +1
1310 ty.specifier = @enumFromInt(@intFromEnum(ty.specifier) + 1);
1270 std.debug.assert(ty.isArray());
1271 ty.decayed = true;
13111272}
13121273
13131274pub fn originalTypeOfDecayedArray(ty: Type) Type {
13141275 std.debug.assert(ty.isDecayed());
13151276 var copy = ty;
1316 copy.specifier = @enumFromInt(@intFromEnum(ty.specifier) - 1);
1277 copy.decayed = false;
13171278 return copy;
13181279}
13191280
......@@ -1405,25 +1366,23 @@ pub fn combine(inner: *Type, outer: Type) Parser.Error!void {
14051366 switch (inner.specifier) {
14061367 .pointer => return inner.data.sub_type.combine(outer),
14071368 .unspecified_variable_len_array => {
1369 std.debug.assert(!inner.isDecayed());
14081370 try inner.data.sub_type.combine(outer);
14091371 },
14101372 .variable_len_array => {
1373 std.debug.assert(!inner.isDecayed());
14111374 try inner.data.expr.ty.combine(outer);
14121375 },
14131376 .array, .static_array, .incomplete_array => {
1377 std.debug.assert(!inner.isDecayed());
14141378 try inner.data.array.elem.combine(outer);
14151379 },
14161380 .func, .var_args_func, .old_style_func => {
14171381 try inner.data.func.return_type.combine(outer);
14181382 },
1419 .decayed_array,
1420 .decayed_static_array,
1421 .decayed_incomplete_array,
1422 .decayed_variable_len_array,
1423 .decayed_unspecified_variable_len_array,
1424 .decayed_typeof_type,
1425 .decayed_typeof_expr,
1426 => unreachable, // type should not be able to decay before being combined
1383 .typeof_type,
1384 .typeof_expr,
1385 => std.debug.assert(!inner.isDecayed()),
14271386 .void, .invalid => inner.* = outer,
14281387 else => unreachable,
14291388 }
......@@ -1474,8 +1433,8 @@ pub fn validateCombinedType(ty: Type, p: *Parser, source_tok: TokenIndex) Parser
14741433 try p.errStr(.suggest_pointer_for_invalid_fp16, source_tok, "function return value");
14751434 }
14761435 },
1477 .typeof_type, .decayed_typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok),
1478 .typeof_expr, .decayed_typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok),
1436 .typeof_type => return ty.data.sub_type.validateCombinedType(p, source_tok),
1437 .typeof_expr => return ty.data.expr.ty.validateCombinedType(p, source_tok),
14791438 .attributed => return ty.data.attributed.base.validateCombinedType(p, source_tok),
14801439 else => {},
14811440 }
......@@ -1610,6 +1569,7 @@ pub const Builder = struct {
16101569 decayed_typeof_expr: *Expr,
16111570
16121571 attributed: *Attributed,
1572 decayed_attributed: *Attributed,
16131573
16141574 pub fn str(spec: Builder.Specifier, langopts: LangOpts) ?[]const u8 {
16151575 return switch (spec) {
......@@ -1835,13 +1795,10 @@ pub const Builder = struct {
18351795 ty.specifier = .pointer;
18361796 ty.data = .{ .sub_type = data };
18371797 },
1838 .unspecified_variable_len_array => |data| {
1798 .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => |data| {
18391799 ty.specifier = .unspecified_variable_len_array;
18401800 ty.data = .{ .sub_type = data };
1841 },
1842 .decayed_unspecified_variable_len_array => |data| {
1843 ty.specifier = .decayed_unspecified_variable_len_array;
1844 ty.data = .{ .sub_type = data };
1801 ty.decayed = b.specifier == .decayed_unspecified_variable_len_array;
18451802 },
18461803 .func => |data| {
18471804 ty.specifier = .func;
......@@ -1855,41 +1812,29 @@ pub const Builder = struct {
18551812 ty.specifier = .old_style_func;
18561813 ty.data = .{ .func = data };
18571814 },
1858 .array => |data| {
1815 .array, .decayed_array => |data| {
18591816 ty.specifier = .array;
18601817 ty.data = .{ .array = data };
1818 ty.decayed = b.specifier == .decayed_array;
18611819 },
1862 .decayed_array => |data| {
1863 ty.specifier = .decayed_array;
1864 ty.data = .{ .array = data };
1865 },
1866 .static_array => |data| {
1820 .static_array, .decayed_static_array => |data| {
18671821 ty.specifier = .static_array;
18681822 ty.data = .{ .array = data };
1823 ty.decayed = b.specifier == .decayed_static_array;
18691824 },
1870 .decayed_static_array => |data| {
1871 ty.specifier = .decayed_static_array;
1872 ty.data = .{ .array = data };
1873 },
1874 .incomplete_array => |data| {
1825 .incomplete_array, .decayed_incomplete_array => |data| {
18751826 ty.specifier = .incomplete_array;
18761827 ty.data = .{ .array = data };
1877 },
1878 .decayed_incomplete_array => |data| {
1879 ty.specifier = .decayed_incomplete_array;
1880 ty.data = .{ .array = data };
1828 ty.decayed = b.specifier == .decayed_incomplete_array;
18811829 },
18821830 .vector => |data| {
18831831 ty.specifier = .vector;
18841832 ty.data = .{ .array = data };
18851833 },
1886 .variable_len_array => |data| {
1834 .variable_len_array, .decayed_variable_len_array => |data| {
18871835 ty.specifier = .variable_len_array;
18881836 ty.data = .{ .expr = data };
1889 },
1890 .decayed_variable_len_array => |data| {
1891 ty.specifier = .decayed_variable_len_array;
1892 ty.data = .{ .expr = data };
1837 ty.decayed = b.specifier == .decayed_variable_len_array;
18931838 },
18941839 .@"struct" => |data| {
18951840 ty.specifier = .@"struct";
......@@ -1903,25 +1848,20 @@ pub const Builder = struct {
19031848 ty.specifier = .@"enum";
19041849 ty.data = .{ .@"enum" = data };
19051850 },
1906 .typeof_type => |data| {
1851 .typeof_type, .decayed_typeof_type => |data| {
19071852 ty.specifier = .typeof_type;
19081853 ty.data = .{ .sub_type = data };
1854 ty.decayed = b.specifier == .decayed_typeof_type;
19091855 },
1910 .decayed_typeof_type => |data| {
1911 ty.specifier = .decayed_typeof_type;
1912 ty.data = .{ .sub_type = data };
1913 },
1914 .typeof_expr => |data| {
1856 .typeof_expr, .decayed_typeof_expr => |data| {
19151857 ty.specifier = .typeof_expr;
19161858 ty.data = .{ .expr = data };
1859 ty.decayed = b.specifier == .decayed_typeof_expr;
19171860 },
1918 .decayed_typeof_expr => |data| {
1919 ty.specifier = .decayed_typeof_expr;
1920 ty.data = .{ .expr = data };
1921 },
1922 .attributed => |data| {
1861 .attributed, .decayed_attributed => |data| {
19231862 ty.specifier = .attributed;
19241863 ty.data = .{ .attributed = data };
1864 ty.decayed = b.specifier == .decayed_attributed;
19251865 },
19261866 }
19271867 if (!ty.isReal() and ty.isInt()) {
......@@ -2359,30 +2299,47 @@ pub const Builder = struct {
23592299 .complex_float128 => .complex_float128,
23602300
23612301 .pointer => .{ .pointer = ty.data.sub_type },
2362 .unspecified_variable_len_array => .{ .unspecified_variable_len_array = ty.data.sub_type },
2363 .decayed_unspecified_variable_len_array => .{ .decayed_unspecified_variable_len_array = ty.data.sub_type },
2302 .unspecified_variable_len_array => if (ty.isDecayed())
2303 .{ .decayed_unspecified_variable_len_array = ty.data.sub_type }
2304 else
2305 .{ .unspecified_variable_len_array = ty.data.sub_type },
23642306 .func => .{ .func = ty.data.func },
23652307 .var_args_func => .{ .var_args_func = ty.data.func },
23662308 .old_style_func => .{ .old_style_func = ty.data.func },
2367 .array => .{ .array = ty.data.array },
2368 .decayed_array => .{ .decayed_array = ty.data.array },
2369 .static_array => .{ .static_array = ty.data.array },
2370 .decayed_static_array => .{ .decayed_static_array = ty.data.array },
2371 .incomplete_array => .{ .incomplete_array = ty.data.array },
2372 .decayed_incomplete_array => .{ .decayed_incomplete_array = ty.data.array },
2309 .array => if (ty.isDecayed())
2310 .{ .decayed_array = ty.data.array }
2311 else
2312 .{ .array = ty.data.array },
2313 .static_array => if (ty.isDecayed())
2314 .{ .decayed_static_array = ty.data.array }
2315 else
2316 .{ .static_array = ty.data.array },
2317 .incomplete_array => if (ty.isDecayed())
2318 .{ .decayed_incomplete_array = ty.data.array }
2319 else
2320 .{ .incomplete_array = ty.data.array },
23732321 .vector => .{ .vector = ty.data.array },
2374 .variable_len_array => .{ .variable_len_array = ty.data.expr },
2375 .decayed_variable_len_array => .{ .decayed_variable_len_array = ty.data.expr },
2322 .variable_len_array => if (ty.isDecayed())
2323 .{ .decayed_variable_len_array = ty.data.expr }
2324 else
2325 .{ .variable_len_array = ty.data.expr },
23762326 .@"struct" => .{ .@"struct" = ty.data.record },
23772327 .@"union" => .{ .@"union" = ty.data.record },
23782328 .@"enum" => .{ .@"enum" = ty.data.@"enum" },
23792329
2380 .typeof_type => .{ .typeof_type = ty.data.sub_type },
2381 .decayed_typeof_type => .{ .decayed_typeof_type = ty.data.sub_type },
2382 .typeof_expr => .{ .typeof_expr = ty.data.expr },
2383 .decayed_typeof_expr => .{ .decayed_typeof_expr = ty.data.expr },
2330 .typeof_type => if (ty.isDecayed())
2331 .{ .decayed_typeof_type = ty.data.sub_type }
2332 else
2333 .{ .typeof_type = ty.data.sub_type },
2334 .typeof_expr => if (ty.isDecayed())
2335 .{ .decayed_typeof_expr = ty.data.expr }
2336 else
2337 .{ .typeof_expr = ty.data.expr },
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 },
23862343 else => unreachable,
23872344 };
23882345 }
......@@ -2472,24 +2429,17 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts
24722429 try w.writeAll(")");
24732430 return true;
24742431 }
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 }
24752441 switch (ty.specifier) {
2476 .pointer,
2477 .decayed_array,
2478 .decayed_static_array,
2479 .decayed_incomplete_array,
2480 .decayed_variable_len_array,
2481 .decayed_unspecified_variable_len_array,
2482 .decayed_typeof_type,
2483 .decayed_typeof_expr,
2484 => {
2485 const elem_ty = ty.elemType();
2486 const simple = try elem_ty.printPrologue(mapper, langopts, w);
2487 if (simple) try w.writeByte(' ');
2488 if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte('(');
2489 try w.writeByte('*');
2490 try ty.qual.dump(w);
2491 return false;
2492 },
2442 .pointer => unreachable,
24932443 .func, .var_args_func, .old_style_func => {
24942444 const ret_ty = ty.data.func.return_type;
24952445 const simple = try ret_ty.printPrologue(mapper, langopts, w);
......@@ -2541,20 +2491,14 @@ fn printPrologue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts
25412491
25422492fn printEpilogue(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w: anytype) @TypeOf(w).Error!void {
25432493 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 }
25442500 switch (ty.specifier) {
2545 .pointer,
2546 .decayed_array,
2547 .decayed_static_array,
2548 .decayed_incomplete_array,
2549 .decayed_variable_len_array,
2550 .decayed_unspecified_variable_len_array,
2551 .decayed_typeof_type,
2552 .decayed_typeof_expr,
2553 => {
2554 const elem_ty = ty.elemType();
2555 if (elem_ty.isFunc() or elem_ty.isArray()) try w.writeByte(')');
2556 try elem_ty.printEpilogue(mapper, langopts, w);
2557 },
2501 .pointer => unreachable, // handled above
25582502 .func, .var_args_func, .old_style_func => {
25592503 try w.writeByte('(');
25602504 for (ty.data.func.params, 0..) |param, i| {
......@@ -2637,10 +2581,10 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w:
26372581 try w.writeAll(") ");
26382582 try ty.data.func.return_type.dump(mapper, langopts, w);
26392583 },
2640 .array, .static_array, .decayed_array, .decayed_static_array => {
2641 if (ty.specifier == .decayed_array or ty.specifier == .decayed_static_array) try w.writeAll("*d");
2584 .array, .static_array => {
2585 if (ty.isDecayed()) try w.writeAll("*d");
26422586 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 ");
26442588 try w.print("{d}]", .{ty.data.array.len});
26452589 try ty.data.array.elem.dump(mapper, langopts, w);
26462590 },
......@@ -2649,8 +2593,8 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w:
26492593 try ty.data.array.elem.dump(mapper, langopts, w);
26502594 try w.writeAll(")");
26512595 },
2652 .incomplete_array, .decayed_incomplete_array => {
2653 if (ty.specifier == .decayed_incomplete_array) try w.writeAll("*d");
2596 .incomplete_array => {
2597 if (ty.isDecayed()) try w.writeAll("*d");
26542598 try w.writeAll("[]");
26552599 try ty.data.array.elem.dump(mapper, langopts, w);
26562600 },
......@@ -2672,27 +2616,28 @@ pub fn dump(ty: Type, mapper: StringInterner.TypeMapper, langopts: LangOpts, w:
26722616 try w.print("union {s}", .{mapper.lookup(ty.data.record.name)});
26732617 if (dump_detailed_containers) try dumpRecord(ty.data.record, mapper, langopts, w);
26742618 },
2675 .unspecified_variable_len_array, .decayed_unspecified_variable_len_array => {
2676 if (ty.specifier == .decayed_unspecified_variable_len_array) try w.writeAll("*d");
2619 .unspecified_variable_len_array => {
2620 if (ty.isDecayed()) try w.writeAll("*d");
26772621 try w.writeAll("[*]");
26782622 try ty.data.sub_type.dump(mapper, langopts, w);
26792623 },
2680 .variable_len_array, .decayed_variable_len_array => {
2681 if (ty.specifier == .decayed_variable_len_array) try w.writeAll("*d");
2624 .variable_len_array => {
2625 if (ty.isDecayed()) try w.writeAll("*d");
26822626 try w.writeAll("[<expr>]");
26832627 try ty.data.expr.ty.dump(mapper, langopts, w);
26842628 },
2685 .typeof_type, .decayed_typeof_type => {
2629 .typeof_type => {
26862630 try w.writeAll("typeof(");
26872631 try ty.data.sub_type.dump(mapper, langopts, w);
26882632 try w.writeAll(")");
26892633 },
2690 .typeof_expr, .decayed_typeof_expr => {
2634 .typeof_expr => {
26912635 try w.writeAll("typeof(<expr>: ");
26922636 try ty.data.expr.ty.dump(mapper, langopts, w);
26932637 try w.writeAll(")");
26942638 },
26952639 .attributed => {
2640 if (ty.isDecayed()) try w.writeAll("*d:");
26962641 try w.writeAll("attributed(");
26972642 try ty.data.attributed.base.dump(mapper, langopts, w);
26982643 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 {
215215
216216 const limbs = try comp.gpa.alloc(
217217 std.math.big.Limb,
218 std.math.big.int.calcTwosCompLimbCount(bits),
218 std.math.big.int.calcTwosCompLimbCount(@max(big.bitCountTwosComp(), bits)),
219219 );
220220 defer comp.gpa.free(limbs);
221221 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 @@
11const std = @import("std");
22const LangOpts = @import("LangOpts.zig");
33const Type = @import("Type.zig");
4const llvm = @import("root").codegen.llvm;
54const TargetSet = @import("Builtins/Properties.zig").TargetSet;
65
76/// intmax_t for this target