aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig277
-rw-r--r--src/Module.zig5
-rw-r--r--src/codegen.zig66
-rw-r--r--src/codegen/arm.zig4
-rw-r--r--src/codegen/llvm.zig151
-rw-r--r--src/codegen/llvm/bindings.zig269
-rw-r--r--src/link/MachO.zig26
-rw-r--r--src/link/MachO/TextBlock.zig4
-rw-r--r--src/translate_c.zig73
-rw-r--r--src/translate_c/ast.zig23
10 files changed, 488 insertions, 410 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 0a34e9a0ca..a51dd38f8c 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -2883,8 +2883,6 @@ fn fnDecl(
};
const fn_name_str_index = try astgen.identAsString(fn_name_token);
- try astgen.declareNewName(scope, fn_name_str_index, decl_node, fn_name_token);
-
// We insert this at the beginning so that its instruction index marks the
// start of the top level declaration.
const block_inst = try gz.addBlock(.block_inline, fn_proto.ast.proto_node);
@@ -3153,8 +3151,6 @@ fn globalVarDecl(
const name_token = var_decl.ast.mut_token + 1;
const name_str_index = try astgen.identAsString(name_token);
- try astgen.declareNewName(scope, name_str_index, node, name_token);
-
var block_scope: GenZir = .{
.parent = scope,
.decl_node_index = node,
@@ -3509,9 +3505,11 @@ fn structDeclInner(
};
defer block_scope.instructions.deinit(gpa);
- var namespace: Scope.Namespace = .{ .parent = scope };
+ var namespace: Scope.Namespace = .{ .parent = scope, .node = node };
defer namespace.decls.deinit(gpa);
+ try astgen.scanDecls(&namespace, container_decl.ast.members);
+
var wip_decls: WipDecls = .{};
defer wip_decls.deinit(gpa);
@@ -3671,7 +3669,7 @@ fn structDeclInner(
const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype")
.none
else
- try typeExpr(&block_scope, &block_scope.base, member.ast.type_expr);
+ try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
fields_data.appendAssumeCapacity(@enumToInt(field_type));
known_has_bits = known_has_bits or nodeImpliesRuntimeBits(tree, member.ast.type_expr);
@@ -3687,13 +3685,13 @@ fn structDeclInner(
(@as(u32, @boolToInt(unused)) << 31);
if (have_align) {
- const align_inst = try expr(&block_scope, &block_scope.base, align_rl, member.ast.align_expr);
+ const align_inst = try expr(&block_scope, &namespace.base, align_rl, member.ast.align_expr);
fields_data.appendAssumeCapacity(@enumToInt(align_inst));
}
if (have_value) {
const rl: ResultLoc = if (field_type == .none) .none else .{ .ty = field_type };
- const default_inst = try expr(&block_scope, &block_scope.base, rl, member.ast.value_expr);
+ const default_inst = try expr(&block_scope, &namespace.base, rl, member.ast.value_expr);
fields_data.appendAssumeCapacity(@enumToInt(default_inst));
} else if (member.comptime_token) |comptime_token| {
return astgen.failTok(comptime_token, "comptime field without default initialization value", .{});
@@ -3756,7 +3754,7 @@ fn unionDeclInner(
node: ast.Node.Index,
members: []const ast.Node.Index,
layout: std.builtin.TypeInfo.ContainerLayout,
- arg_inst: Zir.Inst.Ref,
+ arg_node: ast.Node.Index,
have_auto_enum: bool,
) InnerError!Zir.Inst.Ref {
const astgen = gz.astgen;
@@ -3778,9 +3776,16 @@ fn unionDeclInner(
};
defer block_scope.instructions.deinit(gpa);
- var namespace: Scope.Namespace = .{ .parent = scope };
+ var namespace: Scope.Namespace = .{ .parent = scope, .node = node };
defer namespace.decls.deinit(gpa);
+ try astgen.scanDecls(&namespace, members);
+
+ const arg_inst: Zir.Inst.Ref = if (arg_node != 0)
+ try typeExpr(gz, &namespace.base, arg_node)
+ else
+ .none;
+
var wip_decls: WipDecls = .{};
defer wip_decls.deinit(gpa);
@@ -3946,7 +3951,7 @@ fn unionDeclInner(
(@as(u32, @boolToInt(unused)) << 31);
if (have_type and node_tags[member.ast.type_expr] != .@"anytype") {
- const field_type = try typeExpr(&block_scope, &block_scope.base, member.ast.type_expr);
+ const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
fields_data.appendAssumeCapacity(@enumToInt(field_type));
}
if (have_align) {
@@ -4046,11 +4051,6 @@ fn containerDecl(
// We must not create any types until Sema. Here the goal is only to generate
// ZIR for all the field types, alignments, and default value expressions.
- const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0)
- try comptimeExpr(gz, scope, .{ .ty = .type_type }, container_decl.ast.arg)
- else
- .none;
-
switch (token_tags[container_decl.ast.main_token]) {
.keyword_struct => {
const layout = if (container_decl.layout_token) |t| switch (token_tags[t]) {
@@ -4059,7 +4059,7 @@ fn containerDecl(
else => unreachable,
} else std.builtin.TypeInfo.ContainerLayout.Auto;
- assert(arg_inst == .none);
+ assert(container_decl.ast.arg == 0);
const result = try structDeclInner(gz, scope, node, container_decl, layout);
return rvalue(gz, rl, result, node);
@@ -4073,7 +4073,7 @@ fn containerDecl(
const have_auto_enum = container_decl.ast.enum_token != null;
- const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, arg_inst, have_auto_enum);
+ const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, have_auto_enum);
return rvalue(gz, rl, result, node);
},
.keyword_enum => {
@@ -4140,7 +4140,7 @@ fn containerDecl(
}
total_fields += 1;
if (member.ast.value_expr != 0) {
- if (arg_inst == .none) {
+ if (container_decl.ast.arg == 0) {
return astgen.failNode(member.ast.value_expr, "value assigned to enum tag with inferred tag type", .{});
}
values += 1;
@@ -4159,7 +4159,7 @@ fn containerDecl(
// must be at least one tag.
return astgen.failNode(node, "enum declarations must have at least one tag", .{});
}
- if (counts.nonexhaustive_node != 0 and arg_inst == .none) {
+ if (counts.nonexhaustive_node != 0 and container_decl.ast.arg == 0) {
return astgen.failNodeNotes(
node,
"non-exhaustive enum missing integer tag type",
@@ -4189,9 +4189,16 @@ fn containerDecl(
};
defer block_scope.instructions.deinit(gpa);
- var namespace: Scope.Namespace = .{ .parent = scope };
+ var namespace: Scope.Namespace = .{ .parent = scope, .node = node };
defer namespace.decls.deinit(gpa);
+ try astgen.scanDecls(&namespace, container_decl.ast.members);
+
+ const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0)
+ try comptimeExpr(gz, &namespace.base, .{ .ty = .type_type }, container_decl.ast.arg)
+ else
+ .none;
+
var wip_decls: WipDecls = .{};
defer wip_decls.deinit(gpa);
@@ -4364,7 +4371,7 @@ fn containerDecl(
},
);
}
- const tag_value_inst = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr);
+ const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .ty = arg_inst }, member.ast.value_expr);
fields_data.appendAssumeCapacity(@enumToInt(tag_value_inst));
}
@@ -4416,9 +4423,13 @@ fn containerDecl(
return rvalue(gz, rl, indexToRef(decl_inst), node);
},
.keyword_opaque => {
- var namespace: Scope.Namespace = .{ .parent = scope };
+ assert(container_decl.ast.arg == 0);
+
+ var namespace: Scope.Namespace = .{ .parent = scope, .node = node };
defer namespace.decls.deinit(gpa);
+ try astgen.scanDecls(&namespace, container_decl.ast.members);
+
var wip_decls: WipDecls = .{};
defer wip_decls.deinit(gpa);
@@ -6352,73 +6363,63 @@ fn identifier(
// Local variables, including function parameters.
const name_str_index = try astgen.identAsString(ident_token);
- {
- var s = scope;
- var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already
- var hit_namespace = false;
- while (true) switch (s.tag) {
- .local_val => {
- const local_val = s.cast(Scope.LocalVal).?;
-
- if (local_val.name == name_str_index) {
- local_val.used = true;
- // Captures of non-locals need to be emitted as decl_val or decl_ref.
- // This *might* be capturable depending on if it is comptime known.
- if (!hit_namespace) {
- return rvalue(gz, rl, local_val.inst, ident);
- }
+ var s = scope;
+ var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already
+ var hit_namespace: ast.Node.Index = 0;
+ while (true) switch (s.tag) {
+ .local_val => {
+ const local_val = s.cast(Scope.LocalVal).?;
+
+ if (local_val.name == name_str_index) {
+ local_val.used = true;
+ // Locals cannot shadow anything, so we do not need to look for ambiguous
+ // references in this case.
+ return rvalue(gz, rl, local_val.inst, ident);
+ }
+ s = local_val.parent;
+ },
+ .local_ptr => {
+ const local_ptr = s.cast(Scope.LocalPtr).?;
+ if (local_ptr.name == name_str_index) {
+ local_ptr.used = true;
+ if (hit_namespace != 0 and !local_ptr.maybe_comptime) {
+ return astgen.failNodeNotes(ident, "mutable '{s}' not accessible from here", .{ident_name}, &.{
+ try astgen.errNoteTok(local_ptr.token_src, "declared mutable here", .{}),
+ try astgen.errNoteNode(hit_namespace, "crosses namespace boundary here", .{}),
+ });
}
- s = local_val.parent;
- },
- .local_ptr => {
- const local_ptr = s.cast(Scope.LocalPtr).?;
- if (local_ptr.name == name_str_index) {
- local_ptr.used = true;
- if (hit_namespace) {
- if (local_ptr.maybe_comptime)
- break
- else
- return astgen.failNodeNotes(ident, "'{s}' not accessible from inner function", .{ident_name}, &.{
- try astgen.errNoteTok(local_ptr.token_src, "declared here", .{}),
- // TODO add crossed function definition here note.
- // Maybe add a note to the error about it being because of the var,
- // maybe recommend copying it into a const variable. -SpexGuy
- });
- }
- switch (rl) {
- .ref, .none_or_ref => return local_ptr.ptr,
- else => {
- const loaded = try gz.addUnNode(.load, local_ptr.ptr, ident);
- return rvalue(gz, rl, loaded, ident);
- },
- }
+ switch (rl) {
+ .ref, .none_or_ref => return local_ptr.ptr,
+ else => {
+ const loaded = try gz.addUnNode(.load, local_ptr.ptr, ident);
+ return rvalue(gz, rl, loaded, ident);
+ },
}
- s = local_ptr.parent;
- },
- .gen_zir => s = s.cast(GenZir).?.parent,
- .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
- // look for ambiguous references to decls
- .namespace => {
- const ns = s.cast(Scope.Namespace).?;
- if (ns.decls.get(name_str_index)) |i| {
- if (found_already) |f|
- return astgen.failNodeNotes(ident, "ambiguous reference", .{}, &.{
- try astgen.errNoteNode(i, "declared here", .{}),
- try astgen.errNoteNode(f, "also declared here", .{}),
- })
- else
- found_already = i;
+ }
+ s = local_ptr.parent;
+ },
+ .gen_zir => s = s.cast(GenZir).?.parent,
+ .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
+ .namespace => {
+ const ns = s.cast(Scope.Namespace).?;
+ if (ns.decls.get(name_str_index)) |i| {
+ if (found_already) |f| {
+ return astgen.failNodeNotes(ident, "ambiguous reference", .{}, &.{
+ try astgen.errNoteNode(f, "declared here", .{}),
+ try astgen.errNoteNode(i, "also declared here", .{}),
+ });
}
- hit_namespace = true;
- s = ns.parent;
- },
- .top => break,
- };
- }
+ // We found a match but must continue looking for ambiguous references to decls.
+ found_already = i;
+ }
+ hit_namespace = ns.node;
+ s = ns.parent;
+ },
+ .top => break,
+ };
- // We can't look up Decls until Sema because the same ZIR code is supposed to be
- // used for multiple generic instantiations, and this may refer to a different Decl
- // depending on the scope, determined by the generic instantiation.
+ // Decl references happen by name rather than ZIR index so that when unrelated
+ // decls are modified, ZIR code containing references to them can be unmodified.
switch (rl) {
.ref, .none_or_ref => return gz.addStrTok(.decl_ref, name_str_index, ident_token),
else => {
@@ -8383,7 +8384,7 @@ fn nodeImpliesRuntimeBits(tree: *const ast.Tree, start_node: ast.Node.Index) boo
}
}
-/// Applies `rl` semantics to `inst`. Expressions which do not do their own handling of
+/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of
/// result locations must call this function on their result.
/// As an example, if the `ResultLoc` is `ptr`, it will write the result to the pointer.
/// If the `ResultLoc` is `ty`, it will coerce the result to the type.
@@ -8393,6 +8394,7 @@ fn rvalue(
result: Zir.Inst.Ref,
src_node: ast.Node.Index,
) InnerError!Zir.Inst.Ref {
+ if (gz.endsWithNoReturn()) return result;
switch (rl) {
.none, .none_or_ref, .coerced_ty => return result,
.discard => {
@@ -8941,6 +8943,7 @@ const Scope = struct {
/// Maps string table index to the source location of declaration,
/// for the purposes of reporting name shadowing compile errors.
decls: std.AutoHashMapUnmanaged(u32, ast.Node.Index) = .{},
+ node: ast.Node.Index,
};
const Top = struct {
@@ -10014,53 +10017,6 @@ fn nullTerminatedString(astgen: AstGen, index: usize) [*:0]const u8 {
return @ptrCast([*:0]const u8, astgen.string_bytes.items.ptr) + index;
}
-fn declareNewName(
- astgen: *AstGen,
- start_scope: *Scope,
- name_index: u32,
- node: ast.Node.Index,
- name_token: ast.TokenIndex,
-) !void {
- const gpa = astgen.gpa;
-
- const token_bytes = astgen.tree.tokenSlice(name_token);
- if (token_bytes[0] != '@' and isPrimitive(token_bytes)) {
- return astgen.failTokNotes(name_token, "name shadows primitive '{s}'", .{
- token_bytes,
- }, &[_]u32{
- try astgen.errNoteTok(name_token, "consider using @\"{s}\" to disambiguate", .{
- token_bytes,
- }),
- });
- }
-
- var scope = start_scope;
- while (true) {
- switch (scope.tag) {
- .gen_zir => scope = scope.cast(GenZir).?.parent,
- .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
- .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
- .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
- .namespace => {
- const ns = scope.cast(Scope.Namespace).?;
- const gop = try ns.decls.getOrPut(gpa, name_index);
- if (gop.found_existing) {
- const name = try gpa.dupe(u8, mem.span(astgen.nullTerminatedString(name_index)));
- defer gpa.free(name);
- return astgen.failNodeNotes(node, "redeclaration of '{s}'", .{
- name,
- }, &[_]u32{
- try astgen.errNoteNode(gop.value_ptr.*, "other declaration here", .{}),
- });
- }
- gop.value_ptr.* = node;
- break;
- },
- .top => break,
- }
- }
-}
-
fn isPrimitive(name: []const u8) bool {
if (simple_types.get(name) != null) return true;
if (name.len < 2) return false;
@@ -10183,3 +10139,56 @@ fn refToIndex(inst: Zir.Inst.Ref) ?Zir.Inst.Index {
return null;
}
}
+
+fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const ast.Node.Index) !void {
+ const gpa = astgen.gpa;
+ const tree = astgen.tree;
+ const node_tags = tree.nodes.items(.tag);
+ const main_tokens = tree.nodes.items(.main_token);
+ for (members) |member_node| {
+ const name_token = switch (node_tags[member_node]) {
+ .fn_decl,
+ .fn_proto_simple,
+ .fn_proto_multi,
+ .fn_proto_one,
+ .fn_proto,
+ .global_var_decl,
+ .local_var_decl,
+ .simple_var_decl,
+ .aligned_var_decl,
+ => main_tokens[member_node] + 1,
+
+ else => continue,
+ };
+
+ const token_bytes = astgen.tree.tokenSlice(name_token);
+ if (token_bytes[0] != '@' and isPrimitive(token_bytes)) {
+ switch (astgen.failTokNotes(name_token, "name shadows primitive '{s}'", .{
+ token_bytes,
+ }, &[_]u32{
+ try astgen.errNoteTok(name_token, "consider using @\"{s}\" to disambiguate", .{
+ token_bytes,
+ }),
+ })) {
+ error.AnalysisFail => continue,
+ error.OutOfMemory => return error.OutOfMemory,
+ }
+ }
+
+ const name_str_index = try astgen.identAsString(name_token);
+ const gop = try namespace.decls.getOrPut(gpa, name_str_index);
+ if (gop.found_existing) {
+ const name = try gpa.dupe(u8, mem.span(astgen.nullTerminatedString(name_str_index)));
+ defer gpa.free(name);
+ switch (astgen.failNodeNotes(member_node, "redeclaration of '{s}'", .{
+ name,
+ }, &[_]u32{
+ try astgen.errNoteNode(gop.value_ptr.*, "other declaration here", .{}),
+ })) {
+ error.AnalysisFail => continue,
+ error.OutOfMemory => return error.OutOfMemory,
+ }
+ }
+ gop.value_ptr.* = member_node;
+ }
+}
diff --git a/src/Module.zig b/src/Module.zig
index 4ed39c9954..77f880b492 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -2648,7 +2648,10 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {
undefined;
defer if (data_has_safety_tag) gpa.free(safety_buffer);
const data_ptr = if (data_has_safety_tag)
- @ptrCast([*]const u8, safety_buffer.ptr)
+ if (file.zir.instructions.len == 0)
+ @as([*]const u8, undefined)
+ else
+ @ptrCast([*]const u8, safety_buffer.ptr)
else
@ptrCast([*]const u8, file.zir.instructions.items(.data).ptr);
if (data_has_safety_tag) {
diff --git a/src/codegen.zig b/src/codegen.zig
index 9103c7ad17..7fd93369c9 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -5210,25 +5210,59 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
return error.CodegenFail;
}
- usingnamespace switch (arch) {
- .i386 => @import("codegen/x86.zig"),
- .x86_64 => @import("codegen/x86_64.zig"),
- .riscv64 => @import("codegen/riscv64.zig"),
- .arm, .armeb => @import("codegen/arm.zig"),
- .aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig"),
- else => struct {
- pub const Register = enum {
- dummy,
-
- pub fn allocIndex(self: Register) ?u4 {
- _ = self;
- return null;
- }
- };
- pub const callee_preserved_regs = [_]Register{};
+ const Register = switch (arch) {
+ .i386 => @import("codegen/x86.zig").Register,
+ .x86_64 => @import("codegen/x86_64.zig").Register,
+ .riscv64 => @import("codegen/riscv64.zig").Register,
+ .arm, .armeb => @import("codegen/arm.zig").Register,
+ .aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").Register,
+ else => enum {
+ dummy,
+
+ pub fn allocIndex(self: Register) ?u4 {
+ _ = self;
+ return null;
+ }
},
};
+ const Instruction = switch (arch) {
+ .riscv64 => @import("codegen/riscv64.zig").Instruction,
+ .arm, .armeb => @import("codegen/arm.zig").Instruction,
+ .aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").Instruction,
+ else => void,
+ };
+
+ const Condition = switch (arch) {
+ .arm, .armeb => @import("codegen/arm.zig").Condition,
+ else => void,
+ };
+
+ const callee_preserved_regs = switch (arch) {
+ .i386 => @import("codegen/x86.zig").callee_preserved_regs,
+ .x86_64 => @import("codegen/x86_64.zig").callee_preserved_regs,
+ .riscv64 => @import("codegen/riscv64.zig").callee_preserved_regs,
+ .arm, .armeb => @import("codegen/arm.zig").callee_preserved_regs,
+ .aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").callee_preserved_regs,
+ else => [_]Register{},
+ };
+
+ const c_abi_int_param_regs = switch (arch) {
+ .i386 => @import("codegen/x86.zig").c_abi_int_param_regs,
+ .x86_64 => @import("codegen/x86_64.zig").c_abi_int_param_regs,
+ .arm, .armeb => @import("codegen/arm.zig").c_abi_int_param_regs,
+ .aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").c_abi_int_param_regs,
+ else => [_]Register{},
+ };
+
+ const c_abi_int_return_regs = switch (arch) {
+ .i386 => @import("codegen/x86.zig").c_abi_int_return_regs,
+ .x86_64 => @import("codegen/x86_64.zig").c_abi_int_return_regs,
+ .arm, .armeb => @import("codegen/arm.zig").c_abi_int_return_regs,
+ .aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig").c_abi_int_return_regs,
+ else => [_]Register{},
+ };
+
fn parseRegName(name: []const u8) ?Register {
if (@hasDecl(Register, "parseRegName")) {
return Register.parseRegName(name);
diff --git a/src/codegen/arm.zig b/src/codegen/arm.zig
index 3743afd50f..42e3e52fac 100644
--- a/src/codegen/arm.zig
+++ b/src/codegen/arm.zig
@@ -886,11 +886,11 @@ pub const Instruction = union(enum) {
return dataProcessing(cond, .mov, 1, rd, .r0, op2);
}
- pub fn bic(cond: Condition, rd: Register, op2: Operand) Instruction {
+ pub fn bic(cond: Condition, rd: Register, rn: Register, op2: Operand) Instruction {
return dataProcessing(cond, .bic, 0, rd, rn, op2);
}
- pub fn bics(cond: Condition, rd: Register, op2: Operand) Instruction {
+ pub fn bics(cond: Condition, rd: Register, rn: Register, op2: Operand) Instruction {
return dataProcessing(cond, .bic, 1, rd, rn, op2);
}
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 0a715edbfd..4b2de9fd93 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -169,7 +169,7 @@ pub const Object = struct {
const context = llvm.Context.create();
errdefer context.dispose();
- initializeLLVMTargets();
+ initializeLLVMTarget(options.target.cpu.arch);
const root_nameZ = try gpa.dupeZ(u8, options.root_name);
defer gpa.free(root_nameZ);
@@ -258,14 +258,6 @@ pub const Object = struct {
gpa.destroy(self);
}
- fn initializeLLVMTargets() void {
- llvm.initializeAllTargets();
- llvm.initializeAllTargetInfos();
- llvm.initializeAllTargetMCs();
- llvm.initializeAllAsmPrinters();
- llvm.initializeAllAsmParsers();
- }
-
fn locPath(
arena: *Allocator,
opt_loc: ?Compilation.EmitLoc,
@@ -1960,3 +1952,144 @@ pub const FuncGen = struct {
return self.llvmModule().getIntrinsicDeclaration(id, null, 0);
}
};
+
+fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
+ switch (arch) {
+ .aarch64, .aarch64_be, .aarch64_32 => {
+ llvm.LLVMInitializeAArch64Target();
+ llvm.LLVMInitializeAArch64TargetInfo();
+ llvm.LLVMInitializeAArch64TargetMC();
+ llvm.LLVMInitializeAArch64AsmPrinter();
+ llvm.LLVMInitializeAArch64AsmParser();
+ },
+ .amdgcn => {
+ llvm.LLVMInitializeAMDGPUTarget();
+ llvm.LLVMInitializeAMDGPUTargetInfo();
+ llvm.LLVMInitializeAMDGPUTargetMC();
+ llvm.LLVMInitializeAMDGPUAsmPrinter();
+ llvm.LLVMInitializeAMDGPUAsmParser();
+ },
+ .arm, .armeb => {
+ llvm.LLVMInitializeARMTarget();
+ llvm.LLVMInitializeARMTargetInfo();
+ llvm.LLVMInitializeARMTargetMC();
+ llvm.LLVMInitializeARMAsmPrinter();
+ llvm.LLVMInitializeARMAsmParser();
+ },
+ .avr => {
+ llvm.LLVMInitializeAVRTarget();
+ llvm.LLVMInitializeAVRTargetInfo();
+ llvm.LLVMInitializeAVRTargetMC();
+ llvm.LLVMInitializeAVRAsmPrinter();
+ llvm.LLVMInitializeAVRAsmParser();
+ },
+ .bpfel, .bpfeb => {
+ llvm.LLVMInitializeBPFTarget();
+ llvm.LLVMInitializeBPFTargetInfo();
+ llvm.LLVMInitializeBPFTargetMC();
+ llvm.LLVMInitializeBPFAsmPrinter();
+ llvm.LLVMInitializeBPFAsmParser();
+ },
+ .hexagon => {
+ llvm.LLVMInitializeHexagonTarget();
+ llvm.LLVMInitializeHexagonTargetInfo();
+ llvm.LLVMInitializeHexagonTargetMC();
+ llvm.LLVMInitializeHexagonAsmPrinter();
+ llvm.LLVMInitializeHexagonAsmParser();
+ },
+ .lanai => {
+ llvm.LLVMInitializeLanaiTarget();
+ llvm.LLVMInitializeLanaiTargetInfo();
+ llvm.LLVMInitializeLanaiTargetMC();
+ llvm.LLVMInitializeLanaiAsmPrinter();
+ llvm.LLVMInitializeLanaiAsmParser();
+ },
+ .mips, .mipsel, .mips64, .mips64el => {
+ llvm.LLVMInitializeMipsTarget();
+ llvm.LLVMInitializeMipsTargetInfo();
+ llvm.LLVMInitializeMipsTargetMC();
+ llvm.LLVMInitializeMipsAsmPrinter();
+ llvm.LLVMInitializeMipsAsmParser();
+ },
+ .msp430 => {
+ llvm.LLVMInitializeMSP430Target();
+ llvm.LLVMInitializeMSP430TargetInfo();
+ llvm.LLVMInitializeMSP430TargetMC();
+ llvm.LLVMInitializeMSP430AsmPrinter();
+ llvm.LLVMInitializeMSP430AsmParser();
+ },
+ .nvptx, .nvptx64 => {
+ llvm.LLVMInitializeNVPTXTarget();
+ llvm.LLVMInitializeNVPTXTargetInfo();
+ llvm.LLVMInitializeNVPTXTargetMC();
+ llvm.LLVMInitializeNVPTXAsmPrinter();
+ // There is no LLVMInitializeNVPTXAsmParser function available.
+ },
+ .powerpc, .powerpcle, .powerpc64, .powerpc64le => {
+ llvm.LLVMInitializePowerPCTarget();
+ llvm.LLVMInitializePowerPCTargetInfo();
+ llvm.LLVMInitializePowerPCTargetMC();
+ llvm.LLVMInitializePowerPCAsmPrinter();
+ llvm.LLVMInitializePowerPCAsmParser();
+ },
+ .riscv32, .riscv64 => {
+ llvm.LLVMInitializeRISCVTarget();
+ llvm.LLVMInitializeRISCVTargetInfo();
+ llvm.LLVMInitializeRISCVTargetMC();
+ llvm.LLVMInitializeRISCVAsmPrinter();
+ llvm.LLVMInitializeRISCVAsmParser();
+ },
+ .sparc, .sparcv9, .sparcel => {
+ llvm.LLVMInitializeSparcTarget();
+ llvm.LLVMInitializeSparcTargetInfo();
+ llvm.LLVMInitializeSparcTargetMC();
+ llvm.LLVMInitializeSparcAsmPrinter();
+ llvm.LLVMInitializeSparcAsmParser();
+ },
+ .s390x => {
+ llvm.LLVMInitializeSystemZTarget();
+ llvm.LLVMInitializeSystemZTargetInfo();
+ llvm.LLVMInitializeSystemZTargetMC();
+ llvm.LLVMInitializeSystemZAsmPrinter();
+ llvm.LLVMInitializeSystemZAsmParser();
+ },
+ .wasm32, .wasm64 => {
+ llvm.LLVMInitializeWebAssemblyTarget();
+ llvm.LLVMInitializeWebAssemblyTargetInfo();
+ llvm.LLVMInitializeWebAssemblyTargetMC();
+ llvm.LLVMInitializeWebAssemblyAsmPrinter();
+ llvm.LLVMInitializeWebAssemblyAsmParser();
+ },
+ .i386, .x86_64 => {
+ llvm.LLVMInitializeX86Target();
+ llvm.LLVMInitializeX86TargetInfo();
+ llvm.LLVMInitializeX86TargetMC();
+ llvm.LLVMInitializeX86AsmPrinter();
+ llvm.LLVMInitializeX86AsmParser();
+ },
+ .xcore => {
+ llvm.LLVMInitializeXCoreTarget();
+ llvm.LLVMInitializeXCoreTargetInfo();
+ llvm.LLVMInitializeXCoreTargetMC();
+ llvm.LLVMInitializeXCoreAsmPrinter();
+ // There is no LLVMInitializeXCoreAsmParser function available.
+ },
+ .arc => {},
+ .csky => {},
+ .r600 => {},
+ .tce, .tcele => {},
+ .thumb, .thumbeb => {},
+ .le32, .le64 => {},
+ .amdil, .amdil64 => {},
+ .hsail, .hsail64 => {},
+ .spir, .spir64 => {},
+ .kalimba => {},
+ .shave => {},
+ .renderscript32 => {},
+ .renderscript64 => {},
+ .ve => {},
+ .spu_2 => {},
+ .spirv32 => {},
+ .spirv64 => {},
+ }
+}
diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig
index fe0c211df3..4542b78644 100644
--- a/src/codegen/llvm/bindings.zig
+++ b/src/codegen/llvm/bindings.zig
@@ -597,188 +597,93 @@ pub const Target = opaque {
extern fn LLVMGetTargetFromTriple(Triple: [*:0]const u8, T: **const Target, ErrorMessage: *[*:0]const u8) Bool;
};
-extern fn LLVMInitializeAArch64TargetInfo() void;
-extern fn LLVMInitializeAMDGPUTargetInfo() void;
-extern fn LLVMInitializeARMTargetInfo() void;
-extern fn LLVMInitializeAVRTargetInfo() void;
-extern fn LLVMInitializeBPFTargetInfo() void;
-extern fn LLVMInitializeHexagonTargetInfo() void;
-extern fn LLVMInitializeLanaiTargetInfo() void;
-extern fn LLVMInitializeMipsTargetInfo() void;
-extern fn LLVMInitializeMSP430TargetInfo() void;
-extern fn LLVMInitializeNVPTXTargetInfo() void;
-extern fn LLVMInitializePowerPCTargetInfo() void;
-extern fn LLVMInitializeRISCVTargetInfo() void;
-extern fn LLVMInitializeSparcTargetInfo() void;
-extern fn LLVMInitializeSystemZTargetInfo() void;
-extern fn LLVMInitializeWebAssemblyTargetInfo() void;
-extern fn LLVMInitializeX86TargetInfo() void;
-extern fn LLVMInitializeXCoreTargetInfo() void;
-extern fn LLVMInitializeAArch64Target() void;
-extern fn LLVMInitializeAMDGPUTarget() void;
-extern fn LLVMInitializeARMTarget() void;
-extern fn LLVMInitializeAVRTarget() void;
-extern fn LLVMInitializeBPFTarget() void;
-extern fn LLVMInitializeHexagonTarget() void;
-extern fn LLVMInitializeLanaiTarget() void;
-extern fn LLVMInitializeMipsTarget() void;
-extern fn LLVMInitializeMSP430Target() void;
-extern fn LLVMInitializeNVPTXTarget() void;
-extern fn LLVMInitializePowerPCTarget() void;
-extern fn LLVMInitializeRISCVTarget() void;
-extern fn LLVMInitializeSparcTarget() void;
-extern fn LLVMInitializeSystemZTarget() void;
-extern fn LLVMInitializeWebAssemblyTarget() void;
-extern fn LLVMInitializeX86Target() void;
-extern fn LLVMInitializeXCoreTarget() void;
-extern fn LLVMInitializeAArch64TargetMC() void;
-extern fn LLVMInitializeAMDGPUTargetMC() void;
-extern fn LLVMInitializeARMTargetMC() void;
-extern fn LLVMInitializeAVRTargetMC() void;
-extern fn LLVMInitializeBPFTargetMC() void;
-extern fn LLVMInitializeHexagonTargetMC() void;
-extern fn LLVMInitializeLanaiTargetMC() void;
-extern fn LLVMInitializeMipsTargetMC() void;
-extern fn LLVMInitializeMSP430TargetMC() void;
-extern fn LLVMInitializeNVPTXTargetMC() void;
-extern fn LLVMInitializePowerPCTargetMC() void;
-extern fn LLVMInitializeRISCVTargetMC() void;
-extern fn LLVMInitializeSparcTargetMC() void;
-extern fn LLVMInitializeSystemZTargetMC() void;
-extern fn LLVMInitializeWebAssemblyTargetMC() void;
-extern fn LLVMInitializeX86TargetMC() void;
-extern fn LLVMInitializeXCoreTargetMC() void;
-extern fn LLVMInitializeAArch64AsmPrinter() void;
-extern fn LLVMInitializeAMDGPUAsmPrinter() void;
-extern fn LLVMInitializeARMAsmPrinter() void;
-extern fn LLVMInitializeAVRAsmPrinter() void;
-extern fn LLVMInitializeBPFAsmPrinter() void;
-extern fn LLVMInitializeHexagonAsmPrinter() void;
-extern fn LLVMInitializeLanaiAsmPrinter() void;
-extern fn LLVMInitializeMipsAsmPrinter() void;
-extern fn LLVMInitializeMSP430AsmPrinter() void;
-extern fn LLVMInitializeNVPTXAsmPrinter() void;
-extern fn LLVMInitializePowerPCAsmPrinter() void;
-extern fn LLVMInitializeRISCVAsmPrinter() void;
-extern fn LLVMInitializeSparcAsmPrinter() void;
-extern fn LLVMInitializeSystemZAsmPrinter() void;
-extern fn LLVMInitializeWebAssemblyAsmPrinter() void;
-extern fn LLVMInitializeX86AsmPrinter() void;
-extern fn LLVMInitializeXCoreAsmPrinter() void;
-extern fn LLVMInitializeAArch64AsmParser() void;
-extern fn LLVMInitializeAMDGPUAsmParser() void;
-extern fn LLVMInitializeARMAsmParser() void;
-extern fn LLVMInitializeAVRAsmParser() void;
-extern fn LLVMInitializeBPFAsmParser() void;
-extern fn LLVMInitializeHexagonAsmParser() void;
-extern fn LLVMInitializeLanaiAsmParser() void;
-extern fn LLVMInitializeMipsAsmParser() void;
-extern fn LLVMInitializeMSP430AsmParser() void;
-extern fn LLVMInitializePowerPCAsmParser() void;
-extern fn LLVMInitializeRISCVAsmParser() void;
-extern fn LLVMInitializeSparcAsmParser() void;
-extern fn LLVMInitializeSystemZAsmParser() void;
-extern fn LLVMInitializeWebAssemblyAsmParser() void;
-extern fn LLVMInitializeX86AsmParser() void;
-
-pub const initializeAllTargetInfos = LLVMInitializeAllTargetInfos;
-fn LLVMInitializeAllTargetInfos() callconv(.C) void {
- LLVMInitializeAArch64TargetInfo();
- LLVMInitializeAMDGPUTargetInfo();
- LLVMInitializeARMTargetInfo();
- LLVMInitializeAVRTargetInfo();
- LLVMInitializeBPFTargetInfo();
- LLVMInitializeHexagonTargetInfo();
- LLVMInitializeLanaiTargetInfo();
- LLVMInitializeMipsTargetInfo();
- LLVMInitializeMSP430TargetInfo();
- LLVMInitializeNVPTXTargetInfo();
- LLVMInitializePowerPCTargetInfo();
- LLVMInitializeRISCVTargetInfo();
- LLVMInitializeSparcTargetInfo();
- LLVMInitializeSystemZTargetInfo();
- LLVMInitializeWebAssemblyTargetInfo();
- LLVMInitializeX86TargetInfo();
- LLVMInitializeXCoreTargetInfo();
-}
-pub const initializeAllTargets = LLVMInitializeAllTargets;
-fn LLVMInitializeAllTargets() callconv(.C) void {
- LLVMInitializeAArch64Target();
- LLVMInitializeAMDGPUTarget();
- LLVMInitializeARMTarget();
- LLVMInitializeAVRTarget();
- LLVMInitializeBPFTarget();
- LLVMInitializeHexagonTarget();
- LLVMInitializeLanaiTarget();
- LLVMInitializeMipsTarget();
- LLVMInitializeMSP430Target();
- LLVMInitializeNVPTXTarget();
- LLVMInitializePowerPCTarget();
- LLVMInitializeRISCVTarget();
- LLVMInitializeSparcTarget();
- LLVMInitializeSystemZTarget();
- LLVMInitializeWebAssemblyTarget();
- LLVMInitializeX86Target();
- LLVMInitializeXCoreTarget();
-}
-pub const initializeAllTargetMCs = LLVMInitializeAllTargetMCs;
-fn LLVMInitializeAllTargetMCs() callconv(.C) void {
- LLVMInitializeAArch64TargetMC();
- LLVMInitializeAMDGPUTargetMC();
- LLVMInitializeARMTargetMC();
- LLVMInitializeAVRTargetMC();
- LLVMInitializeBPFTargetMC();
- LLVMInitializeHexagonTargetMC();
- LLVMInitializeLanaiTargetMC();
- LLVMInitializeMipsTargetMC();
- LLVMInitializeMSP430TargetMC();
- LLVMInitializeNVPTXTargetMC();
- LLVMInitializePowerPCTargetMC();
- LLVMInitializeRISCVTargetMC();
- LLVMInitializeSparcTargetMC();
- LLVMInitializeSystemZTargetMC();
- LLVMInitializeWebAssemblyTargetMC();
- LLVMInitializeX86TargetMC();
- LLVMInitializeXCoreTargetMC();
-}
-pub const initializeAllAsmPrinters = LLVMInitializeAllAsmPrinters;
-fn LLVMInitializeAllAsmPrinters() callconv(.C) void {
- LLVMInitializeAArch64AsmPrinter();
- LLVMInitializeAMDGPUAsmPrinter();
- LLVMInitializeARMAsmPrinter();
- LLVMInitializeAVRAsmPrinter();
- LLVMInitializeBPFAsmPrinter();
- LLVMInitializeHexagonAsmPrinter();
- LLVMInitializeLanaiAsmPrinter();
- LLVMInitializeMipsAsmPrinter();
- LLVMInitializeMSP430AsmPrinter();
- LLVMInitializeNVPTXAsmPrinter();
- LLVMInitializePowerPCAsmPrinter();
- LLVMInitializeRISCVAsmPrinter();
- LLVMInitializeSparcAsmPrinter();
- LLVMInitializeSystemZAsmPrinter();
- LLVMInitializeWebAssemblyAsmPrinter();
- LLVMInitializeX86AsmPrinter();
- LLVMInitializeXCoreAsmPrinter();
-}
-pub const initializeAllAsmParsers = LLVMInitializeAllAsmParsers;
-fn LLVMInitializeAllAsmParsers() callconv(.C) void {
- LLVMInitializeAArch64AsmParser();
- LLVMInitializeAMDGPUAsmParser();
- LLVMInitializeARMAsmParser();
- LLVMInitializeAVRAsmParser();
- LLVMInitializeBPFAsmParser();
- LLVMInitializeHexagonAsmParser();
- LLVMInitializeLanaiAsmParser();
- LLVMInitializeMipsAsmParser();
- LLVMInitializeMSP430AsmParser();
- LLVMInitializePowerPCAsmParser();
- LLVMInitializeRISCVAsmParser();
- LLVMInitializeSparcAsmParser();
- LLVMInitializeSystemZAsmParser();
- LLVMInitializeWebAssemblyAsmParser();
- LLVMInitializeX86AsmParser();
-}
+pub extern fn LLVMInitializeAArch64TargetInfo() void;
+pub extern fn LLVMInitializeAMDGPUTargetInfo() void;
+pub extern fn LLVMInitializeARMTargetInfo() void;
+pub extern fn LLVMInitializeAVRTargetInfo() void;
+pub extern fn LLVMInitializeBPFTargetInfo() void;
+pub extern fn LLVMInitializeHexagonTargetInfo() void;
+pub extern fn LLVMInitializeLanaiTargetInfo() void;
+pub extern fn LLVMInitializeMipsTargetInfo() void;
+pub extern fn LLVMInitializeMSP430TargetInfo() void;
+pub extern fn LLVMInitializeNVPTXTargetInfo() void;
+pub extern fn LLVMInitializePowerPCTargetInfo() void;
+pub extern fn LLVMInitializeRISCVTargetInfo() void;
+pub extern fn LLVMInitializeSparcTargetInfo() void;
+pub extern fn LLVMInitializeSystemZTargetInfo() void;
+pub extern fn LLVMInitializeWebAssemblyTargetInfo() void;
+pub extern fn LLVMInitializeX86TargetInfo() void;
+pub extern fn LLVMInitializeXCoreTargetInfo() void;
+
+pub extern fn LLVMInitializeAArch64Target() void;
+pub extern fn LLVMInitializeAMDGPUTarget() void;
+pub extern fn LLVMInitializeARMTarget() void;
+pub extern fn LLVMInitializeAVRTarget() void;
+pub extern fn LLVMInitializeBPFTarget() void;
+pub extern fn LLVMInitializeHexagonTarget() void;
+pub extern fn LLVMInitializeLanaiTarget() void;
+pub extern fn LLVMInitializeMipsTarget() void;
+pub extern fn LLVMInitializeMSP430Target() void;
+pub extern fn LLVMInitializeNVPTXTarget() void;
+pub extern fn LLVMInitializePowerPCTarget() void;
+pub extern fn LLVMInitializeRISCVTarget() void;
+pub extern fn LLVMInitializeSparcTarget() void;
+pub extern fn LLVMInitializeSystemZTarget() void;
+pub extern fn LLVMInitializeWebAssemblyTarget() void;
+pub extern fn LLVMInitializeX86Target() void;
+pub extern fn LLVMInitializeXCoreTarget() void;
+
+pub extern fn LLVMInitializeAArch64TargetMC() void;
+pub extern fn LLVMInitializeAMDGPUTargetMC() void;
+pub extern fn LLVMInitializeARMTargetMC() void;
+pub extern fn LLVMInitializeAVRTargetMC() void;
+pub extern fn LLVMInitializeBPFTargetMC() void;
+pub extern fn LLVMInitializeHexagonTargetMC() void;
+pub extern fn LLVMInitializeLanaiTargetMC() void;
+pub extern fn LLVMInitializeMipsTargetMC() void;
+pub extern fn LLVMInitializeMSP430TargetMC() void;
+pub extern fn LLVMInitializeNVPTXTargetMC() void;
+pub extern fn LLVMInitializePowerPCTargetMC() void;
+pub extern fn LLVMInitializeRISCVTargetMC() void;
+pub extern fn LLVMInitializeSparcTargetMC() void;
+pub extern fn LLVMInitializeSystemZTargetMC() void;
+pub extern fn LLVMInitializeWebAssemblyTargetMC() void;
+pub extern fn LLVMInitializeX86TargetMC() void;
+pub extern fn LLVMInitializeXCoreTargetMC() void;
+
+pub extern fn LLVMInitializeAArch64AsmPrinter() void;
+pub extern fn LLVMInitializeAMDGPUAsmPrinter() void;
+pub extern fn LLVMInitializeARMAsmPrinter() void;
+pub extern fn LLVMInitializeAVRAsmPrinter() void;
+pub extern fn LLVMInitializeBPFAsmPrinter() void;
+pub extern fn LLVMInitializeHexagonAsmPrinter() void;
+pub extern fn LLVMInitializeLanaiAsmPrinter() void;
+pub extern fn LLVMInitializeMipsAsmPrinter() void;
+pub extern fn LLVMInitializeMSP430AsmPrinter() void;
+pub extern fn LLVMInitializeNVPTXAsmPrinter() void;
+pub extern fn LLVMInitializePowerPCAsmPrinter() void;
+pub extern fn LLVMInitializeRISCVAsmPrinter() void;
+pub extern fn LLVMInitializeSparcAsmPrinter() void;
+pub extern fn LLVMInitializeSystemZAsmPrinter() void;
+pub extern fn LLVMInitializeWebAssemblyAsmPrinter() void;
+pub extern fn LLVMInitializeX86AsmPrinter() void;
+pub extern fn LLVMInitializeXCoreAsmPrinter() void;
+
+pub extern fn LLVMInitializeAArch64AsmParser() void;
+pub extern fn LLVMInitializeAMDGPUAsmParser() void;
+pub extern fn LLVMInitializeARMAsmParser() void;
+pub extern fn LLVMInitializeAVRAsmParser() void;
+pub extern fn LLVMInitializeBPFAsmParser() void;
+pub extern fn LLVMInitializeHexagonAsmParser() void;
+pub extern fn LLVMInitializeLanaiAsmParser() void;
+pub extern fn LLVMInitializeMipsAsmParser() void;
+pub extern fn LLVMInitializeMSP430AsmParser() void;
+pub extern fn LLVMInitializePowerPCAsmParser() void;
+pub extern fn LLVMInitializeRISCVAsmParser() void;
+pub extern fn LLVMInitializeSparcAsmParser() void;
+pub extern fn LLVMInitializeSystemZAsmParser() void;
+pub extern fn LLVMInitializeWebAssemblyAsmParser() void;
+pub extern fn LLVMInitializeX86AsmParser() void;
extern fn ZigLLDLinkCOFF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
extern fn ZigLLDLinkELF(argc: c_int, argv: [*:null]const ?[*:0]const u8, can_exit_early: bool) c_int;
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 3b6eccbc3a..b2d75ab658 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -148,7 +148,7 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{},
stub_helper_stubs_start_off: ?u64 = null,
strtab: std.ArrayListUnmanaged(u8) = .{},
-strtab_dir: std.HashMapUnmanaged(u32, u32, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
+strtab_dir: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
got_entries: std.ArrayListUnmanaged(GotIndirectionKey) = .{},
got_entries_map: std.AutoHashMapUnmanaged(GotIndirectionKey, u32) = .{},
@@ -938,7 +938,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
{
// Add dyld_stub_binder as the final GOT entry.
- const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
+ const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
.strtab = &self.strtab,
}) orelse unreachable;
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
@@ -1966,7 +1966,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
code[9] = 0xff;
code[10] = 0x25;
{
- const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
+ const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
.strtab = &self.strtab,
}) orelse unreachable;
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
@@ -2017,7 +2017,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
code[10] = 0xbf;
code[11] = 0xa9;
binder_blk_outer: {
- const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
+ const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
.strtab = &self.strtab,
}) orelse unreachable;
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
@@ -2435,7 +2435,7 @@ fn resolveSymbols(self: *MachO) !void {
}
// Fourth pass, handle synthetic symbols and flag any undefined references.
- if (self.strtab_dir.getAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{
+ if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{
.strtab = &self.strtab,
})) |n_strx| blk: {
const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;
@@ -2985,7 +2985,7 @@ fn setEntryPoint(self: *MachO) !void {
// TODO we should respect the -entry flag passed in by the user to set a custom
// entrypoint. For now, assume default of `_main`.
const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
- const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "_main"), StringSliceAdapter{
+ const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringSliceAdapter{
.strtab = &self.strtab,
}) orelse {
log.err("'_main' export not found", .{});
@@ -4616,7 +4616,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
defer self.base.allocator.free(sym_name);
- if (self.strtab_dir.getAdapted(@as([]const u8, sym_name), StringSliceAdapter{
+ if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringSliceAdapter{
.strtab = &self.strtab,
})) |n_strx| {
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
@@ -5858,7 +5858,13 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
}
pub fn makeString(self: *MachO, string: []const u8) !u32 {
- if (self.strtab_dir.getAdapted(@as([]const u8, string), StringSliceAdapter{ .strtab = &self.strtab })) |off| {
+ const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringSliceAdapter{
+ .strtab = &self.strtab,
+ }, StringIndexContext{
+ .strtab = &self.strtab,
+ });
+ if (gop.found_existing) {
+ const off = gop.key_ptr.*;
log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off });
return off;
}
@@ -5871,9 +5877,7 @@ pub fn makeString(self: *MachO, string: []const u8) !u32 {
self.strtab.appendSliceAssumeCapacity(string);
self.strtab.appendAssumeCapacity(0);
- try self.strtab_dir.putContext(self.base.allocator, new_off, new_off, StringIndexContext{
- .strtab = &self.strtab,
- });
+ gop.key_ptr.* = new_off;
return new_off;
}
diff --git a/src/link/MachO/TextBlock.zig b/src/link/MachO/TextBlock.zig
index 4788487d3b..4d103fa6eb 100644
--- a/src/link/MachO/TextBlock.zig
+++ b/src/link/MachO/TextBlock.zig
@@ -656,7 +656,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc
parsed_rel.where = .local;
parsed_rel.where_index = where_index;
} else {
- const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
+ const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
.strtab = &context.macho_file.strtab,
}) orelse unreachable;
const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
@@ -717,7 +717,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
subtractor = where_index;
} else {
- const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
+ const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
.strtab = &context.macho_file.strtab,
}) orelse unreachable;
const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
diff --git a/src/translate_c.zig b/src/translate_c.zig
index 0cc40cdfd4..6b7165176b 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -203,9 +203,7 @@ const Scope = struct {
/// Check if the global scope contains this name, without looking into the "future", e.g.
/// ignore the preprocessed decl and macro names.
fn containsNow(scope: *Root, name: []const u8) bool {
- return isZigPrimitiveType(name) or
- scope.sym_table.contains(name) or
- scope.macro_table.contains(name);
+ return scope.sym_table.contains(name) or scope.macro_table.contains(name);
}
/// Check if the global scope contains the name, includes all decls that haven't been translated yet.
@@ -495,19 +493,17 @@ fn declVisitorNamesOnly(c: *Context, decl: *const clang.Decl) Error!void {
},
else => return,
} else unreachable;
- // TODO https://github.com/ziglang/zig/issues/3756
- // TODO https://github.com/ziglang/zig/issues/1802
- const name = if (isZigPrimitiveType(decl_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ decl_name, c.getMangle() }) else decl_name;
+
const result = try c.unnamed_typedefs.getOrPut(c.gpa, addr);
if (result.found_existing) {
// One typedef can declare multiple names.
// Don't put this one in `decl_table` so it's processed later.
return;
}
- result.value_ptr.* = name;
+ result.value_ptr.* = decl_name;
// Put this typedef in the decl_table to avoid redefinitions.
- try c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), name);
- try c.typedefs.put(c.gpa, name, {});
+ try c.decl_table.putNoClobber(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), decl_name);
+ try c.typedefs.put(c.gpa, decl_name, {});
}
}
}
@@ -752,10 +748,6 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
const is_pub = mangled_name == null;
const is_threadlocal = var_decl.getTLSKind() != .None;
const scope = &c.global_scope.base;
-
- // TODO https://github.com/ziglang/zig/issues/3756
- // TODO https://github.com/ziglang/zig/issues/1802
- const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ var_name, c.getMangle() }) else var_name;
const var_decl_loc = var_decl.getLocation();
const qual_type = var_decl.getTypeSourceInfo_getType();
@@ -774,7 +766,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
const type_node = transQualTypeMaybeInitialized(c, scope, qual_type, decl_init, var_decl_loc) catch |err| switch (err) {
error.UnsupportedTranslation, error.UnsupportedType => {
- return failDecl(c, var_decl_loc, checked_name, "unable to resolve variable type", .{});
+ return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{});
},
error.OutOfMemory => |e| return e,
};
@@ -833,11 +825,11 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
.is_threadlocal = is_threadlocal,
.linksection_string = linksection_string,
.alignment = zigAlignment(var_decl.getAlignedAttribute(c.clang_context)),
- .name = checked_name,
+ .name = var_name,
.type = type_node,
.init = init_node,
});
- return addTopLevelDecl(c, checked_name, node);
+ return addTopLevelDecl(c, var_name, node);
}
const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{
@@ -861,11 +853,7 @@ fn transTypeDef(c: *Context, scope: *Scope, typedef_decl: *const clang.TypedefNa
const toplevel = scope.id == .root;
const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined;
- const bare_name = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin());
-
- // TODO https://github.com/ziglang/zig/issues/3756
- // TODO https://github.com/ziglang/zig/issues/1802
- var name: []const u8 = if (isZigPrimitiveType(bare_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ bare_name, c.getMangle() }) else bare_name;
+ var name: []const u8 = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin());
try c.typedefs.put(c.gpa, name, {});
if (builtin_typedef_map.get(name)) |builtin| {
@@ -1535,12 +1523,12 @@ fn transOffsetOfExpr(
/// node -> @bitCast(usize, @intCast(isize, node))
fn usizeCastForWrappingPtrArithmetic(gpa: *mem.Allocator, node: Node) TransError!Node {
const intcast_node = try Tag.int_cast.create(gpa, .{
- .lhs = try Tag.identifier.create(gpa, "isize"),
+ .lhs = try Tag.type.create(gpa, "isize"),
.rhs = node,
});
return Tag.bit_cast.create(gpa, .{
- .lhs = try Tag.identifier.create(gpa, "usize"),
+ .lhs = try Tag.type.create(gpa, "usize"),
.rhs = intcast_node,
});
}
@@ -3345,7 +3333,7 @@ fn transSignedArrayAccess(
const then_value = try Tag.add.create(c.arena, .{
.lhs = container_node,
.rhs = try Tag.int_cast.create(c.arena, .{
- .lhs = try Tag.identifier.create(c.arena, "usize"),
+ .lhs = try Tag.type.create(c.arena, "usize"),
.rhs = tmp_ref,
}),
});
@@ -3357,7 +3345,7 @@ fn transSignedArrayAccess(
const minuend = container_node;
const signed_size = try Tag.int_cast.create(c.arena, .{
- .lhs = try Tag.identifier.create(c.arena, "isize"),
+ .lhs = try Tag.type.create(c.arena, "isize"),
.rhs = tmp_ref,
});
const to_cast = try Tag.add_wrap.create(c.arena, .{
@@ -3365,7 +3353,7 @@ fn transSignedArrayAccess(
.rhs = try Tag.negate.create(c.arena, Tag.one_literal.init()),
});
const bitcast_node = try Tag.bit_cast.create(c.arena, .{
- .lhs = try Tag.identifier.create(c.arena, "usize"),
+ .lhs = try Tag.type.create(c.arena, "usize"),
.rhs = to_cast,
});
const subtrahend = try Tag.bit_not.create(c.arena, bitcast_node);
@@ -3421,7 +3409,7 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip
const container_node = try transExpr(c, scope, unwrapped_base, .used);
const rhs = if (is_longlong or is_signed) blk: {
// check if long long first so that signed long long doesn't just become unsigned long long
- const typeid_node = if (is_longlong) try Tag.identifier.create(c.arena, "usize") else try transQualTypeIntWidthOf(c, subscr_qt, false);
+ const typeid_node = if (is_longlong) try Tag.type.create(c.arena, "usize") else try transQualTypeIntWidthOf(c, subscr_qt, false);
break :blk try Tag.int_cast.create(c.arena, .{ .lhs = typeid_node, .rhs = try transExpr(c, scope, subscr_expr, .used) });
} else try transExpr(c, scope, subscr_expr, .used);
@@ -3953,7 +3941,7 @@ fn transFloatingLiteral(c: *Context, scope: *Scope, expr: *const clang.FloatingL
fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.BinaryConditionalOperator, used: ResultUsed) TransError!Node {
// GNU extension of the ternary operator where the middle expression is
- // omitted, the conditition itself is returned if it evaluates to true
+ // omitted, the condition itself is returned if it evaluates to true
const qt = @ptrCast(*const clang.Expr, stmt).getType();
const res_is_bool = qualTypeIsBoolean(qt);
const casted_stmt = @ptrCast(*const clang.AbstractConditionalOperator, stmt);
@@ -4040,7 +4028,7 @@ fn transConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.Condi
.then = then_body,
.@"else" = else_body,
});
- // Clang inserts ImplicitCast(ToVoid)'s to both rhs and lhs so we don't need to supress the result here.
+ // Clang inserts ImplicitCast(ToVoid)'s to both rhs and lhs so we don't need to suppress the result here.
return if_node;
}
@@ -4671,6 +4659,7 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan
if (@ptrCast(*const clang.Decl, typedef_decl).castToNamedDecl()) |named_decl| {
const decl_name = try c.str(named_decl.getName_bytes_begin());
if (c.global_names.get(decl_name)) |_| trans_scope = &c.global_scope.base;
+ if (builtin_typedef_map.get(decl_name)) |builtin| return Tag.type.create(c.arena, builtin);
}
try transTypeDef(c, trans_scope, typedef_decl);
const name = c.decl_table.get(@ptrToInt(typedef_decl.getCanonicalDecl())).?;
@@ -4994,19 +4983,6 @@ pub fn freeErrors(errors: []ClangErrMsg) void {
errors.ptr.delete(errors.len);
}
-fn isZigPrimitiveType(name: []const u8) bool {
- if (name.len > 1 and (name[0] == 'u' or name[0] == 'i')) {
- for (name[1..]) |c| {
- switch (c) {
- '0'...'9' => {},
- else => return false,
- }
- }
- return true;
- }
- return @import("AstGen.zig").simple_types.has(name);
-}
-
const PatternList = struct {
patterns: []Pattern,
@@ -5311,10 +5287,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
const end_loc = clang.Lexer.getLocForEndOfToken(macro.getSourceRange_getEnd(), c.source_manager, unit);
const name = try c.str(raw_name);
- // TODO https://github.com/ziglang/zig/issues/3756
- // TODO https://github.com/ziglang/zig/issues/1802
- const mangled_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ name, c.getMangle() }) else name;
- if (scope.containsNow(mangled_name)) {
+ if (scope.containsNow(name)) {
continue;
}
@@ -5328,7 +5301,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
var macro_ctx = MacroCtx{
.source = slice,
.list = tok_list.items,
- .name = mangled_name,
+ .name = name,
.loc = begin_loc,
};
assert(mem.eql(u8, macro_ctx.slice(), name));
@@ -5766,7 +5739,8 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
try m.fail(c, "TODO implement function '{s}' in std.zig.c_builtins", .{mangled_name});
return error.ParseError;
}
- const identifier = try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name);
+ if (builtin_typedef_map.get(mangled_name)) |ty| return Tag.type.create(c.arena, ty);
+ const identifier = try Tag.identifier.create(c.arena, mangled_name);
scope.skipVariableDiscard(identifier.castTag(.identifier).?.data);
return identifier;
},
@@ -6055,7 +6029,8 @@ fn parseCSpecifierQualifierList(c: *Context, m: *MacroCtx, scope: *Scope, allow_
.Identifier => {
const mangled_name = scope.getAlias(m.slice());
if (!allow_fail or c.typedefs.contains(mangled_name)) {
- return try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name);
+ if (builtin_typedef_map.get(mangled_name)) |ty| return try Tag.type.create(c.arena, ty);
+ return try Tag.identifier.create(c.arena, mangled_name);
}
},
.Keyword_void => return try Tag.type.create(c.arena, "c_void"),
diff --git a/src/translate_c/ast.zig b/src/translate_c/ast.zig
index 1058936191..01f7d24d04 100644
--- a/src/translate_c/ast.zig
+++ b/src/translate_c/ast.zig
@@ -801,11 +801,26 @@ const Context = struct {
}
fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
- return addTokenFmt(c, tag, "{s}", .{bytes});
+ return c.addTokenFmt(tag, "{s}", .{bytes});
+ }
+
+ fn isZigPrimitiveType(name: []const u8) bool {
+ if (name.len > 1 and (name[0] == 'u' or name[0] == 'i')) {
+ for (name[1..]) |c| {
+ switch (c) {
+ '0'...'9' => {},
+ else => return false,
+ }
+ }
+ return true;
+ }
+ return @import("../AstGen.zig").simple_types.has(name);
}
fn addIdentifier(c: *Context, bytes: []const u8) Allocator.Error!TokenIndex {
- return addTokenFmt(c, .identifier, "{s}", .{std.zig.fmtId(bytes)});
+ if (isZigPrimitiveType(bytes))
+ return c.addTokenFmt(.identifier, "@\"{s}\"", .{bytes});
+ return c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(bytes)});
}
fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange {
@@ -1999,7 +2014,7 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex {
members[1] = 0;
for (payload.fields) |field, i| {
- const name_tok = try c.addIdentifier(field.name);
+ const name_tok = try c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(field.name)});
_ = try c.addToken(.colon, ":");
const type_expr = try renderNode(c, field.type);
@@ -2079,7 +2094,7 @@ fn renderFieldAccess(c: *Context, lhs: NodeIndex, field_name: []const u8) !NodeI
.main_token = try c.addToken(.period, "."),
.data = .{
.lhs = lhs,
- .rhs = try c.addIdentifier(field_name),
+ .rhs = try c.addTokenFmt(.identifier, "{s}", .{std.zig.fmtId(field_name)}),
},
});
}