diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2025-09-29 13:12:07 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-29 13:12:07 +0100 |
| commit | 11dc6680d2101a76e5fff8baedd8717501b625c0 (patch) | |
| tree | cc80ffec2742974e4e4882eb209e03248410adbe /src/llvm_backend.cpp | |
| parent | d3b877031838c5a13c4adbfdd1d8fb77c35c9801 (diff) | |
| parent | 240b2f1819294cc59b48f88ef3344bf77265fec6 (diff) | |
Merge pull request #5723 from odin-lang/bill/const-union
Basic support for constant union literals
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 81 |
1 files changed, 45 insertions, 36 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 3af473c3a..ec9630a47 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1947,7 +1947,7 @@ gb_internal bool lb_init_global_var(lbModule *m, lbProcedure *p, Entity *e, Ast GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr)); } - if (is_type_any(e->type) || is_type_union(e->type)) { + if (is_type_any(e->type)) { var.init = init; } else if (lb_is_const_or_global(init)) { if (!var.is_initialized) { @@ -3255,6 +3255,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { } GB_ASSERT(e->kind == Entity_Variable); + bool is_foreign = e->Variable.is_foreign; bool is_export = e->Variable.is_export; @@ -3262,40 +3263,16 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { lbModule *m = &gen->default_module; String name = lb_get_entity_name(m, e); - lbValue g = {}; - g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); - g.type = alloc_type_pointer(e->type); - - lb_apply_thread_local_model(g.value, e->Variable.thread_local_model); - - if (is_foreign) { - LLVMSetLinkage(g.value, LLVMExternalLinkage); - LLVMSetDLLStorageClass(g.value, LLVMDLLImportStorageClass); - LLVMSetExternallyInitialized(g.value, true); - lb_add_foreign_library_path(m, e->Variable.foreign_library); - } else { - LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type))); - } - if (is_export) { - LLVMSetLinkage(g.value, LLVMDLLExportLinkage); - LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass); - } else if (!is_foreign) { - LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMWeakAnyLinkage : LLVMInternalLinkage); - } - lb_set_linkage_from_entity_flags(m, g.value, e->flags); - LLVMSetAlignment(g.value, cast(u32)type_align_of(e->type)); - - if (e->Variable.link_section.len > 0) { - LLVMSetSection(g.value, alloc_cstring(permanent_allocator(), e->Variable.link_section)); - } - lbGlobalVariable var = {}; - var.var = g; var.decl = decl; + lbValue g = {}; + g.type = alloc_type_pointer(e->type); + g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); + if (decl->init_expr != nullptr) { TypeAndValue tav = type_and_value_of_expr(decl->init_expr); - if (!is_type_any(e->type) && !is_type_union(e->type)) { + if (!is_type_any(e->type)) { if (tav.mode != Addressing_Invalid) { if (tav.value.kind != ExactValue_Invalid) { auto cc = LB_CONST_CONTEXT_DEFAULT; @@ -3305,6 +3282,11 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { ExactValue v = tav.value; lbValue init = lb_const_value(m, tav.type, v, cc); + + LLVMDeleteGlobal(g.value); + g.value = nullptr; + g.value = LLVMAddGlobal(m->mod, LLVMTypeOf(init.value), alloc_cstring(permanent_allocator(), name)); + LLVMSetInitializer(g.value, init.value); var.is_initialized = true; if (cc.is_rodata) { @@ -3323,15 +3305,32 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMSetGlobalConstant(g.value, true); } - if (e->flags & EntityFlag_Require) { - lb_append_to_compiler_used(m, g.value); - } - array_add(&global_variables, var); + lb_apply_thread_local_model(g.value, e->Variable.thread_local_model); - lb_add_entity(m, e, g); - lb_add_member(m, name, g); + if (is_foreign) { + LLVMSetLinkage(g.value, LLVMExternalLinkage); + LLVMSetDLLStorageClass(g.value, LLVMDLLImportStorageClass); + LLVMSetExternallyInitialized(g.value, true); + lb_add_foreign_library_path(m, e->Variable.foreign_library); + } else if (LLVMGetInitializer(g.value) == nullptr) { + LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type))); + } + if (is_export) { + LLVMSetLinkage(g.value, LLVMDLLExportLinkage); + LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass); + } else if (!is_foreign) { + LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMWeakAnyLinkage : LLVMInternalLinkage); + } + lb_set_linkage_from_entity_flags(m, g.value, e->flags); + LLVMSetAlignment(g.value, cast(u32)type_align_of(e->type)); + if (e->Variable.link_section.len > 0) { + LLVMSetSection(g.value, alloc_cstring(permanent_allocator(), e->Variable.link_section)); + } + if (e->flags & EntityFlag_Require) { + lb_append_to_compiler_used(m, g.value); + } if (m->debug_builder) { String global_name = e->token.string; @@ -3361,6 +3360,16 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMGlobalSetMetadata(g.value, 0, global_variable_metadata); } } + + g.value = LLVMConstPointerCast(g.value, lb_type(m, alloc_type_pointer(e->type))); + + var.var = g; + array_add(&global_variables, var); + + lb_add_entity(m, e, g); + lb_add_member(m, name, g); + + } if (build_context.ODIN_DEBUG) { |