diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 3b0a24d3f5..bf9a2d5682 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -70,7 +70,7 @@ pub const GlobalLinkage = enum { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. -pub const GlobalVisibility = enum { +pub const SymbolVisibility = enum { default, hidden, protected, @@ -663,7 +663,7 @@ pub const ExportOptions = struct { name: []const u8, linkage: GlobalLinkage = .Strong, section: ?[]const u8 = null, - visibility: GlobalVisibility = .default, + visibility: SymbolVisibility = .default, }; /// This data structure is used by the Zig language code generation and diff --git a/src/Sema.zig b/src/Sema.zig index 6de4e3704c..fbf25be288 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -14999,27 +14999,37 @@ fn resolveExportOptions( const air_ref = sema.resolveInst(zir_ref); const options = try sema.coerce(block, export_options_ty, air_ref, src); - const name = try sema.fieldVal(block, src, options, "name", src); - const name_val = try sema.resolveConstValue(block, src, name); + const name_operand = try sema.fieldVal(block, src, options, "name", src); + const name_val = try sema.resolveConstValue(block, src, name_operand); + const name_ty = Type.initTag(.const_slice_u8); + const name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod); - const linkage = try sema.fieldVal(block, src, options, "linkage", src); - const linkage_val = try sema.resolveConstValue(block, src, linkage); + const linkage_operand = try sema.fieldVal(block, src, options, "linkage", src); + const linkage_val = try sema.resolveConstValue(block, src, linkage_operand); + const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage); const section = try sema.fieldVal(block, src, options, "section", src); const section_val = try sema.resolveConstValue(block, src, section); - const visibility = try sema.fieldVal(block, src, options, "visibility", src); - const visibility_val = try sema.resolveConstValue(block, src, visibility); + const visibility_operand = try sema.fieldVal(block, src, options, "visibility", src); + const visibility_val = try sema.resolveConstValue(block, src, visibility_operand); + const visibility = visibility_val.toEnum(std.builtin.SymbolVisibility); + + if (visibility != .default and linkage == .Internal) { + return sema.fail(block, src, "symbol '{s}' exported with internal linkage has non-default visibility {s}", .{ + name, @tagName(visibility), + }); + } if (!section_val.isNull()) { return sema.fail(block, src, "TODO: implement exporting with linksection", .{}); } - const name_ty = Type.initTag(.const_slice_u8); + return std.builtin.ExportOptions{ - .name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod), - .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage), + .name = name, + .linkage = linkage, .section = null, // TODO - .visibility = visibility_val.toEnum(std.builtin.GlobalVisibility), + .visibility = visibility, }; } diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index f2395efdcb..5ee07fcaf8 100644 --- a/src/stage1/all_types.hpp +++ b/src/stage1/all_types.hpp @@ -571,10 +571,10 @@ enum GlobalLinkageId { GlobalLinkageIdLinkOnce, }; -enum GlobalVisibilityId { - GlobalVisibilityIdDefault, - GlobalVisibilityIdHidden, - GlobalVisibilityIdProtected, +enum SymbolVisibilityId { + SymbolVisibilityIdDefault, + SymbolVisibilityIdHidden, + SymbolVisibilityIdProtected, }; enum TldId { @@ -1660,7 +1660,7 @@ enum FnAnalState { struct GlobalExport { Buf name; GlobalLinkageId linkage; - GlobalVisibilityId visibility; + SymbolVisibilityId visibility; }; struct ZigFn { diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index 0a5468cbc3..62b343b35c 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -3717,7 +3717,7 @@ ZigType *get_test_fn_type(CodeGen *g) { return g->test_fn_type; } -void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility) { +void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLinkageId linkage, SymbolVisibilityId visibility) { GlobalExport *global_export = var->export_list.add_one(); memset(global_export, 0, sizeof(GlobalExport)); buf_init_from_str(&global_export->name, symbol_name); @@ -3725,7 +3725,7 @@ void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLink global_export->visibility = visibility; } -void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility, CallingConvention cc) { +void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, SymbolVisibilityId visibility, CallingConvention cc) { CallingConvention winapi_cc = g->zig_target->arch == ZigLLVM_x86 ? CallingConventionStdcall : CallingConventionC; @@ -3854,13 +3854,13 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { case CallingConventionWin64: case CallingConventionPtxKernel: add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), - GlobalLinkageIdStrong, GlobalVisibilityIdDefault, fn_cc); + GlobalLinkageIdStrong, SymbolVisibilityIdDefault, fn_cc); break; case CallingConventionUnspecified: // An exported function without a specific calling // convention defaults to C add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), - GlobalLinkageIdStrong, GlobalVisibilityIdDefault, CallingConventionC); + GlobalLinkageIdStrong, SymbolVisibilityIdDefault, CallingConventionC); break; } } @@ -4323,7 +4323,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { if (is_export) { validate_export_var_type(g, type, source_node); - add_var_export(g, tld_var->var, tld_var->var->name, GlobalLinkageIdStrong, GlobalVisibilityIdDefault); + add_var_export(g, tld_var->var, tld_var->var->name, GlobalLinkageIdStrong, SymbolVisibilityIdDefault); } if (is_extern) { diff --git a/src/stage1/analyze.hpp b/src/stage1/analyze.hpp index d4985286d5..b2669eb637 100644 --- a/src/stage1/analyze.hpp +++ b/src/stage1/analyze.hpp @@ -221,8 +221,8 @@ ZigType *get_align_amt_type(CodeGen *g); ZigPackage *new_anonymous_package(void); Buf *const_value_to_buffer(ZigValue *const_val); -void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility, CallingConvention cc); -void add_var_export(CodeGen *g, ZigVar *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, GlobalVisibilityId visibility); +void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, SymbolVisibilityId visibility, CallingConvention cc); +void add_var_export(CodeGen *g, ZigVar *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, SymbolVisibilityId visibility); ZigValue *get_builtin_value(CodeGen *codegen, const char *name); diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index dece8e7348..e057a8cc80 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -242,13 +242,13 @@ static LLVMLinkage to_llvm_linkage(GlobalLinkageId id, bool is_extern) { zig_unreachable(); } -static LLVMVisibility to_llvm_visibility(GlobalVisibilityId id) { +static LLVMVisibility to_llvm_visibility(SymbolVisibilityId id) { switch (id) { - case GlobalVisibilityIdDefault: + case SymbolVisibilityIdDefault: return LLVMDefaultVisibility; - case GlobalVisibilityIdHidden: + case SymbolVisibilityIdHidden: return LLVMHiddenVisibility; - case GlobalVisibilityIdProtected: + case SymbolVisibilityIdProtected: return LLVMProtectedVisibility; } zig_unreachable(); @@ -412,7 +412,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { const char *unmangled_name = buf_ptr(&fn->symbol_name); const char *symbol_name; GlobalLinkageId linkage; - GlobalVisibilityId visibility = GlobalVisibilityIdDefault; + SymbolVisibilityId visibility = SymbolVisibilityIdDefault; if (fn->body_node == nullptr) { symbol_name = unmangled_name; linkage = GlobalLinkageIdStrong; @@ -8967,7 +8967,7 @@ static void do_code_gen(CodeGen *g) { assert(var->decl_node); GlobalLinkageId linkage; - GlobalVisibilityId visibility = GlobalVisibilityIdDefault; + SymbolVisibilityId visibility = SymbolVisibilityIdDefault; const char *unmangled_name = var->name; const char *symbol_name; if (var->export_list.length == 0) { diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 02b9dbd48b..4449985574 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -8635,11 +8635,11 @@ static bool ir_resolve_global_linkage(IrAnalyze *ira, Stage1AirInst *value, Glob return true; } -static bool ir_resolve_global_visibility(IrAnalyze *ira, Stage1AirInst *value, GlobalVisibilityId *out) { +static bool ir_resolve_global_visibility(IrAnalyze *ira, Stage1AirInst *value, SymbolVisibilityId *out) { if (type_is_invalid(value->value->type)) return false; - ZigType *global_visibility_type = get_builtin_type(ira->codegen, "GlobalVisibility"); + ZigType *global_visibility_type = get_builtin_type(ira->codegen, "SymbolVisibility"); Stage1AirInst *casted_value = ir_implicit_cast(ira, value, global_visibility_type); if (type_is_invalid(casted_value->value->type)) @@ -8649,7 +8649,7 @@ static bool ir_resolve_global_visibility(IrAnalyze *ira, Stage1AirInst *value, G if (!const_val) return false; - *out = (GlobalVisibilityId)bigint_as_u32(&const_val->data.x_enum_tag); + *out = (SymbolVisibilityId)bigint_as_u32(&const_val->data.x_enum_tag); return true; } @@ -11714,7 +11714,7 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id)) return ira->codegen->invalid_inst_gen; - GlobalVisibilityId global_visibility_id; + SymbolVisibilityId global_visibility_id; if (!ir_resolve_global_visibility(ira, visibility_inst, &global_visibility_id)) return ira->codegen->invalid_inst_gen;