diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 277 | ||||
| -rw-r--r-- | src/Module.zig | 5 | ||||
| -rw-r--r-- | src/codegen.zig | 66 | ||||
| -rw-r--r-- | src/codegen/arm.zig | 4 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 151 | ||||
| -rw-r--r-- | src/codegen/llvm/bindings.zig | 269 | ||||
| -rw-r--r-- | src/link/MachO.zig | 26 | ||||
| -rw-r--r-- | src/link/MachO/TextBlock.zig | 4 | ||||
| -rw-r--r-- | src/translate_c.zig | 73 | ||||
| -rw-r--r-- | src/translate_c/ast.zig | 23 |
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)}), }, }); } |
