mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
aro: update
This is f5fb720a5399ee98e45f36337b2f68a4d23a783c plus ehaas's nonnull attribute pull request currently at 4b26cb3ac610a0a070fc43e43da8b4cdf0e9101b with zig patches intact.
This commit is contained in:
parent
01132e0cf8
commit
8cba6b1df8
103
lib/compiler/aro/aro/Attribute.zig
vendored
103
lib/compiler/aro/aro/Attribute.zig
vendored
@ -345,6 +345,7 @@ fn diagnoseField(
|
||||
|
||||
pub fn diagnose(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, arg_start: TokenIndex, node: Tree.Node, p: *Parser) !bool {
|
||||
switch (attr) {
|
||||
.nonnull => return false,
|
||||
inline else => |tag| {
|
||||
const decl = @typeInfo(attributes).@"struct".decls[@intFromEnum(tag)];
|
||||
const max_arg_count = comptime maxArgCount(tag);
|
||||
@ -532,10 +533,7 @@ const attributes = struct {
|
||||
pub const @"noinline" = struct {};
|
||||
pub const noipa = struct {};
|
||||
// TODO: arbitrary number of arguments
|
||||
// const nonnull = struct {
|
||||
// // arg_index: []const u32,
|
||||
// };
|
||||
// };
|
||||
pub const nonnull = struct {};
|
||||
pub const nonstring = struct {};
|
||||
pub const noplt = struct {};
|
||||
pub const @"noreturn" = struct {};
|
||||
@ -802,8 +800,16 @@ fn ignoredAttrErr(p: *Parser, tok: TokenIndex, attr: Attribute.Tag, context: []c
|
||||
try p.errStr(.ignored_attribute, tok, str);
|
||||
}
|
||||
|
||||
pub const applyParameterAttributes = applyVariableAttributes;
|
||||
pub fn applyParameterAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diagnostic: ?Parser.Diagnostic) !QualType {
|
||||
return applyVariableOrParameterAttributes(p, qt, attr_buf_start, diagnostic, .parameter);
|
||||
}
|
||||
|
||||
pub fn applyVariableAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diagnostic: ?Parser.Diagnostic) !QualType {
|
||||
return applyVariableOrParameterAttributes(p, qt, attr_buf_start, diagnostic, .variable);
|
||||
}
|
||||
|
||||
fn applyVariableOrParameterAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diagnostic: ?Parser.Diagnostic, context: enum { parameter, variable }) !QualType {
|
||||
const gpa = p.comp.gpa;
|
||||
const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
|
||||
const toks = p.attr_buf.items(.tok)[attr_buf_start..];
|
||||
p.attr_application_buf.items.len = 0;
|
||||
@ -814,27 +820,33 @@ pub fn applyVariableAttributes(p: *Parser, qt: QualType, attr_buf_start: usize,
|
||||
// zig fmt: off
|
||||
.alias, .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .weak, .used,
|
||||
.noinit, .retain, .persistent, .section, .mode, .asm_label, .nullability, .unaligned,
|
||||
=> try p.attr_application_buf.append(p.gpa, attr),
|
||||
=> try p.attr_application_buf.append(gpa, attr),
|
||||
// zig fmt: on
|
||||
.common => if (nocommon) {
|
||||
try p.err(tok, .ignore_common, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
common = true;
|
||||
},
|
||||
.nocommon => if (common) {
|
||||
try p.err(tok, .ignore_nocommon, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
nocommon = true;
|
||||
},
|
||||
.vector_size => try attr.applyVectorSize(p, tok, &base_qt),
|
||||
.aligned => try attr.applyAligned(p, base_qt, diagnostic),
|
||||
.nonnull => {
|
||||
switch (context) {
|
||||
.parameter => try p.err(tok, .attribute_todo, .{ "nonnull", "parameters" }),
|
||||
.variable => try p.err(tok, .nonnull_not_applicable, .{}),
|
||||
}
|
||||
},
|
||||
.nonstring => {
|
||||
if (base_qt.get(p.comp, .array)) |array_ty| {
|
||||
if (array_ty.elem.get(p.comp, .int)) |int_ty| switch (int_ty) {
|
||||
.char, .uchar, .schar => {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
continue;
|
||||
},
|
||||
else => {},
|
||||
@ -845,12 +857,12 @@ pub fn applyVariableAttributes(p: *Parser, qt: QualType, attr_buf_start: usize,
|
||||
.uninitialized => if (p.func.qt == null) {
|
||||
try p.err(tok, .local_variable_attribute, .{"uninitialized"});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
},
|
||||
.cleanup => if (p.func.qt == null) {
|
||||
try p.err(tok, .local_variable_attribute, .{"cleanup"});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
},
|
||||
.calling_convention => try applyCallingConvention(attr, p, tok, base_qt),
|
||||
.alloc_size,
|
||||
@ -873,7 +885,7 @@ pub fn applyFieldAttributes(p: *Parser, field_qt: *QualType, attr_buf_start: usi
|
||||
// zig fmt: off
|
||||
.@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned,
|
||||
.mode, .warn_unused_result, .nodiscard, .nullability, .unaligned,
|
||||
=> try p.attr_application_buf.append(p.gpa, attr),
|
||||
=> try p.attr_application_buf.append(p.comp.gpa, attr),
|
||||
// zig fmt: on
|
||||
.vector_size => try attr.applyVectorSize(p, tok, field_qt),
|
||||
.aligned => try attr.applyAligned(p, field_qt.*, null),
|
||||
@ -884,6 +896,7 @@ pub fn applyFieldAttributes(p: *Parser, field_qt: *QualType, attr_buf_start: usi
|
||||
}
|
||||
|
||||
pub fn applyTypeAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diagnostic: ?Parser.Diagnostic) !QualType {
|
||||
const gpa = p.comp.gpa;
|
||||
const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
|
||||
const toks = p.attr_buf.items(.tok)[attr_buf_start..];
|
||||
p.attr_application_buf.items.len = 0;
|
||||
@ -891,13 +904,13 @@ pub fn applyTypeAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diag
|
||||
for (attrs, toks) |attr, tok| switch (attr.tag) {
|
||||
// zig fmt: off
|
||||
.@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode, .nullability, .unaligned,
|
||||
=> try p.attr_application_buf.append(p.gpa, attr),
|
||||
=> try p.attr_application_buf.append(gpa, attr),
|
||||
// zig fmt: on
|
||||
.transparent_union => try attr.applyTransparentUnion(p, tok, base_qt),
|
||||
.vector_size => try attr.applyVectorSize(p, tok, &base_qt),
|
||||
.aligned => try attr.applyAligned(p, base_qt, diagnostic),
|
||||
.designated_init => if (base_qt.is(p.comp, .@"struct")) {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
} else {
|
||||
try p.err(tok, .designated_init_invalid, .{});
|
||||
},
|
||||
@ -913,6 +926,7 @@ pub fn applyTypeAttributes(p: *Parser, qt: QualType, attr_buf_start: usize, diag
|
||||
}
|
||||
|
||||
pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize) !QualType {
|
||||
const gpa = p.comp.gpa;
|
||||
const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
|
||||
const toks = p.attr_buf.items(.tok)[attr_buf_start..];
|
||||
p.attr_application_buf.items.len = 0;
|
||||
@ -927,37 +941,37 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
.@"const", .warn_unused_result, .section, .returns_nonnull, .returns_twice, .@"error",
|
||||
.externally_visible, .retain, .flatten, .gnu_inline, .alias, .asm_label, .nodiscard,
|
||||
.reproducible, .unsequenced, .nothrow, .nullability, .unaligned,
|
||||
=> try p.attr_application_buf.append(p.gpa, attr),
|
||||
=> try p.attr_application_buf.append(gpa, attr),
|
||||
// zig fmt: on
|
||||
.hot => if (cold) {
|
||||
try p.err(tok, .ignore_hot, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
hot = true;
|
||||
},
|
||||
.cold => if (hot) {
|
||||
try p.err(tok, .ignore_cold, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
cold = true;
|
||||
},
|
||||
.always_inline => if (@"noinline") {
|
||||
try p.err(tok, .ignore_always_inline, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
always_inline = true;
|
||||
},
|
||||
.@"noinline" => if (always_inline) {
|
||||
try p.err(tok, .ignore_noinline, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
@"noinline" = true;
|
||||
},
|
||||
.aligned => try attr.applyAligned(p, base_qt, null),
|
||||
.format => try attr.applyFormat(p, base_qt),
|
||||
.calling_convention => try applyCallingConvention(attr, p, tok, base_qt),
|
||||
.fastcall => if (p.comp.target.cpu.arch == .x86) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .fastcall } },
|
||||
.syntax = attr.syntax,
|
||||
@ -966,7 +980,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
try p.err(tok, .callconv_not_supported, .{"fastcall"});
|
||||
},
|
||||
.stdcall => if (p.comp.target.cpu.arch == .x86) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .stdcall } },
|
||||
.syntax = attr.syntax,
|
||||
@ -975,7 +989,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
try p.err(tok, .callconv_not_supported, .{"stdcall"});
|
||||
},
|
||||
.thiscall => if (p.comp.target.cpu.arch == .x86) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .thiscall } },
|
||||
.syntax = attr.syntax,
|
||||
@ -984,7 +998,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
try p.err(tok, .callconv_not_supported, .{"thiscall"});
|
||||
},
|
||||
.vectorcall => if (p.comp.target.cpu.arch == .x86 or p.comp.target.cpu.arch.isAARCH64()) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .vectorcall } },
|
||||
.syntax = attr.syntax,
|
||||
@ -994,7 +1008,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
},
|
||||
.cdecl => {},
|
||||
.pcs => if (p.comp.target.cpu.arch.isArm()) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = switch (attr.args.pcs.kind) {
|
||||
.aapcs => .arm_aapcs,
|
||||
@ -1006,7 +1020,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
try p.err(tok, .callconv_not_supported, .{"pcs"});
|
||||
},
|
||||
.riscv_vector_cc => if (p.comp.target.cpu.arch.isRISCV()) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .riscv_vector } },
|
||||
.syntax = attr.syntax,
|
||||
@ -1015,7 +1029,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
try p.err(tok, .callconv_not_supported, .{"pcs"});
|
||||
},
|
||||
.aarch64_sve_pcs => if (p.comp.target.cpu.arch.isAARCH64()) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .aarch64_sve_pcs } },
|
||||
.syntax = attr.syntax,
|
||||
@ -1024,7 +1038,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
try p.err(tok, .callconv_not_supported, .{"pcs"});
|
||||
},
|
||||
.aarch64_vector_pcs => if (p.comp.target.cpu.arch.isAARCH64()) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .aarch64_vector_pcs } },
|
||||
.syntax = attr.syntax,
|
||||
@ -1033,14 +1047,14 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
try p.err(tok, .callconv_not_supported, .{"pcs"});
|
||||
},
|
||||
.sysv_abi => if (p.comp.target.cpu.arch == .x86_64 and p.comp.target.os.tag == .windows) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .x86_64_sysv } },
|
||||
.syntax = attr.syntax,
|
||||
});
|
||||
},
|
||||
.ms_abi => if (p.comp.target.cpu.arch == .x86_64 and p.comp.target.os.tag != .windows) {
|
||||
try p.attr_application_buf.append(p.gpa, .{
|
||||
try p.attr_application_buf.append(gpa, .{
|
||||
.tag = .calling_convention,
|
||||
.args = .{ .calling_convention = .{ .cc = .x86_64_win } },
|
||||
.syntax = attr.syntax,
|
||||
@ -1048,7 +1062,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
},
|
||||
.malloc => {
|
||||
if (base_qt.get(p.comp, .func).?.return_type.isPointer(p.comp)) {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
} else {
|
||||
try ignoredAttrErr(p, tok, attr.tag, "functions that do not return pointers");
|
||||
}
|
||||
@ -1065,7 +1079,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
if (!arg_sk.isInt() or !arg_sk.isReal()) {
|
||||
try p.err(tok, .alloc_align_required_int_param, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1098,7 +1112,7 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
.no_stack_protector,
|
||||
.noclone,
|
||||
.noipa,
|
||||
// .nonnull,
|
||||
.nonnull,
|
||||
.noplt,
|
||||
// .optimize,
|
||||
.patchable_function_entry,
|
||||
@ -1118,23 +1132,24 @@ pub fn applyFunctionAttributes(p: *Parser, qt: QualType, attr_buf_start: usize)
|
||||
}
|
||||
|
||||
pub fn applyLabelAttributes(p: *Parser, attr_buf_start: usize) !QualType {
|
||||
const gpa = p.comp.gpa;
|
||||
const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
|
||||
const toks = p.attr_buf.items(.tok)[attr_buf_start..];
|
||||
p.attr_application_buf.items.len = 0;
|
||||
var hot = false;
|
||||
var cold = false;
|
||||
for (attrs, toks) |attr, tok| switch (attr.tag) {
|
||||
.unused => try p.attr_application_buf.append(p.gpa, attr),
|
||||
.unused => try p.attr_application_buf.append(gpa, attr),
|
||||
.hot => if (cold) {
|
||||
try p.err(tok, .ignore_hot, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
hot = true;
|
||||
},
|
||||
.cold => if (hot) {
|
||||
try p.err(tok, .ignore_cold, .{});
|
||||
} else {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(gpa, attr);
|
||||
cold = true;
|
||||
},
|
||||
else => try ignoredAttrErr(p, tok, attr.tag, "labels"),
|
||||
@ -1151,7 +1166,7 @@ pub fn applyStatementAttributes(p: *Parser, expr_start: TokenIndex, attr_buf_sta
|
||||
for (p.tok_ids[p.tok_i..]) |tok_id| {
|
||||
switch (tok_id) {
|
||||
.keyword_case, .keyword_default, .eof => {
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(p.comp.gpa, attr);
|
||||
break;
|
||||
},
|
||||
.r_brace => {},
|
||||
@ -1172,7 +1187,7 @@ pub fn applyEnumeratorAttributes(p: *Parser, qt: QualType, attr_buf_start: usize
|
||||
const toks = p.attr_buf.items(.tok)[attr_buf_start..];
|
||||
p.attr_application_buf.items.len = 0;
|
||||
for (attrs, toks) |attr, tok| switch (attr.tag) {
|
||||
.deprecated, .unavailable => try p.attr_application_buf.append(p.gpa, attr),
|
||||
.deprecated, .unavailable => try p.attr_application_buf.append(p.comp.gpa, attr),
|
||||
else => try ignoredAttrErr(p, tok, attr.tag, "enums"),
|
||||
};
|
||||
return applySelected(qt, p);
|
||||
@ -1193,7 +1208,7 @@ fn applyAligned(attr: Attribute, p: *Parser, qt: QualType, diagnostic: ?Parser.D
|
||||
try p.err(align_tok, .minimum_alignment, .{default_align});
|
||||
}
|
||||
}
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(p.comp.gpa, attr);
|
||||
}
|
||||
|
||||
fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, qt: QualType) !void {
|
||||
@ -1214,7 +1229,7 @@ fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, qt: QualT
|
||||
return p.err(union_ty.fields[0].name_tok, .transparent_union_size_note, .{first_field_size});
|
||||
}
|
||||
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(p.comp.gpa, attr);
|
||||
}
|
||||
|
||||
fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, qt: *QualType) !void {
|
||||
@ -1245,7 +1260,7 @@ fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, qt: *QualType)
|
||||
return p.err(tok, .vec_size_not_multiple, .{});
|
||||
}
|
||||
|
||||
qt.* = try p.comp.type_store.put(p.gpa, .{ .vector = .{
|
||||
qt.* = try p.comp.type_store.put(p.comp.gpa, .{ .vector = .{
|
||||
.elem = qt.*,
|
||||
.len = @intCast(vec_bytes / elem_size),
|
||||
} });
|
||||
@ -1254,7 +1269,7 @@ fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, qt: *QualType)
|
||||
fn applyFormat(attr: Attribute, p: *Parser, qt: QualType) !void {
|
||||
// TODO validate
|
||||
_ = qt;
|
||||
try p.attr_application_buf.append(p.gpa, attr);
|
||||
try p.attr_application_buf.append(p.comp.gpa, attr);
|
||||
}
|
||||
|
||||
fn applyCallingConvention(attr: Attribute, p: *Parser, tok: TokenIndex, qt: QualType) !void {
|
||||
@ -1264,11 +1279,11 @@ fn applyCallingConvention(attr: Attribute, p: *Parser, tok: TokenIndex, qt: Qual
|
||||
switch (attr.args.calling_convention.cc) {
|
||||
.c => {},
|
||||
.stdcall, .thiscall, .fastcall, .regcall => switch (p.comp.target.cpu.arch) {
|
||||
.x86 => try p.attr_application_buf.append(p.gpa, attr),
|
||||
.x86 => try p.attr_application_buf.append(p.comp.gpa, attr),
|
||||
else => try p.err(tok, .callconv_not_supported, .{p.tok_ids[tok].symbol()}),
|
||||
},
|
||||
.vectorcall => switch (p.comp.target.cpu.arch) {
|
||||
.x86, .aarch64, .aarch64_be => try p.attr_application_buf.append(p.gpa, attr),
|
||||
.x86, .aarch64, .aarch64_be => try p.attr_application_buf.append(p.comp.gpa, attr),
|
||||
else => try p.err(tok, .callconv_not_supported, .{p.tok_ids[tok].symbol()}),
|
||||
},
|
||||
.riscv_vector,
|
||||
@ -1285,7 +1300,7 @@ fn applyCallingConvention(attr: Attribute, p: *Parser, tok: TokenIndex, qt: Qual
|
||||
fn applySelected(qt: QualType, p: *Parser) !QualType {
|
||||
if (p.attr_application_buf.items.len == 0) return qt;
|
||||
if (qt.isInvalid()) return qt;
|
||||
return (try p.comp.type_store.put(p.gpa, .{ .attributed = .{
|
||||
return (try p.comp.type_store.put(p.comp.gpa, .{ .attributed = .{
|
||||
.base = qt,
|
||||
.attributes = p.attr_application_buf.items,
|
||||
} })).withQualifiers(qt);
|
||||
|
||||
993
lib/compiler/aro/aro/Attribute/names.zig
vendored
993
lib/compiler/aro/aro/Attribute/names.zig
vendored
File diff suppressed because it is too large
Load Diff
9
lib/compiler/aro/aro/Builtins.zig
vendored
9
lib/compiler/aro/aro/Builtins.zig
vendored
@ -312,12 +312,13 @@ pub const Iterator = struct {
|
||||
};
|
||||
|
||||
test Iterator {
|
||||
const gpa = std.testing.allocator;
|
||||
var it = Iterator{};
|
||||
|
||||
var seen = std.StringHashMap(Builtin).init(std.testing.allocator);
|
||||
defer seen.deinit();
|
||||
var seen: std.StringHashMapUnmanaged(Builtin) = .empty;
|
||||
defer seen.deinit(gpa);
|
||||
|
||||
var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
var arena_state = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_state.deinit();
|
||||
const arena = arena_state.allocator();
|
||||
|
||||
@ -333,7 +334,7 @@ test Iterator {
|
||||
std.debug.print("previous data: {}\n", .{seen.get(entry.name).?});
|
||||
return error.TestExpectedUniqueEntries;
|
||||
}
|
||||
try seen.put(try arena.dupe(u8, entry.name), entry.builtin);
|
||||
try seen.put(gpa, try arena.dupe(u8, entry.name), entry.builtin);
|
||||
}
|
||||
try std.testing.expectEqual(@as(usize, Builtin.data.len), seen.count());
|
||||
}
|
||||
|
||||
17
lib/compiler/aro/aro/CodeGen.zig
vendored
17
lib/compiler/aro/aro/CodeGen.zig
vendored
@ -40,11 +40,11 @@ tree: *const Tree,
|
||||
comp: *Compilation,
|
||||
builder: Builder,
|
||||
wip_switch: *WipSwitch = undefined,
|
||||
symbols: std.ArrayListUnmanaged(Symbol) = .{},
|
||||
ret_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
|
||||
phi_nodes: std.ArrayListUnmanaged(Ir.Inst.Phi.Input) = .{},
|
||||
record_elem_buf: std.ArrayListUnmanaged(Interner.Ref) = .{},
|
||||
record_cache: std.AutoHashMapUnmanaged(QualType, Interner.Ref) = .{},
|
||||
symbols: std.ArrayList(Symbol) = .empty,
|
||||
ret_nodes: std.ArrayList(Ir.Inst.Phi.Input) = .empty,
|
||||
phi_nodes: std.ArrayList(Ir.Inst.Phi.Input) = .empty,
|
||||
record_elem_buf: std.ArrayList(Interner.Ref) = .empty,
|
||||
record_cache: std.AutoHashMapUnmanaged(QualType, Interner.Ref) = .empty,
|
||||
cond_dummy_ty: ?Interner.Ref = null,
|
||||
bool_invert: bool = false,
|
||||
bool_end_label: Ir.Ref = .none,
|
||||
@ -56,10 +56,11 @@ compound_assign_dummy: ?Ir.Ref = null,
|
||||
|
||||
fn fail(c: *CodeGen, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {
|
||||
var sf = std.heap.stackFallback(1024, c.comp.gpa);
|
||||
var buf = std.ArrayList(u8).init(sf.get());
|
||||
defer buf.deinit();
|
||||
const allocator = sf.get();
|
||||
var buf: std.ArrayList(u8) = .empty;
|
||||
defer buf.deinit(allocator);
|
||||
|
||||
try buf.print(fmt, args);
|
||||
try buf.print(allocator, fmt, args);
|
||||
try c.comp.diagnostics.add(.{ .text = buf.items, .kind = .@"fatal error", .location = null });
|
||||
return error.FatalError;
|
||||
}
|
||||
|
||||
109
lib/compiler/aro/aro/Compilation.zig
vendored
109
lib/compiler/aro/aro/Compilation.zig
vendored
@ -4,8 +4,9 @@ const EpochSeconds = std.time.epoch.EpochSeconds;
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
const Interner = @import("../backend.zig").Interner;
|
||||
const CodeGenOptions = @import("../backend.zig").CodeGenOptions;
|
||||
const backend = @import("../backend.zig");
|
||||
const Interner = backend.Interner;
|
||||
const CodeGenOptions = backend.CodeGenOptions;
|
||||
|
||||
const Builtins = @import("Builtins.zig");
|
||||
const Builtin = Builtins.Builtin;
|
||||
@ -127,24 +128,24 @@ diagnostics: *Diagnostics,
|
||||
|
||||
code_gen_options: CodeGenOptions = .default,
|
||||
environment: Environment = .{},
|
||||
sources: std.StringArrayHashMapUnmanaged(Source) = .{},
|
||||
sources: std.StringArrayHashMapUnmanaged(Source) = .empty,
|
||||
/// Allocated into `gpa`, but keys are externally managed.
|
||||
include_dirs: std.ArrayListUnmanaged([]const u8) = .empty,
|
||||
include_dirs: std.ArrayList([]const u8) = .empty,
|
||||
/// Allocated into `gpa`, but keys are externally managed.
|
||||
system_include_dirs: std.ArrayListUnmanaged([]const u8) = .empty,
|
||||
system_include_dirs: std.ArrayList([]const u8) = .empty,
|
||||
/// Allocated into `gpa`, but keys are externally managed.
|
||||
after_include_dirs: std.ArrayListUnmanaged([]const u8) = .empty,
|
||||
after_include_dirs: std.ArrayList([]const u8) = .empty,
|
||||
/// Allocated into `gpa`, but keys are externally managed.
|
||||
framework_dirs: std.ArrayListUnmanaged([]const u8) = .empty,
|
||||
framework_dirs: std.ArrayList([]const u8) = .empty,
|
||||
/// Allocated into `gpa`, but keys are externally managed.
|
||||
system_framework_dirs: std.ArrayListUnmanaged([]const u8) = .empty,
|
||||
system_framework_dirs: std.ArrayList([]const u8) = .empty,
|
||||
/// Allocated into `gpa`, but keys are externally managed.
|
||||
embed_dirs: std.ArrayListUnmanaged([]const u8) = .empty,
|
||||
embed_dirs: std.ArrayList([]const u8) = .empty,
|
||||
target: std.Target = @import("builtin").target,
|
||||
cmodel: std.builtin.CodeModel = .default,
|
||||
pragma_handlers: std.StringArrayHashMapUnmanaged(*Pragma) = .{},
|
||||
pragma_handlers: std.StringArrayHashMapUnmanaged(*Pragma) = .empty,
|
||||
langopts: LangOpts = .{},
|
||||
generated_buf: std.ArrayListUnmanaged(u8) = .{},
|
||||
generated_buf: std.ArrayList(u8) = .empty,
|
||||
builtins: Builtins = .{},
|
||||
string_interner: StringInterner = .{},
|
||||
interner: Interner = .{},
|
||||
@ -245,6 +246,13 @@ fn generateSystemDefines(comp: *Compilation, w: *std.Io.Writer) !void {
|
||||
try w.print("#define __GNUC_PATCHLEVEL__ {d}\n", .{comp.langopts.gnuc_version % 100});
|
||||
}
|
||||
|
||||
if (comp.code_gen_options.optimization_level.hasAnyOptimizations()) {
|
||||
try define(w, "__OPTIMIZE__");
|
||||
}
|
||||
if (comp.code_gen_options.optimization_level.isSizeOptimized()) {
|
||||
try define(w, "__OPTIMIZE_SIZE__");
|
||||
}
|
||||
|
||||
// os macros
|
||||
switch (comp.target.os.tag) {
|
||||
.linux => try defineStd(w, "linux", is_gnu),
|
||||
@ -1379,8 +1387,8 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
|
||||
const duped_path = try comp.gpa.dupe(u8, path);
|
||||
errdefer comp.gpa.free(duped_path);
|
||||
|
||||
var splice_list = std.array_list.Managed(u32).init(comp.gpa);
|
||||
defer splice_list.deinit();
|
||||
var splice_list: std.ArrayList(u32) = .empty;
|
||||
defer splice_list.deinit(comp.gpa);
|
||||
|
||||
const source_id: Source.Id = @enumFromInt(comp.sources.count() + 2);
|
||||
|
||||
@ -1413,9 +1421,9 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
|
||||
},
|
||||
.back_slash, .trailing_ws, .back_slash_cr => {
|
||||
i = backslash_loc;
|
||||
try splice_list.append(i);
|
||||
try splice_list.append(comp.gpa, i);
|
||||
if (state == .trailing_ws) {
|
||||
try comp.addNewlineEscapeError(path, buf, splice_list.items, i, line);
|
||||
try comp.addNewlineEscapeError(path, buf, splice_list.items, i, line, kind);
|
||||
}
|
||||
state = if (state == .back_slash_cr) .cr else .back_slash_cr;
|
||||
},
|
||||
@ -1433,10 +1441,10 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
|
||||
.back_slash, .trailing_ws => {
|
||||
i = backslash_loc;
|
||||
if (state == .back_slash or state == .trailing_ws) {
|
||||
try splice_list.append(i);
|
||||
try splice_list.append(comp.gpa, i);
|
||||
}
|
||||
if (state == .trailing_ws) {
|
||||
try comp.addNewlineEscapeError(path, buf, splice_list.items, i, line);
|
||||
try comp.addNewlineEscapeError(path, buf, splice_list.items, i, line, kind);
|
||||
}
|
||||
},
|
||||
.bom1, .bom2 => break,
|
||||
@ -1486,11 +1494,11 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
|
||||
}
|
||||
}
|
||||
|
||||
const splice_locs = try splice_list.toOwnedSlice();
|
||||
const splice_locs = try splice_list.toOwnedSlice(comp.gpa);
|
||||
errdefer comp.gpa.free(splice_locs);
|
||||
|
||||
if (i != contents.len) {
|
||||
var list: std.ArrayListUnmanaged(u8) = .{
|
||||
var list: std.ArrayList(u8) = .{
|
||||
.items = contents[0..i],
|
||||
.capacity = contents.len,
|
||||
};
|
||||
@ -1510,13 +1518,21 @@ pub fn addSourceFromOwnedBuffer(comp: *Compilation, path: []const u8, buf: []u8,
|
||||
return source;
|
||||
}
|
||||
|
||||
fn addNewlineEscapeError(comp: *Compilation, path: []const u8, buf: []const u8, splice_locs: []const u32, byte_offset: u32, line: u32) !void {
|
||||
fn addNewlineEscapeError(
|
||||
comp: *Compilation,
|
||||
path: []const u8,
|
||||
buf: []const u8,
|
||||
splice_locs: []const u32,
|
||||
byte_offset: u32,
|
||||
line: u32,
|
||||
kind: Source.Kind,
|
||||
) !void {
|
||||
// Temporary source for getting the location for errors.
|
||||
var tmp_source: Source = .{
|
||||
.path = path,
|
||||
.buf = buf,
|
||||
.id = undefined,
|
||||
.kind = undefined,
|
||||
.kind = kind,
|
||||
.splice_locs = splice_locs,
|
||||
};
|
||||
|
||||
@ -1566,17 +1582,7 @@ fn addSourceFromPathExtra(comp: *Compilation, path: []const u8, kind: Source.Kin
|
||||
}
|
||||
|
||||
pub fn addSourceFromFile(comp: *Compilation, file: std.fs.File, path: []const u8, kind: Source.Kind) !Source {
|
||||
var file_buf: [4096]u8 = undefined;
|
||||
var file_reader = file.reader(&file_buf);
|
||||
if (try file_reader.getSize() > std.math.maxInt(u32)) return error.FileTooBig;
|
||||
|
||||
var allocating: std.Io.Writer.Allocating = .init(comp.gpa);
|
||||
_ = allocating.writer.sendFileAll(&file_reader, .limited(std.math.maxInt(u32))) catch |e| switch (e) {
|
||||
error.WriteFailed => return error.OutOfMemory,
|
||||
error.ReadFailed => return file_reader.err.?,
|
||||
};
|
||||
|
||||
const contents = try allocating.toOwnedSlice();
|
||||
const contents = try comp.getFileContents(file, .unlimited);
|
||||
errdefer comp.gpa.free(contents);
|
||||
return comp.addSourceFromOwnedBuffer(path, contents, kind);
|
||||
}
|
||||
@ -1671,7 +1677,7 @@ const FindInclude = struct {
|
||||
if (try find.checkFrameworkDir(dir, .system)) |res| return res;
|
||||
}
|
||||
for (comp.after_include_dirs.items) |dir| {
|
||||
if (try find.checkIncludeDir(dir, .user)) |res| return res;
|
||||
if (try find.checkIncludeDir(dir, .system)) |res| return res;
|
||||
}
|
||||
if (comp.ms_cwd_source_id) |source_id| {
|
||||
if (try find.checkMsCwdIncludeDir(source_id)) |res| return res;
|
||||
@ -1766,26 +1772,38 @@ pub const IncludeType = enum {
|
||||
angle_brackets,
|
||||
};
|
||||
|
||||
fn getFileContents(comp: *Compilation, path: []const u8, limit: std.Io.Limit) ![]const u8 {
|
||||
fn getPathContents(comp: *Compilation, path: []const u8, limit: std.Io.Limit) ![]u8 {
|
||||
if (mem.indexOfScalar(u8, path, 0) != null) {
|
||||
return error.FileNotFound;
|
||||
}
|
||||
|
||||
const file = try comp.cwd.openFile(path, .{});
|
||||
defer file.close();
|
||||
return comp.getFileContents(file, limit);
|
||||
}
|
||||
|
||||
fn getFileContents(comp: *Compilation, file: std.fs.File, limit: std.Io.Limit) ![]u8 {
|
||||
var file_buf: [4096]u8 = undefined;
|
||||
var file_reader = file.reader(&file_buf);
|
||||
|
||||
var allocating: std.Io.Writer.Allocating = .init(comp.gpa);
|
||||
defer allocating.deinit();
|
||||
if (file_reader.getSize()) |size| {
|
||||
const limited_size = limit.minInt64(size);
|
||||
if (limited_size > std.math.maxInt(u32)) return error.FileTooBig;
|
||||
try allocating.ensureUnusedCapacity(limited_size);
|
||||
} else |_| {}
|
||||
|
||||
var file_buf: [4096]u8 = undefined;
|
||||
var file_reader = file.reader(&file_buf);
|
||||
if (limit.minInt64(try file_reader.getSize()) > std.math.maxInt(u32)) return error.FileTooBig;
|
||||
|
||||
_ = allocating.writer.sendFileAll(&file_reader, limit) catch |err| switch (err) {
|
||||
var remaining = limit.min(.limited(std.math.maxInt(u32)));
|
||||
while (remaining.nonzero()) {
|
||||
const n = file_reader.interface.stream(&allocating.writer, remaining) catch |err| switch (err) {
|
||||
error.EndOfStream => return allocating.toOwnedSlice(),
|
||||
error.WriteFailed => return error.OutOfMemory,
|
||||
error.ReadFailed => return file_reader.err.?,
|
||||
};
|
||||
|
||||
remaining = remaining.subtract(n).?;
|
||||
}
|
||||
if (limit == .unlimited) return error.FileTooBig;
|
||||
return allocating.toOwnedSlice();
|
||||
}
|
||||
|
||||
@ -1797,9 +1815,10 @@ pub fn findEmbed(
|
||||
include_type: IncludeType,
|
||||
limit: std.Io.Limit,
|
||||
opt_dep_file: ?*DepFile,
|
||||
) !?[]const u8 {
|
||||
) !?[]u8 {
|
||||
if (std.fs.path.isAbsolute(filename)) {
|
||||
if (comp.getFileContents(filename, limit)) |some| {
|
||||
if (comp.getPathContents(filename, limit)) |some| {
|
||||
errdefer comp.gpa.free(some);
|
||||
if (opt_dep_file) |dep_file| try dep_file.addDependencyDupe(comp.gpa, comp.arena, filename);
|
||||
return some;
|
||||
} else |err| switch (err) {
|
||||
@ -1819,7 +1838,8 @@ pub fn findEmbed(
|
||||
if (comp.langopts.ms_extensions) {
|
||||
std.mem.replaceScalar(u8, path, '\\', '/');
|
||||
}
|
||||
if (comp.getFileContents(path, limit)) |some| {
|
||||
if (comp.getPathContents(path, limit)) |some| {
|
||||
errdefer comp.gpa.free(some);
|
||||
if (opt_dep_file) |dep_file| try dep_file.addDependencyDupe(comp.gpa, comp.arena, filename);
|
||||
return some;
|
||||
} else |err| switch (err) {
|
||||
@ -1835,7 +1855,8 @@ pub fn findEmbed(
|
||||
if (comp.langopts.ms_extensions) {
|
||||
std.mem.replaceScalar(u8, path, '\\', '/');
|
||||
}
|
||||
if (comp.getFileContents(path, limit)) |some| {
|
||||
if (comp.getPathContents(path, limit)) |some| {
|
||||
errdefer comp.gpa.free(some);
|
||||
if (opt_dep_file) |dep_file| try dep_file.addDependencyDupe(comp.gpa, comp.arena, filename);
|
||||
return some;
|
||||
} else |err| switch (err) {
|
||||
|
||||
33
lib/compiler/aro/aro/DepFile.zig
vendored
33
lib/compiler/aro/aro/DepFile.zig
vendored
@ -28,7 +28,7 @@ pub fn write(d: *const DepFile, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||
const max_columns = 75;
|
||||
var columns: usize = 0;
|
||||
|
||||
try w.writeAll(d.target);
|
||||
try writeTarget(d.target, w);
|
||||
columns += d.target.len;
|
||||
try w.writeByte(':');
|
||||
columns += 1;
|
||||
@ -48,6 +48,26 @@ pub fn write(d: *const DepFile, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||
try w.flush();
|
||||
}
|
||||
|
||||
fn writeTarget(path: []const u8, w: *std.Io.Writer) !void {
|
||||
for (path, 0..) |c, i| {
|
||||
switch (c) {
|
||||
' ', '\t' => {
|
||||
try w.writeByte('\\');
|
||||
var j = i;
|
||||
while (j != 0) {
|
||||
j -= 1;
|
||||
if (path[j] != '\\') break;
|
||||
try w.writeByte('\\');
|
||||
}
|
||||
},
|
||||
'$' => try w.writeByte('$'),
|
||||
'#' => try w.writeByte('\\'),
|
||||
else => {},
|
||||
}
|
||||
try w.writeByte(c);
|
||||
}
|
||||
}
|
||||
|
||||
fn writePath(d: *const DepFile, path: []const u8, w: *std.Io.Writer) !void {
|
||||
switch (d.format) {
|
||||
.nmake => {
|
||||
@ -58,11 +78,8 @@ fn writePath(d: *const DepFile, path: []const u8, w: *std.Io.Writer) !void {
|
||||
},
|
||||
.make => {
|
||||
for (path, 0..) |c, i| {
|
||||
if (c == '#') {
|
||||
try w.writeByte('\\');
|
||||
} else if (c == '$') {
|
||||
try w.writeByte('$');
|
||||
} else if (c == ' ') {
|
||||
switch (c) {
|
||||
' ' => {
|
||||
try w.writeByte('\\');
|
||||
var j = i;
|
||||
while (j != 0) {
|
||||
@ -70,6 +87,10 @@ fn writePath(d: *const DepFile, path: []const u8, w: *std.Io.Writer) !void {
|
||||
if (path[j] != '\\') break;
|
||||
try w.writeByte('\\');
|
||||
}
|
||||
},
|
||||
'$' => try w.writeByte('$'),
|
||||
'#' => try w.writeByte('\\'),
|
||||
else => {},
|
||||
}
|
||||
try w.writeByte(c);
|
||||
}
|
||||
|
||||
20
lib/compiler/aro/aro/Diagnostics.zig
vendored
20
lib/compiler/aro/aro/Diagnostics.zig
vendored
@ -193,6 +193,8 @@ pub const Option = enum {
|
||||
@"microsoft-flexible-array",
|
||||
@"microsoft-anon-tag",
|
||||
@"out-of-scope-function",
|
||||
@"date-time",
|
||||
@"attribute-todo",
|
||||
|
||||
/// GNU extensions
|
||||
pub const gnu = [_]Option{
|
||||
@ -278,6 +280,8 @@ pub const State = struct {
|
||||
extensions: Message.Kind = .off,
|
||||
/// How to treat individual options, set by -W<name>
|
||||
options: std.EnumMap(Option, Message.Kind) = .{},
|
||||
/// Should warnings be suppressed in system headers, set by -Wsystem-headers
|
||||
suppress_system_headers: bool = true,
|
||||
};
|
||||
|
||||
const Diagnostics = @This();
|
||||
@ -288,7 +292,7 @@ output: union(enum) {
|
||||
color: std.Io.tty.Config,
|
||||
},
|
||||
to_list: struct {
|
||||
messages: std.ArrayListUnmanaged(Message) = .empty,
|
||||
messages: std.ArrayList(Message) = .empty,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
},
|
||||
ignore,
|
||||
@ -373,6 +377,16 @@ pub fn effectiveKind(d: *Diagnostics, message: anytype) Message.Kind {
|
||||
return .off;
|
||||
}
|
||||
|
||||
if (@hasField(@TypeOf(message), "location")) {
|
||||
if (message.location) |location| {
|
||||
if (location.kind != .user and d.state.suppress_system_headers and
|
||||
(message.kind == .warning or message.kind == .off))
|
||||
{
|
||||
return .off;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var kind = message.kind;
|
||||
|
||||
// Get explicit kind set by -W<name>=
|
||||
@ -418,9 +432,9 @@ pub fn addWithLocation(
|
||||
note_msg_loc: bool,
|
||||
) Compilation.Error!void {
|
||||
var copy = msg;
|
||||
copy.effective_kind = d.effectiveKind(msg);
|
||||
if (copy.effective_kind == .off) return;
|
||||
if (expansion_locs.len != 0) copy.location = expansion_locs[expansion_locs.len - 1].expand(comp);
|
||||
copy.effective_kind = d.effectiveKind(copy);
|
||||
if (copy.effective_kind == .off) return;
|
||||
try d.addMessage(copy);
|
||||
|
||||
if (expansion_locs.len != 0) {
|
||||
|
||||
44
lib/compiler/aro/aro/Driver.zig
vendored
44
lib/compiler/aro/aro/Driver.zig
vendored
@ -45,8 +45,8 @@ const Driver = @This();
|
||||
comp: *Compilation,
|
||||
diagnostics: *Diagnostics,
|
||||
|
||||
inputs: std.ArrayListUnmanaged(Source) = .{},
|
||||
link_objects: std.ArrayListUnmanaged([]const u8) = .{},
|
||||
inputs: std.ArrayList(Source) = .empty,
|
||||
link_objects: std.ArrayList([]const u8) = .empty,
|
||||
output_name: ?[]const u8 = null,
|
||||
sysroot: ?[]const u8 = null,
|
||||
resource_dir: ?[]const u8 = null,
|
||||
@ -107,7 +107,6 @@ raw_cpu: ?[]const u8 = null,
|
||||
use_assembly_backend: bool = false,
|
||||
|
||||
// linker options
|
||||
use_linker: ?[]const u8 = null,
|
||||
linker_path: ?[]const u8 = null,
|
||||
nodefaultlibs: bool = false,
|
||||
nolibc: bool = false,
|
||||
@ -270,7 +269,7 @@ pub const usage =
|
||||
pub fn parseArgs(
|
||||
d: *Driver,
|
||||
stdout: *std.Io.Writer,
|
||||
macro_buf: *std.ArrayListUnmanaged(u8),
|
||||
macro_buf: *std.ArrayList(u8),
|
||||
args: []const []const u8,
|
||||
) (Compilation.Error || std.Io.Writer.Error)!bool {
|
||||
var i: usize = 1;
|
||||
@ -322,7 +321,7 @@ pub fn parseArgs(
|
||||
}
|
||||
try macro_buf.print(d.comp.gpa, "#undef {s}\n", .{macro});
|
||||
} else if (mem.eql(u8, arg, "-O")) {
|
||||
d.comp.code_gen_options.optimization_level = .@"0";
|
||||
d.comp.code_gen_options.optimization_level = .@"1";
|
||||
} else if (mem.startsWith(u8, arg, "-O")) {
|
||||
d.comp.code_gen_options.optimization_level = backend.CodeGenOptions.OptimizationLevel.fromString(arg["-O".len..]) orelse {
|
||||
try d.err("invalid optimization level '{s}'", .{arg});
|
||||
@ -600,6 +599,10 @@ pub fn parseArgs(
|
||||
d.diagnostics.state.enable_all_warnings = false;
|
||||
} else if (mem.eql(u8, arg, "-Weverything")) {
|
||||
d.diagnostics.state.enable_all_warnings = true;
|
||||
} else if (mem.eql(u8, arg, "-Wno-system-headers")) {
|
||||
d.diagnostics.state.suppress_system_headers = true;
|
||||
} else if (mem.eql(u8, arg, "-Wsystem-headers")) {
|
||||
d.diagnostics.state.suppress_system_headers = false;
|
||||
} else if (mem.eql(u8, arg, "-Werror")) {
|
||||
d.diagnostics.state.error_warnings = true;
|
||||
} else if (mem.eql(u8, arg, "-Wno-error")) {
|
||||
@ -644,10 +647,6 @@ pub fn parseArgs(
|
||||
d.comp.langopts.preserve_comments = true;
|
||||
d.comp.langopts.preserve_comments_in_macros = true;
|
||||
comment_arg = arg;
|
||||
} else if (option(arg, "-fuse-ld=")) |linker_name| {
|
||||
d.use_linker = linker_name;
|
||||
} else if (mem.eql(u8, arg, "-fuse-ld=")) {
|
||||
d.use_linker = null;
|
||||
} else if (option(arg, "--ld-path=")) |linker_path| {
|
||||
d.linker_path = linker_path;
|
||||
} else if (mem.eql(u8, arg, "-r")) {
|
||||
@ -917,13 +916,11 @@ pub fn errorDescription(e: anyerror) []const u8 {
|
||||
};
|
||||
}
|
||||
|
||||
var stdout_buffer: [4096]u8 = undefined;
|
||||
|
||||
/// The entry point of the Aro compiler.
|
||||
/// **MAY call `exit` if `fast_exit` is set.**
|
||||
pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_exit: bool, asm_gen_fn: ?AsmCodeGenFn) Compilation.Error!void {
|
||||
const user_macros = macros: {
|
||||
var macro_buf: std.ArrayListUnmanaged(u8) = .empty;
|
||||
var macro_buf: std.ArrayList(u8) = .empty;
|
||||
defer macro_buf.deinit(d.comp.gpa);
|
||||
|
||||
var stdout_buf: [256]u8 = undefined;
|
||||
@ -1107,7 +1104,7 @@ fn processSource(
|
||||
|
||||
var name_buf: [std.fs.max_name_bytes]u8 = undefined;
|
||||
var opt_dep_file = try d.initDepFile(source, &name_buf, false);
|
||||
defer if (opt_dep_file) |*dep_file| dep_file.deinit(pp.gpa);
|
||||
defer if (opt_dep_file) |*dep_file| dep_file.deinit(d.comp.gpa);
|
||||
|
||||
if (opt_dep_file) |*dep_file| pp.dep_file = dep_file;
|
||||
|
||||
@ -1164,14 +1161,11 @@ fn processSource(
|
||||
else
|
||||
std.fs.File.stdout();
|
||||
defer if (d.output_name != null) file.close();
|
||||
var file_buffer: [1024]u8 = undefined;
|
||||
var file_writer = file.writer(&file_buffer);
|
||||
|
||||
pp.prettyPrintTokens(&file_writer.interface, dump_mode) catch |er|
|
||||
return d.fatal("unable to write result: {s}", .{errorDescription(er)});
|
||||
var file_writer = file.writer(&writer_buf);
|
||||
pp.prettyPrintTokens(&file_writer.interface, dump_mode) catch
|
||||
return d.fatal("unable to write result: {s}", .{errorDescription(file_writer.err.?)});
|
||||
|
||||
file_writer.interface.flush() catch |er|
|
||||
return d.fatal("unable to write result: {s}", .{errorDescription(er)});
|
||||
if (fast_exit) std.process.exit(0); // Not linking, no need for cleanup.
|
||||
return;
|
||||
}
|
||||
@ -1180,9 +1174,8 @@ fn processSource(
|
||||
defer tree.deinit();
|
||||
|
||||
if (d.verbose_ast) {
|
||||
var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
|
||||
tree.dump(d.detectConfig(.stdout()), &stdout_writer.interface) catch {};
|
||||
stdout_writer.interface.flush() catch {};
|
||||
var stdout = std.fs.File.stdout().writer(&writer_buf);
|
||||
tree.dump(d.detectConfig(stdout.file), &stdout.interface) catch {};
|
||||
}
|
||||
|
||||
d.printDiagnosticsStats();
|
||||
@ -1299,12 +1292,13 @@ fn dumpLinkerArgs(w: *std.Io.Writer, items: []const []const u8) !void {
|
||||
/// The entry point of the Aro compiler.
|
||||
/// **MAY call `exit` if `fast_exit` is set.**
|
||||
pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) Compilation.Error!void {
|
||||
var argv = std.array_list.Managed([]const u8).init(d.comp.gpa);
|
||||
defer argv.deinit();
|
||||
const gpa = d.comp.gpa;
|
||||
var argv: std.ArrayList([]const u8) = .empty;
|
||||
defer argv.deinit(gpa);
|
||||
|
||||
var linker_path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
const linker_path = try tc.getLinkerPath(&linker_path_buf);
|
||||
try argv.append(linker_path);
|
||||
try argv.append(gpa, linker_path);
|
||||
|
||||
try tc.buildLinkerArgs(&argv);
|
||||
|
||||
|
||||
55
lib/compiler/aro/aro/Driver/Multilib.zig
vendored
55
lib/compiler/aro/aro/Driver/Multilib.zig
vendored
@ -1,47 +1,50 @@
|
||||
const std = @import("std");
|
||||
const Filesystem = @import("Filesystem.zig").Filesystem;
|
||||
|
||||
pub const Flags = std.ArrayListUnmanaged([]const u8);
|
||||
|
||||
/// Large enough for GCCDetector for Linux; may need to be increased to support other toolchains.
|
||||
const max_multilibs = 4;
|
||||
|
||||
const MultilibArray = std.ArrayListUnmanaged(Multilib);
|
||||
|
||||
pub const Detected = struct {
|
||||
multilibs: MultilibArray = .{},
|
||||
multilib_buf: [max_multilibs]Multilib = undefined,
|
||||
multilib_count: u8 = 0,
|
||||
selected: Multilib = .{},
|
||||
biarch_sibling: ?Multilib = null,
|
||||
|
||||
pub fn filter(self: *Detected, multilib_filter: Filter, fs: Filesystem) void {
|
||||
var found_count: usize = 0;
|
||||
for (self.multilibs.items) |multilib| {
|
||||
pub fn filter(d: *Detected, multilib_filter: Filter, fs: Filesystem) void {
|
||||
var found_count: u8 = 0;
|
||||
for (d.multilibs()) |multilib| {
|
||||
if (multilib_filter.exists(multilib, fs)) {
|
||||
self.multilibs.items[found_count] = multilib;
|
||||
d.multilib_buf[found_count] = multilib;
|
||||
found_count += 1;
|
||||
}
|
||||
}
|
||||
self.multilibs.resize(found_count) catch unreachable;
|
||||
d.multilib_count = found_count;
|
||||
}
|
||||
|
||||
pub fn select(self: *Detected, flags: []const []const Flags) !bool {
|
||||
var filtered: MultilibArray = .{};
|
||||
for (self.multilibs.items) |multilib| {
|
||||
for (flags) |multilib_flag| {
|
||||
const matched = for (flags) |arg_flag| {
|
||||
pub fn select(d: *Detected, check_flags: []const []const u8) !bool {
|
||||
var selected: ?Multilib = null;
|
||||
|
||||
for (d.multilibs()) |multilib| {
|
||||
for (multilib.flags()) |multilib_flag| {
|
||||
const matched = for (check_flags) |arg_flag| {
|
||||
if (std.mem.eql(u8, arg_flag[1..], multilib_flag[1..])) break arg_flag;
|
||||
} else multilib_flag;
|
||||
if (matched[0] != multilib_flag[0]) break;
|
||||
} else if (selected != null) {
|
||||
return error.TooManyMultilibs;
|
||||
} else {
|
||||
filtered.appendAssumeCapacity(multilib);
|
||||
selected = multilib;
|
||||
}
|
||||
}
|
||||
if (filtered.len == 0) return false;
|
||||
if (filtered.len == 1) {
|
||||
self.selected = filtered.get(0);
|
||||
if (selected) |multilib| {
|
||||
d.selected = multilib;
|
||||
return true;
|
||||
}
|
||||
return error.TooManyMultilibs;
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn multilibs(d: *const Detected) []const Multilib {
|
||||
return d.multilib_buf[0..d.multilib_count];
|
||||
}
|
||||
};
|
||||
|
||||
@ -58,14 +61,20 @@ const Multilib = @This();
|
||||
gcc_suffix: []const u8 = "",
|
||||
os_suffix: []const u8 = "",
|
||||
include_suffix: []const u8 = "",
|
||||
flags: Flags = .{},
|
||||
flag_buf: [6][]const u8 = undefined,
|
||||
flag_count: u8 = 0,
|
||||
priority: u32 = 0,
|
||||
|
||||
pub fn init(gcc_suffix: []const u8, os_suffix: []const u8, flags: []const []const u8) Multilib {
|
||||
pub fn init(gcc_suffix: []const u8, os_suffix: []const u8, init_flags: []const []const u8) Multilib {
|
||||
var self: Multilib = .{
|
||||
.gcc_suffix = gcc_suffix,
|
||||
.os_suffix = os_suffix,
|
||||
.flag_count = @intCast(init_flags.len),
|
||||
};
|
||||
self.flags.appendSliceAssumeCapacity(flags);
|
||||
@memcpy(self.flag_buf[0..init_flags.len], init_flags);
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn flags(m: *const Multilib) []const []const u8 {
|
||||
return m.flag_buf[0..m.flag_count];
|
||||
}
|
||||
|
||||
2
lib/compiler/aro/aro/InitList.zig
vendored
2
lib/compiler/aro/aro/InitList.zig
vendored
@ -22,7 +22,7 @@ const Item = struct {
|
||||
|
||||
const InitList = @This();
|
||||
|
||||
list: std.ArrayListUnmanaged(Item) = .empty,
|
||||
list: std.ArrayList(Item) = .empty,
|
||||
node: Node.OptIndex = .null,
|
||||
tok: TokenIndex = 0,
|
||||
|
||||
|
||||
512
lib/compiler/aro/aro/Parser.zig
vendored
512
lib/compiler/aro/aro/Parser.zig
vendored
File diff suppressed because it is too large
Load Diff
27
lib/compiler/aro/aro/Parser/Diagnostic.zig
vendored
27
lib/compiler/aro/aro/Parser/Diagnostic.zig
vendored
@ -2304,6 +2304,7 @@ pub const overflow_result_requires_ptr: Diagnostic = .{
|
||||
pub const attribute_todo: Diagnostic = .{
|
||||
.fmt = "TODO: implement '{s}' attribute for {s}",
|
||||
.kind = .warning,
|
||||
.opt = .@"attribute-todo",
|
||||
};
|
||||
|
||||
pub const invalid_type_underlying_enum: Diagnostic = .{
|
||||
@ -2395,3 +2396,29 @@ pub const invalid_nullability: Diagnostic = .{
|
||||
.fmt = "nullability specifier cannot be applied to non-pointer type {qt}",
|
||||
.kind = .@"error",
|
||||
};
|
||||
|
||||
pub const array_not_assignable: Diagnostic = .{
|
||||
.fmt = "array type {qt} is not assignable",
|
||||
.kind = .@"error",
|
||||
};
|
||||
|
||||
pub const non_object_not_assignable: Diagnostic = .{
|
||||
.fmt = "non-object type {qt} is not assignable",
|
||||
.kind = .@"error",
|
||||
};
|
||||
|
||||
pub const const_var_assignment: Diagnostic = .{
|
||||
.fmt = "cannot assign to variable '{s}' with const-qualified type {qt}",
|
||||
.kind = .@"error",
|
||||
};
|
||||
|
||||
pub const declared_const_here: Diagnostic = .{
|
||||
.fmt = "variable '{s}' declared const here",
|
||||
.kind = .note,
|
||||
};
|
||||
|
||||
pub const nonnull_not_applicable: Diagnostic = .{
|
||||
.fmt = "'nonnull' attribute only applies to functions, methods, and parameters",
|
||||
.kind = .warning,
|
||||
.opt = .@"ignored-attributes",
|
||||
};
|
||||
|
||||
4
lib/compiler/aro/aro/Pragma.zig
vendored
4
lib/compiler/aro/aro/Pragma.zig
vendored
@ -60,7 +60,7 @@ pub fn pasteTokens(pp: *Preprocessor, start_idx: TokenIndex) ![]const u8 {
|
||||
.string_literal => {
|
||||
if (rparen_count != 0) return error.ExpectedStringLiteral;
|
||||
const str = pp.expandedSlice(tok);
|
||||
try pp.char_buf.appendSlice(str[1 .. str.len - 1]);
|
||||
try pp.char_buf.appendSlice(pp.comp.gpa, str[1 .. str.len - 1]);
|
||||
},
|
||||
else => return error.ExpectedStringLiteral,
|
||||
}
|
||||
@ -194,7 +194,7 @@ pub const Diagnostic = struct {
|
||||
};
|
||||
|
||||
pub fn err(pp: *Preprocessor, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) Compilation.Error!void {
|
||||
var sf = std.heap.stackFallback(1024, pp.gpa);
|
||||
var sf = std.heap.stackFallback(1024, pp.comp.gpa);
|
||||
var allocating: std.Io.Writer.Allocating = .init(sf.get());
|
||||
defer allocating.deinit();
|
||||
|
||||
|
||||
520
lib/compiler/aro/aro/Preprocessor.zig
vendored
520
lib/compiler/aro/aro/Preprocessor.zig
vendored
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,7 @@ fmt: []const u8,
|
||||
kind: Diagnostics.Message.Kind,
|
||||
opt: ?Diagnostics.Option = null,
|
||||
extension: bool = false,
|
||||
show_in_system_headers: bool = false,
|
||||
|
||||
pub const elif_without_if: Diagnostic = .{
|
||||
.fmt = "#elif without #if",
|
||||
@ -91,6 +92,7 @@ pub const warning_directive: Diagnostic = .{
|
||||
.fmt = "{s}",
|
||||
.opt = .@"#warnings",
|
||||
.kind = .warning,
|
||||
.show_in_system_headers = true,
|
||||
};
|
||||
|
||||
pub const macro_name_missing: Diagnostic = .{
|
||||
@ -440,3 +442,10 @@ pub const invalid_source_epoch: Diagnostic = .{
|
||||
.fmt = "environment variable SOURCE_DATE_EPOCH must expand to a non-negative integer less than or equal to 253402300799",
|
||||
.kind = .@"error",
|
||||
};
|
||||
|
||||
pub const date_time: Diagnostic = .{
|
||||
.fmt = "expansion of date or time macro is not reproducible",
|
||||
.kind = .off,
|
||||
.opt = .@"date-time",
|
||||
.show_in_system_headers = true,
|
||||
};
|
||||
|
||||
2
lib/compiler/aro/aro/Source.zig
vendored
2
lib/compiler/aro/aro/Source.zig
vendored
@ -38,6 +38,7 @@ pub const ExpandedLocation = struct {
|
||||
col: u32,
|
||||
width: u32,
|
||||
end_with_splice: bool,
|
||||
kind: Kind,
|
||||
};
|
||||
|
||||
const Source = @This();
|
||||
@ -120,6 +121,7 @@ pub fn lineCol(source: Source, loc: Location) ExpandedLocation {
|
||||
.col = col,
|
||||
.width = width,
|
||||
.end_with_splice = end_with_splice,
|
||||
.kind = source.kind,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
20
lib/compiler/aro/aro/SymbolStack.zig
vendored
20
lib/compiler/aro/aro/SymbolStack.zig
vendored
@ -35,14 +35,14 @@ pub const Kind = enum {
|
||||
constexpr,
|
||||
};
|
||||
|
||||
scopes: std.ArrayListUnmanaged(Scope) = .{},
|
||||
scopes: std.ArrayList(Scope) = .empty,
|
||||
/// allocations from nested scopes are retained after popping; `active_len` is the number
|
||||
/// of currently-active items in `scopes`.
|
||||
active_len: usize = 0,
|
||||
|
||||
const Scope = struct {
|
||||
vars: std.AutoHashMapUnmanaged(StringId, Symbol) = .{},
|
||||
tags: std.AutoHashMapUnmanaged(StringId, Symbol) = .{},
|
||||
vars: std.AutoHashMapUnmanaged(StringId, Symbol) = .empty,
|
||||
tags: std.AutoHashMapUnmanaged(StringId, Symbol) = .empty,
|
||||
|
||||
fn deinit(self: *Scope, allocator: Allocator) void {
|
||||
self.vars.deinit(allocator);
|
||||
@ -66,7 +66,7 @@ pub fn deinit(s: *SymbolStack, gpa: Allocator) void {
|
||||
|
||||
pub fn pushScope(s: *SymbolStack, p: *Parser) !void {
|
||||
if (s.active_len + 1 > s.scopes.items.len) {
|
||||
try s.scopes.append(p.gpa, .{});
|
||||
try s.scopes.append(p.comp.gpa, .{});
|
||||
s.active_len = s.scopes.items.len;
|
||||
} else {
|
||||
s.scopes.items[s.active_len].clearRetainingCapacity();
|
||||
@ -195,7 +195,7 @@ pub fn defineTypedef(
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
try s.define(p.gpa, .{
|
||||
try s.define(p.comp.gpa, .{
|
||||
.kind = .typedef,
|
||||
.name = name,
|
||||
.tok = tok,
|
||||
@ -245,7 +245,7 @@ pub fn defineSymbol(
|
||||
}
|
||||
}
|
||||
|
||||
try s.define(p.gpa, .{
|
||||
try s.define(p.comp.gpa, .{
|
||||
.kind = if (constexpr) .constexpr else .def,
|
||||
.name = name,
|
||||
.tok = tok,
|
||||
@ -306,7 +306,7 @@ pub fn declareSymbol(
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
try s.define(p.gpa, .{
|
||||
try s.define(p.comp.gpa, .{
|
||||
.kind = .decl,
|
||||
.name = name,
|
||||
.tok = tok,
|
||||
@ -317,7 +317,7 @@ pub fn declareSymbol(
|
||||
|
||||
// Declare out of scope symbol for functions declared in functions.
|
||||
if (s.active_len > 1 and !p.comp.langopts.standard.atLeast(.c23) and qt.is(p.comp, .func)) {
|
||||
try s.scopes.items[0].vars.put(p.gpa, name, .{
|
||||
try s.scopes.items[0].vars.put(p.comp.gpa, name, .{
|
||||
.kind = .decl,
|
||||
.name = name,
|
||||
.tok = tok,
|
||||
@ -352,7 +352,7 @@ pub fn defineParam(
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
try s.define(p.gpa, .{
|
||||
try s.define(p.comp.gpa, .{
|
||||
.kind = .def,
|
||||
.name = name,
|
||||
.tok = tok,
|
||||
@ -424,7 +424,7 @@ pub fn defineEnumeration(
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
try s.define(p.gpa, .{
|
||||
try s.define(p.comp.gpa, .{
|
||||
.kind = .enumeration,
|
||||
.name = name,
|
||||
.tok = tok,
|
||||
|
||||
78
lib/compiler/aro/aro/Toolchain.zig
vendored
78
lib/compiler/aro/aro/Toolchain.zig
vendored
@ -9,7 +9,7 @@ const Filesystem = @import("Driver/Filesystem.zig").Filesystem;
|
||||
const Multilib = @import("Driver/Multilib.zig");
|
||||
const target_util = @import("target.zig");
|
||||
|
||||
pub const PathList = std.ArrayListUnmanaged([]const u8);
|
||||
pub const PathList = std.ArrayList([]const u8);
|
||||
|
||||
pub const RuntimeLibKind = enum {
|
||||
compiler_rt,
|
||||
@ -64,7 +64,6 @@ pub fn getTarget(tc: *const Toolchain) std.Target {
|
||||
fn getDefaultLinker(tc: *const Toolchain) []const u8 {
|
||||
return switch (tc.inner) {
|
||||
.uninitialized => unreachable,
|
||||
.linux => |linux| linux.getDefaultLinker(tc.getTarget()),
|
||||
.unknown => "ld",
|
||||
};
|
||||
}
|
||||
@ -72,6 +71,7 @@ fn getDefaultLinker(tc: *const Toolchain) []const u8 {
|
||||
/// Call this after driver has finished parsing command line arguments to find the toolchain
|
||||
pub fn discover(tc: *Toolchain) !void {
|
||||
if (tc.inner != .uninitialized) return;
|
||||
|
||||
tc.inner = .unknown;
|
||||
return switch (tc.inner) {
|
||||
.uninitialized => unreachable,
|
||||
@ -143,8 +143,11 @@ pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 {
|
||||
return use_linker;
|
||||
}
|
||||
} else {
|
||||
var linker_name = try std.array_list.Managed(u8).initCapacity(tc.driver.comp.gpa, 5 + use_linker.len); // "ld64." ++ use_linker
|
||||
defer linker_name.deinit();
|
||||
const gpa = tc.driver.comp.gpa;
|
||||
var linker_name: std.ArrayList(u8) = .empty;
|
||||
defer linker_name.deinit(gpa);
|
||||
try linker_name.ensureUnusedCapacity(tc.driver.comp.gpa, 5 + use_linker.len); // "ld64." ++ use_linker
|
||||
|
||||
if (tc.getTarget().os.tag.isDarwin()) {
|
||||
linker_name.appendSliceAssumeCapacity("ld64.");
|
||||
} else {
|
||||
@ -171,20 +174,27 @@ pub fn getLinkerPath(tc: *const Toolchain, buf: []u8) ![]const u8 {
|
||||
/// TODO: this isn't exactly right since our target names don't necessarily match up
|
||||
/// with GCC's.
|
||||
/// For example the Zig target `arm-freestanding-eabi` would need the `arm-none-eabi` tools
|
||||
fn possibleProgramNames(raw_triple: ?[]const u8, name: []const u8, buf: *[64]u8, possible_names: *std.ArrayListUnmanaged([]const u8)) void {
|
||||
fn possibleProgramNames(
|
||||
raw_triple: ?[]const u8,
|
||||
name: []const u8,
|
||||
buf: *[64]u8,
|
||||
possible_name_buf: *[2][]const u8,
|
||||
) []const []const u8 {
|
||||
var i: u32 = 0;
|
||||
if (raw_triple) |triple| {
|
||||
if (std.fmt.bufPrint(buf, "{s}-{s}", .{ triple, name })) |res| {
|
||||
possible_names.appendAssumeCapacity(res);
|
||||
possible_name_buf[i] = res;
|
||||
i += 1;
|
||||
} else |_| {}
|
||||
}
|
||||
possible_names.appendAssumeCapacity(name);
|
||||
possible_name_buf[i] = name;
|
||||
|
||||
return possible_names;
|
||||
return possible_name_buf[0..i];
|
||||
}
|
||||
|
||||
/// Add toolchain `file_paths` to argv as `-L` arguments
|
||||
pub fn addFilePathLibArgs(tc: *const Toolchain, argv: *std.array_list.Managed([]const u8)) !void {
|
||||
try argv.ensureUnusedCapacity(tc.file_paths.items.len);
|
||||
pub fn addFilePathLibArgs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
|
||||
try argv.ensureUnusedCapacity(tc.driver.comp.gpa, tc.file_paths.items.len);
|
||||
|
||||
var bytes_needed: usize = 0;
|
||||
for (tc.file_paths.items) |path| {
|
||||
@ -208,11 +218,10 @@ fn getProgramPath(tc: *const Toolchain, name: []const u8, buf: []u8) []const u8
|
||||
var fib = std.heap.FixedBufferAllocator.init(&path_buf);
|
||||
|
||||
var tool_specific_buf: [64]u8 = undefined;
|
||||
var possible_names_buffer: [2][]const u8 = undefined;
|
||||
var possible_names = std.ArrayListUnmanaged.initBuffer(&possible_names_buffer);
|
||||
possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_buf, &possible_names);
|
||||
var possible_name_buf: [2][]const u8 = undefined;
|
||||
const possible_names = possibleProgramNames(tc.driver.raw_target_triple, name, &tool_specific_buf, &possible_name_buf);
|
||||
|
||||
for (possible_names.items) |tool_name| {
|
||||
for (possible_names) |tool_name| {
|
||||
for (tc.program_paths.items) |program_path| {
|
||||
defer fib.reset();
|
||||
|
||||
@ -318,16 +327,6 @@ pub fn addPathFromComponents(tc: *Toolchain, components: []const []const u8, des
|
||||
try dest.append(tc.driver.comp.gpa, full_path);
|
||||
}
|
||||
|
||||
/// Add linker args to `argv`. Does not add path to linker executable as first item; that must be handled separately
|
||||
/// Items added to `argv` will be string literals or owned by `tc.driver.comp.arena` so they must not be individually freed
|
||||
pub fn buildLinkerArgs(tc: *Toolchain, argv: *std.array_list.Managed([]const u8)) !void {
|
||||
return switch (tc.inner) {
|
||||
.uninitialized => unreachable,
|
||||
.linux => |*linux| linux.buildLinkerArgs(tc, argv),
|
||||
.unknown => @panic("This toolchain does not support linking yet"),
|
||||
};
|
||||
}
|
||||
|
||||
fn getDefaultRuntimeLibKind(tc: *const Toolchain) RuntimeLibKind {
|
||||
if (tc.getTarget().abi.isAndroid()) {
|
||||
return .compiler_rt;
|
||||
@ -400,7 +399,7 @@ fn getAsNeededOption(is_solaris: bool, needed: bool) []const u8 {
|
||||
}
|
||||
}
|
||||
|
||||
fn addUnwindLibrary(tc: *const Toolchain, argv: *std.array_list.Managed([]const u8)) !void {
|
||||
fn addUnwindLibrary(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
|
||||
const unw = try tc.getUnwindLibKind();
|
||||
const target = tc.getTarget();
|
||||
if ((target.abi.isAndroid() and unw == .libgcc) or
|
||||
@ -410,46 +409,49 @@ fn addUnwindLibrary(tc: *const Toolchain, argv: *std.array_list.Managed([]const
|
||||
|
||||
const lgk = tc.getLibGCCKind();
|
||||
const as_needed = lgk == .unspecified and !target.abi.isAndroid() and !target_util.isCygwinMinGW(target) and target.os.tag != .aix;
|
||||
|
||||
try argv.ensureUnusedCapacity(tc.driver.comp.gpa, 3);
|
||||
if (as_needed) {
|
||||
try argv.append(getAsNeededOption(target.os.tag == .solaris, true));
|
||||
argv.appendAssumeCapacity(getAsNeededOption(target.os.tag == .solaris, true));
|
||||
}
|
||||
switch (unw) {
|
||||
.none => return,
|
||||
.libgcc => if (lgk == .static) try argv.append("-lgcc_eh") else try argv.append("-lgcc_s"),
|
||||
.libgcc => argv.appendAssumeCapacity(if (lgk == .static) "-lgcc_eh" else "-lgcc_s"),
|
||||
.compiler_rt => if (target.os.tag == .aix) {
|
||||
if (lgk != .static) {
|
||||
try argv.append("-lunwind");
|
||||
argv.appendAssumeCapacity("-lunwind");
|
||||
}
|
||||
} else if (lgk == .static) {
|
||||
try argv.append("-l:libunwind.a");
|
||||
argv.appendAssumeCapacity("-l:libunwind.a");
|
||||
} else if (lgk == .shared) {
|
||||
if (target_util.isCygwinMinGW(target)) {
|
||||
try argv.append("-l:libunwind.dll.a");
|
||||
argv.appendAssumeCapacity("-l:libunwind.dll.a");
|
||||
} else {
|
||||
try argv.append("-l:libunwind.so");
|
||||
argv.appendAssumeCapacity("-l:libunwind.so");
|
||||
}
|
||||
} else {
|
||||
try argv.append("-lunwind");
|
||||
argv.appendAssumeCapacity("-lunwind");
|
||||
},
|
||||
}
|
||||
|
||||
if (as_needed) {
|
||||
try argv.append(getAsNeededOption(target.os.tag == .solaris, false));
|
||||
argv.appendAssumeCapacity(getAsNeededOption(target.os.tag == .solaris, false));
|
||||
}
|
||||
}
|
||||
|
||||
fn addLibGCC(tc: *const Toolchain, argv: *std.array_list.Managed([]const u8)) !void {
|
||||
fn addLibGCC(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
|
||||
const gpa = tc.driver.comp.gpa;
|
||||
const libgcc_kind = tc.getLibGCCKind();
|
||||
if (libgcc_kind == .static or libgcc_kind == .unspecified) {
|
||||
try argv.append("-lgcc");
|
||||
try argv.append(gpa, "-lgcc");
|
||||
}
|
||||
try tc.addUnwindLibrary(argv);
|
||||
if (libgcc_kind == .shared) {
|
||||
try argv.append("-lgcc");
|
||||
try argv.append(gpa, "-lgcc");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.array_list.Managed([]const u8)) !void {
|
||||
pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.ArrayList([]const u8)) !void {
|
||||
const target = tc.getTarget();
|
||||
const rlt = tc.getRuntimeLibKind();
|
||||
switch (rlt) {
|
||||
@ -469,7 +471,7 @@ pub fn addRuntimeLibs(tc: *const Toolchain, argv: *std.array_list.Managed([]cons
|
||||
}
|
||||
|
||||
if (target.abi.isAndroid() and !tc.driver.static and !tc.driver.static_pie) {
|
||||
try argv.append("-ldl");
|
||||
try argv.append(tc.driver.comp.gpa, "-ldl");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
lib/compiler/aro/aro/Tree.zig
vendored
8
lib/compiler/aro/aro/Tree.zig
vendored
@ -42,7 +42,7 @@ pub const TokenWithExpansionLocs = struct {
|
||||
|
||||
pub fn addExpansionLocation(tok: *TokenWithExpansionLocs, gpa: std.mem.Allocator, new: []const Source.Location) !void {
|
||||
if (new.len == 0 or tok.id == .whitespace or tok.id == .macro_ws or tok.id == .placemarker) return;
|
||||
var list = std.array_list.Managed(Source.Location).init(gpa);
|
||||
var list: std.ArrayList(Source.Location) = .empty;
|
||||
defer {
|
||||
@memset(list.items.ptr[list.items.len..list.capacity], .{});
|
||||
// Add a sentinel to indicate the end of the list since
|
||||
@ -65,7 +65,7 @@ pub const TokenWithExpansionLocs = struct {
|
||||
const min_len = @max(list.items.len + new.len + 1, 4);
|
||||
const wanted_len = std.math.ceilPowerOfTwo(usize, min_len) catch
|
||||
return error.OutOfMemory;
|
||||
try list.ensureTotalCapacity(wanted_len);
|
||||
try list.ensureTotalCapacity(gpa, wanted_len);
|
||||
|
||||
for (new) |new_loc| {
|
||||
if (new_loc.id == .generated) continue;
|
||||
@ -119,8 +119,8 @@ tokens: Token.List.Slice,
|
||||
|
||||
// Values owned by this Tree
|
||||
nodes: std.MultiArrayList(Node.Repr) = .empty,
|
||||
extra: std.ArrayListUnmanaged(u32) = .empty,
|
||||
root_decls: std.ArrayListUnmanaged(Node.Index) = .empty,
|
||||
extra: std.ArrayList(u32) = .empty,
|
||||
root_decls: std.ArrayList(Node.Index) = .empty,
|
||||
value_map: ValueMap = .empty,
|
||||
|
||||
pub const genIr = CodeGen.genIr;
|
||||
|
||||
26
lib/compiler/aro/aro/TypeStore.zig
vendored
26
lib/compiler/aro/aro/TypeStore.zig
vendored
@ -1216,6 +1216,13 @@ pub const QualType = packed struct(u32) {
|
||||
return false;
|
||||
},
|
||||
.array => |array| {
|
||||
if (qt.@"const") {
|
||||
try w.writeAll("const ");
|
||||
}
|
||||
if (qt.@"volatile") {
|
||||
try w.writeAll("volatile");
|
||||
}
|
||||
|
||||
const simple = try array.elem.printPrologue(comp, desugar, w);
|
||||
if (simple) try w.writeByte(' ');
|
||||
return false;
|
||||
@ -1341,14 +1348,6 @@ pub const QualType = packed struct(u32) {
|
||||
|
||||
const static = array.len == .static;
|
||||
if (static) try w.writeAll("static");
|
||||
if (qt.@"const") {
|
||||
if (static) try w.writeByte(' ');
|
||||
try w.writeAll("const");
|
||||
}
|
||||
if (qt.@"volatile") {
|
||||
if (static or qt.@"const") try w.writeByte(' ');
|
||||
try w.writeAll("volatile");
|
||||
}
|
||||
if (qt.restrict) {
|
||||
if (static or qt.@"const" or qt.@"volatile") try w.writeByte(' ');
|
||||
try w.writeAll("restrict");
|
||||
@ -1694,8 +1693,8 @@ pub const Type = union(enum) {
|
||||
};
|
||||
|
||||
types: std.MultiArrayList(Repr) = .empty,
|
||||
extra: std.ArrayListUnmanaged(u32) = .empty,
|
||||
attributes: std.ArrayListUnmanaged(Attribute) = .empty,
|
||||
extra: std.ArrayList(u32) = .empty,
|
||||
attributes: std.ArrayList(Attribute) = .empty,
|
||||
anon_name_arena: std.heap.ArenaAllocator.State = .{},
|
||||
|
||||
wchar: QualType = .invalid,
|
||||
@ -2435,7 +2434,7 @@ pub const Builder = struct {
|
||||
}
|
||||
if (b.complex_tok) |tok| try b.parser.err(tok, .complex_int, .{});
|
||||
|
||||
const qt = try b.parser.comp.type_store.put(b.parser.gpa, .{ .bit_int = .{
|
||||
const qt = try b.parser.comp.type_store.put(b.parser.comp.gpa, .{ .bit_int = .{
|
||||
.signedness = if (unsigned) .unsigned else .signed,
|
||||
.bits = @intCast(bits),
|
||||
} });
|
||||
@ -2476,6 +2475,7 @@ pub const Builder = struct {
|
||||
|
||||
pub fn finishQuals(b: Builder, qt: QualType) !QualType {
|
||||
if (qt.isInvalid()) return .invalid;
|
||||
const gpa = b.parser.comp.gpa;
|
||||
var result_qt = qt;
|
||||
if (b.atomic_type orelse b.atomic) |atomic_tok| {
|
||||
if (result_qt.isAutoType()) return b.parser.todo("_Atomic __auto_type");
|
||||
@ -2505,7 +2505,7 @@ pub const Builder = struct {
|
||||
return .invalid;
|
||||
},
|
||||
else => {
|
||||
result_qt = try b.parser.comp.type_store.put(b.parser.gpa, .{ .atomic = result_qt });
|
||||
result_qt = try b.parser.comp.type_store.put(gpa, .{ .atomic = result_qt });
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -2514,7 +2514,7 @@ pub const Builder = struct {
|
||||
const is_pointer = qt.isAutoType() or qt.isC23Auto() or qt.base(b.parser.comp).type == .pointer;
|
||||
|
||||
if (b.unaligned != null and !is_pointer) {
|
||||
result_qt = (try b.parser.comp.type_store.put(b.parser.gpa, .{ .attributed = .{
|
||||
result_qt = (try b.parser.comp.type_store.put(gpa, .{ .attributed = .{
|
||||
.base = result_qt,
|
||||
.attributes = &.{.{ .tag = .unaligned, .args = .{ .unaligned = .{} }, .syntax = .keyword }},
|
||||
} })).withQualifiers(result_qt);
|
||||
|
||||
4
lib/compiler/aro/aro/pragmas/gcc.zig
vendored
4
lib/compiler/aro/aro/pragmas/gcc.zig
vendored
@ -20,7 +20,7 @@ pragma: Pragma = .{
|
||||
.preserveTokens = preserveTokens,
|
||||
},
|
||||
original_state: Diagnostics.State = .{},
|
||||
state_stack: std.ArrayListUnmanaged(Diagnostics.State) = .{},
|
||||
state_stack: std.ArrayList(Diagnostics.State) = .empty,
|
||||
|
||||
const Directive = enum {
|
||||
warning,
|
||||
@ -138,7 +138,7 @@ fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex
|
||||
if (pp.defines.get(str) != null) {
|
||||
try Pragma.err(pp, start_idx + i, .pragma_poison_macro, .{});
|
||||
}
|
||||
try pp.poisoned_identifiers.put(str, {});
|
||||
try pp.poisoned_identifiers.put(pp.comp.gpa, str, {});
|
||||
}
|
||||
return;
|
||||
},
|
||||
|
||||
2
lib/compiler/aro/aro/pragmas/message.zig
vendored
2
lib/compiler/aro/aro/pragmas/message.zig
vendored
@ -44,7 +44,7 @@ fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pra
|
||||
|
||||
const diagnostic: Pragma.Diagnostic = .pragma_message;
|
||||
|
||||
var sf = std.heap.stackFallback(1024, pp.gpa);
|
||||
var sf = std.heap.stackFallback(1024, pp.comp.gpa);
|
||||
var allocating: std.Io.Writer.Allocating = .init(sf.get());
|
||||
defer allocating.deinit();
|
||||
|
||||
|
||||
11
lib/compiler/aro/aro/pragmas/once.zig
vendored
11
lib/compiler/aro/aro/pragmas/once.zig
vendored
@ -17,14 +17,12 @@ pragma: Pragma = .{
|
||||
.preprocessorHandler = preprocessorHandler,
|
||||
.preserveTokens = preserveTokens,
|
||||
},
|
||||
pragma_once: std.AutoHashMap(Source.Id, void),
|
||||
pragma_once: std.AutoHashMapUnmanaged(Source.Id, void) = .empty,
|
||||
preprocess_count: u32 = 0,
|
||||
|
||||
pub fn init(allocator: mem.Allocator) !*Pragma {
|
||||
var once = try allocator.create(Once);
|
||||
once.* = .{
|
||||
.pragma_once = std.AutoHashMap(Source.Id, void).init(allocator),
|
||||
};
|
||||
once.* = .{};
|
||||
return &once.pragma;
|
||||
}
|
||||
|
||||
@ -35,8 +33,9 @@ fn afterParse(pragma: *Pragma, _: *Compilation) void {
|
||||
|
||||
fn deinit(pragma: *Pragma, comp: *Compilation) void {
|
||||
var self: *Once = @fieldParentPtr("pragma", pragma);
|
||||
self.pragma_once.deinit();
|
||||
self.pragma_once.deinit(comp.gpa);
|
||||
comp.gpa.destroy(self);
|
||||
pragma.* = undefined;
|
||||
}
|
||||
|
||||
fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
|
||||
@ -53,7 +52,7 @@ fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex
|
||||
}, pp.expansionSlice(start_idx + 1), true);
|
||||
}
|
||||
const seen = self.preprocess_count == pp.preprocess_count;
|
||||
const prev = try self.pragma_once.fetchPut(name_tok.loc.id, {});
|
||||
const prev = try self.pragma_once.fetchPut(pp.comp.gpa, name_tok.loc.id, {});
|
||||
if (prev != null and !seen) {
|
||||
return error.StopPreprocessing;
|
||||
}
|
||||
|
||||
4
lib/compiler/aro/aro/pragmas/pack.zig
vendored
4
lib/compiler/aro/aro/pragmas/pack.zig
vendored
@ -15,7 +15,7 @@ pragma: Pragma = .{
|
||||
.deinit = deinit,
|
||||
.parserHandler = parserHandler,
|
||||
},
|
||||
stack: std.ArrayListUnmanaged(struct { label: []const u8, val: u8 }) = .{},
|
||||
stack: std.ArrayList(struct { label: []const u8, val: u8 }) = .empty,
|
||||
|
||||
pub fn init(allocator: mem.Allocator) !*Pragma {
|
||||
var pack = try allocator.create(Pack);
|
||||
@ -82,7 +82,7 @@ fn parserHandler(pragma: *Pragma, p: *Parser, start_idx: TokenIndex) Compilation
|
||||
}
|
||||
}
|
||||
if (action == .push) {
|
||||
try pack.stack.append(p.gpa, .{ .label = label orelse "", .val = p.pragma_pack orelse 8 });
|
||||
try pack.stack.append(p.comp.gpa, .{ .label = label orelse "", .val = p.pragma_pack orelse 8 });
|
||||
} else {
|
||||
pack.pop(p, label);
|
||||
if (new_val != null) {
|
||||
|
||||
9
lib/compiler/aro/assembly_backend/x86_64.zig
vendored
9
lib/compiler/aro/assembly_backend/x86_64.zig
vendored
@ -70,10 +70,11 @@ pub fn todo(c: *AsmCodeGen, msg: []const u8, tok: Tree.TokenIndex) Error {
|
||||
const loc: Source.Location = c.tree.tokens.items(.loc)[tok];
|
||||
|
||||
var sf = std.heap.stackFallback(1024, c.comp.gpa);
|
||||
var buf = std.ArrayList(u8).init(sf.get());
|
||||
defer buf.deinit();
|
||||
const allocator = sf.get();
|
||||
var buf: std.ArrayList(u8) = .empty;
|
||||
defer buf.deinit(allocator);
|
||||
|
||||
try buf.print("TODO: {s}", .{msg});
|
||||
try buf.print(allocator, "TODO: {s}", .{msg});
|
||||
try c.comp.diagnostics.add(.{
|
||||
.text = buf.items,
|
||||
.kind = .@"error",
|
||||
@ -163,7 +164,7 @@ pub fn genAsm(tree: *const Tree) Error!Assembly {
|
||||
}
|
||||
|
||||
fn genDecls(c: *AsmCodeGen) !void {
|
||||
if (c.tree.comp.code_gen_options.debug) {
|
||||
if (c.tree.comp.code_gen_options.debug != .strip) {
|
||||
const sources = c.tree.comp.sources.values();
|
||||
for (sources) |source| {
|
||||
try c.data.print(" .file {d} \"{s}\"\n", .{ @intFromEnum(source.id) - 1, source.path });
|
||||
|
||||
14
lib/compiler/aro/backend/CodeGenOptions.zig
vendored
14
lib/compiler/aro/backend/CodeGenOptions.zig
vendored
@ -66,6 +66,20 @@ pub const OptimizationLevel = enum {
|
||||
pub fn fromString(str: []const u8) ?OptimizationLevel {
|
||||
return level_map.get(str);
|
||||
}
|
||||
|
||||
pub fn isSizeOptimized(self: OptimizationLevel) bool {
|
||||
return switch (self) {
|
||||
.s, .z => true,
|
||||
.@"0", .@"1", .@"2", .@"3", .fast, .g => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn hasAnyOptimizations(self: OptimizationLevel) bool {
|
||||
return switch (self) {
|
||||
.@"0" => false,
|
||||
.@"1", .@"2", .@"3", .s, .fast, .g, .z => true,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const default: @This() = .{
|
||||
|
||||
10
lib/compiler/aro/backend/Interner.zig
vendored
10
lib/compiler/aro/backend/Interner.zig
vendored
@ -8,14 +8,14 @@ const Limb = std.math.big.Limb;
|
||||
|
||||
const Interner = @This();
|
||||
|
||||
map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
|
||||
map: std.AutoArrayHashMapUnmanaged(void, void) = .empty,
|
||||
items: std.MultiArrayList(struct {
|
||||
tag: Tag,
|
||||
data: u32,
|
||||
}) = .{},
|
||||
extra: std.ArrayListUnmanaged(u32) = .{},
|
||||
limbs: std.ArrayListUnmanaged(Limb) = .{},
|
||||
strings: std.ArrayListUnmanaged(u8) = .{},
|
||||
}) = .empty,
|
||||
extra: std.ArrayList(u32) = .empty,
|
||||
limbs: std.ArrayList(Limb) = .empty,
|
||||
strings: std.ArrayList(u8) = .empty,
|
||||
|
||||
const KeyAdapter = struct {
|
||||
interner: *const Interner,
|
||||
|
||||
40
lib/compiler/aro/backend/Ir.zig
vendored
40
lib/compiler/aro/backend/Ir.zig
vendored
@ -11,7 +11,7 @@ decls: std.StringArrayHashMapUnmanaged(Decl),
|
||||
|
||||
pub const Decl = struct {
|
||||
instructions: std.MultiArrayList(Inst),
|
||||
body: std.ArrayListUnmanaged(Ref),
|
||||
body: std.ArrayList(Ref),
|
||||
arena: std.heap.ArenaAllocator.State,
|
||||
|
||||
pub fn deinit(decl: *Decl, gpa: Allocator) void {
|
||||
@ -26,9 +26,9 @@ pub const Builder = struct {
|
||||
arena: std.heap.ArenaAllocator,
|
||||
interner: *Interner,
|
||||
|
||||
decls: std.StringArrayHashMapUnmanaged(Decl) = .{},
|
||||
instructions: std.MultiArrayList(Ir.Inst) = .{},
|
||||
body: std.ArrayListUnmanaged(Ref) = .{},
|
||||
decls: std.StringArrayHashMapUnmanaged(Decl) = .empty,
|
||||
instructions: std.MultiArrayList(Ir.Inst) = .empty,
|
||||
body: std.ArrayList(Ref) = .empty,
|
||||
alloc_count: u32 = 0,
|
||||
arg_count: u32 = 0,
|
||||
current_label: Ref = undefined,
|
||||
@ -380,7 +380,7 @@ const REF = std.Io.tty.Color.bright_blue;
|
||||
const LITERAL = std.Io.tty.Color.bright_green;
|
||||
const ATTRIBUTE = std.Io.tty.Color.bright_yellow;
|
||||
|
||||
const RefMap = std.AutoArrayHashMap(Ref, void);
|
||||
const RefMap = std.AutoArrayHashMapUnmanaged(Ref, void);
|
||||
|
||||
pub fn dump(ir: *const Ir, gpa: Allocator, config: std.Io.tty.Config, w: *std.Io.Writer) !void {
|
||||
for (ir.decls.keys(), ir.decls.values()) |name, *decl| {
|
||||
@ -393,11 +393,11 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
const tags = decl.instructions.items(.tag);
|
||||
const data = decl.instructions.items(.data);
|
||||
|
||||
var ref_map = RefMap.init(gpa);
|
||||
defer ref_map.deinit();
|
||||
var ref_map: RefMap = .empty;
|
||||
defer ref_map.deinit(gpa);
|
||||
|
||||
var label_map = RefMap.init(gpa);
|
||||
defer label_map.deinit();
|
||||
var label_map: RefMap = .empty;
|
||||
defer label_map.deinit(gpa);
|
||||
|
||||
const ret_inst = decl.body.items[decl.body.items.len - 1];
|
||||
const ret_operand = data[@intFromEnum(ret_inst)].un;
|
||||
@ -413,14 +413,14 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
const ref = decl.body.items[arg_count];
|
||||
if (tags[@intFromEnum(ref)] != .arg) break;
|
||||
if (arg_count != 0) try w.writeAll(", ");
|
||||
try ref_map.put(ref, {});
|
||||
try ref_map.put(gpa, ref, {});
|
||||
try ir.writeRef(decl, &ref_map, ref, config, w);
|
||||
try config.setColor(w, .reset);
|
||||
}
|
||||
try w.writeAll(") {\n");
|
||||
for (decl.body.items[arg_count..]) |ref| {
|
||||
switch (tags[@intFromEnum(ref)]) {
|
||||
.label => try label_map.put(ref, {}),
|
||||
.label => try label_map.put(gpa, ref, {}),
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
@ -461,7 +461,7 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
},
|
||||
.select => {
|
||||
const br = data[i].branch;
|
||||
try ir.writeNewRef(decl, &ref_map, ref, config, w);
|
||||
try ir.writeNewRef(gpa, decl, &ref_map, ref, config, w);
|
||||
try w.writeAll("select ");
|
||||
try ir.writeRef(decl, &ref_map, br.cond, config, w);
|
||||
try config.setColor(w, .reset);
|
||||
@ -501,7 +501,7 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
},
|
||||
.call => {
|
||||
const call = data[i].call;
|
||||
try ir.writeNewRef(decl, &ref_map, ref, config, w);
|
||||
try ir.writeNewRef(gpa, decl, &ref_map, ref, config, w);
|
||||
try w.writeAll("call ");
|
||||
try ir.writeRef(decl, &ref_map, call.func, config, w);
|
||||
try config.setColor(w, .reset);
|
||||
@ -515,7 +515,7 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
},
|
||||
.alloc => {
|
||||
const alloc = data[i].alloc;
|
||||
try ir.writeNewRef(decl, &ref_map, ref, config, w);
|
||||
try ir.writeNewRef(gpa, decl, &ref_map, ref, config, w);
|
||||
try w.writeAll("alloc ");
|
||||
try config.setColor(w, ATTRIBUTE);
|
||||
try w.writeAll("size ");
|
||||
@ -528,7 +528,7 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
try w.writeByte('\n');
|
||||
},
|
||||
.phi => {
|
||||
try ir.writeNewRef(decl, &ref_map, ref, config, w);
|
||||
try ir.writeNewRef(gpa, decl, &ref_map, ref, config, w);
|
||||
try w.writeAll("phi");
|
||||
try config.setColor(w, .reset);
|
||||
try w.writeAll(" {");
|
||||
@ -560,7 +560,7 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
try w.writeByte('\n');
|
||||
},
|
||||
.load => {
|
||||
try ir.writeNewRef(decl, &ref_map, ref, config, w);
|
||||
try ir.writeNewRef(gpa, decl, &ref_map, ref, config, w);
|
||||
try w.writeAll("load ");
|
||||
try ir.writeRef(decl, &ref_map, data[i].un, config, w);
|
||||
try w.writeByte('\n');
|
||||
@ -583,7 +583,7 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
.mod,
|
||||
=> {
|
||||
const bin = data[i].bin;
|
||||
try ir.writeNewRef(decl, &ref_map, ref, config, w);
|
||||
try ir.writeNewRef(gpa, decl, &ref_map, ref, config, w);
|
||||
try w.print("{s} ", .{@tagName(tag)});
|
||||
try ir.writeRef(decl, &ref_map, bin.lhs, config, w);
|
||||
try config.setColor(w, .reset);
|
||||
@ -598,7 +598,7 @@ fn dumpDecl(ir: *const Ir, decl: *const Decl, gpa: Allocator, name: []const u8,
|
||||
.sext,
|
||||
=> {
|
||||
const un = data[i].un;
|
||||
try ir.writeNewRef(decl, &ref_map, ref, config, w);
|
||||
try ir.writeNewRef(gpa, decl, &ref_map, ref, config, w);
|
||||
try w.print("{s} ", .{@tagName(tag)});
|
||||
try ir.writeRef(decl, &ref_map, un, config, w);
|
||||
try w.writeByte('\n');
|
||||
@ -679,8 +679,8 @@ fn writeRef(ir: Ir, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.I
|
||||
try w.print(" %{d}", .{ref_index});
|
||||
}
|
||||
|
||||
fn writeNewRef(ir: Ir, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.Io.tty.Config, w: *std.Io.Writer) !void {
|
||||
try ref_map.put(ref, {});
|
||||
fn writeNewRef(ir: Ir, gpa: Allocator, decl: *const Decl, ref_map: *RefMap, ref: Ref, config: std.Io.tty.Config, w: *std.Io.Writer) !void {
|
||||
try ref_map.put(gpa, ref, {});
|
||||
try w.writeAll(" ");
|
||||
try ir.writeRef(decl, ref_map, ref, config, w);
|
||||
try config.setColor(w, .reset);
|
||||
|
||||
2
lib/compiler/aro/backend/Object.zig
vendored
2
lib/compiler/aro/backend/Object.zig
vendored
@ -30,7 +30,7 @@ pub const Section = union(enum) {
|
||||
custom: []const u8,
|
||||
};
|
||||
|
||||
pub fn getSection(obj: *Object, section: Section) !*std.array_list.Managed(u8) {
|
||||
pub fn getSection(obj: *Object, section: Section) !*std.ArrayList(u8) {
|
||||
switch (obj.format) {
|
||||
.elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).getSection(section),
|
||||
else => unreachable,
|
||||
|
||||
16
lib/compiler/aro/backend/Object/Elf.zig
vendored
16
lib/compiler/aro/backend/Object/Elf.zig
vendored
@ -4,8 +4,8 @@ const Target = std.Target;
|
||||
const Object = @import("../Object.zig");
|
||||
|
||||
const Section = struct {
|
||||
data: std.array_list.Managed(u8),
|
||||
relocations: std.ArrayListUnmanaged(Relocation) = .{},
|
||||
data: std.ArrayList(u8) = .empty,
|
||||
relocations: std.ArrayList(Relocation) = .empty,
|
||||
flags: u64,
|
||||
type: u32,
|
||||
index: u16 = undefined,
|
||||
@ -37,9 +37,9 @@ const Elf = @This();
|
||||
|
||||
obj: Object,
|
||||
/// The keys are owned by the Codegen.tree
|
||||
sections: std.StringHashMapUnmanaged(*Section) = .{},
|
||||
local_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
|
||||
global_symbols: std.StringHashMapUnmanaged(*Symbol) = .{},
|
||||
sections: std.StringHashMapUnmanaged(*Section) = .empty,
|
||||
local_symbols: std.StringHashMapUnmanaged(*Symbol) = .empty,
|
||||
global_symbols: std.StringHashMapUnmanaged(*Symbol) = .empty,
|
||||
unnamed_symbol_mangle: u32 = 0,
|
||||
strtab_len: u64 = strtab_default.len,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
@ -58,7 +58,7 @@ pub fn deinit(elf: *Elf) void {
|
||||
{
|
||||
var it = elf.sections.valueIterator();
|
||||
while (it.next()) |sect| {
|
||||
sect.*.data.deinit();
|
||||
sect.*.data.deinit(gpa);
|
||||
sect.*.relocations.deinit(gpa);
|
||||
}
|
||||
}
|
||||
@ -80,12 +80,12 @@ fn sectionString(sec: Object.Section) []const u8 {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getSection(elf: *Elf, section_kind: Object.Section) !*std.array_list.Managed(u8) {
|
||||
pub fn getSection(elf: *Elf, section_kind: Object.Section) !*std.ArrayList(u8) {
|
||||
const section_name = sectionString(section_kind);
|
||||
const section = elf.sections.get(section_name) orelse blk: {
|
||||
const section = try elf.arena.allocator().create(Section);
|
||||
section.* = .{
|
||||
.data = std.array_list.Managed(u8).init(elf.arena.child_allocator),
|
||||
.data = std.ArrayList(u8).init(elf.arena.child_allocator),
|
||||
.type = std.elf.SHT_PROGBITS,
|
||||
.flags = switch (section_kind) {
|
||||
.func, .custom => std.elf.SHF_ALLOC + std.elf.SHF_EXECINSTR,
|
||||
|
||||
@ -150,7 +150,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void {
|
||||
// be written to a tmp file then renamed into place, meaning the path will be
|
||||
// wrong as soon as the work is done.
|
||||
var opt_dep_file = try d.initDepFile(source, &name_buf, true);
|
||||
defer if (opt_dep_file) |*dep_file| dep_file.deinit(pp.gpa);
|
||||
defer if (opt_dep_file) |*dep_file| dep_file.deinit(gpa);
|
||||
|
||||
if (opt_dep_file) |*dep_file| pp.dep_file = dep_file;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user